diff --git a/README.md b/README.md index 539980b..fe219cd 100644 --- a/README.md +++ b/README.md @@ -22,9 +22,14 @@ npm install @kitbag/mapper ```ts import mapper from '@kitbag/mapper' +const profiles = [ + createProfile('number', 'string', (source: number): boolean => source.toString()) + createProfile('number', 'Date', (source: number): Date =>new Date(source)) +] + mapper.register(profiles) -mapper.map('source-key', source, 'destination-key') +const dateValue = mapper.map('number', 123, 'Date') // Wed Dec 31 1969... ``` Kitbag Mapper relies an an underlying set of `Profile` objects to define what types are supported and how to map between them. To add profiles to Kitbag Mapper, use `register`. @@ -45,24 +50,55 @@ declare module '@kitbag/mapper' { Each profile defines a value for `sourceKey` and `destinationKey`. These keys must extend `string` and should be unique, beyond that the choice is irrelevant to the function of Kitbag Mapper. -Here are a couple simple examples of `Profile` objects +Profiles can be created with the `createProfile` function, which takes 3 arguments + +| Argument | Type | +| ------------- | ------------- | +| SourceKey | `string` | +| DestinationKey | `string` | +| MapFunction | `(source: TSource) => TDestination` | ```ts -export const numberToString = { +import { createProfile } from '@kitbag/mapper' + +createProfile('number', 'string', (source: number): boolean => source.toString()) +``` + +Alternatively, you can define profiles as static objects + +```ts +import { Profile } from '@kitbag/mapper' + +const numberToString = { sourceKey: 'number', destinationKey: 'string', map: (source: number): string => { return source.toString() }, -} as const satisfies Profile +} as const satisfies Profile, +``` -export const numberToDate = { - sourceKey: 'number', - destinationKey: 'Date', - map: (source: number): Date => { - return new Date(source) +or together in an array + +```ts +import { Profile } from '@kitbag/mapper' + +export const profiles = [ + { + sourceKey: 'number', + destinationKey: 'string', + map: (source: number): string => { + return source.toString() + }, }, -} as const satisfies Profile + { + sourceKey: 'number', + destinationKey: 'Date', + map: (source: number): Date => { + return new Date(source) + }, + } +] as const satisfies Profile[] ``` Note the [satisfies operator](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-9.html#the-satisfies-operator) requires Typescript v4.9+. diff --git a/docs/defining-profiles.md b/docs/defining-profiles.md index 83ef5fb..b7bd4c3 100644 --- a/docs/defining-profiles.md +++ b/docs/defining-profiles.md @@ -2,6 +2,36 @@ Each profile defines a value for `sourceKey` and `destinationKey`. These keys must extend `string` and should be unique combinations, beyond that the choice is irrelevant to the function of Kitbag Mapper. +Profiles can be defined with `createProfile` utility + +```ts +const profiles = [ + createProfile('number', 'string', (source: number): string => source.toString()), + createProfile('number', 'Date', (source: number): Date => new Date(source)), +] +``` + +or as static objects + +```ts +export const profiles = [ + { + sourceKey: 'number', + destinationKey: 'string', + map: (source: number): string => { + return source.toString() + }, + }, + { + sourceKey: 'number', + destinationKey: 'Date', + map: (source: number): Date => { + return new Date(source) + }, + }, +] as const satisfies Profile[] +``` + Here is a simple example of a profile that converts a server model you might see in an API service to the frontend model. ::: code-group diff --git a/docs/getting-started.md b/docs/getting-started.md index 1e616e6..1580905 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -21,21 +21,9 @@ We will cover profiles in greater depth soon, for now let's just write some simp import type { Profile } from '@kitbag/mapper' const profiles = [ - { - sourceKey: 'number', - destinationKey: 'string', - map: (source: number): string => { - return source.toString() - }, - }, - { - sourceKey: 'number', - destinationKey: 'Date', - map: (source: number): Date => { - return new Date(source) - }, - } -] as const satisfies Profile[] + createProfile('number', 'string', (source: number): string => source.toString()), + createProfile('number', 'Date', (source: number): Date => new Date(source)), +] ``` Here we have (2) profiles, 1 that is responsible for mapping `number` to `string` and another for mapping `number` to a `Date` instance.