From 7ba77ce615d96d97eda65c09872d4eef287a13d3 Mon Sep 17 00:00:00 2001 From: Chau Tran Date: Fri, 5 Mar 2021 22:17:48 -0600 Subject: [PATCH 1/6] docs: adjust docs for sequelize --- .../docs/plugins-system/introduce-to-sequelize.md | 14 ++++++++++++++ packages/sequelize/README.md | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/docs-site/docs/plugins-system/introduce-to-sequelize.md b/docs-site/docs/plugins-system/introduce-to-sequelize.md index 79bddc6f9..2f48e07d6 100644 --- a/docs-site/docs/plugins-system/introduce-to-sequelize.md +++ b/docs-site/docs/plugins-system/introduce-to-sequelize.md @@ -13,3 +13,17 @@ npm i @automapper/sequelize # or with yarn yarn add @automapper/sequelize ``` + +## Usage + +```ts +import { sequelize } from '@automapper/sequelize'; + +const mapper = createMapper({ + ..., + pluginInitializer: sequelize() // or sequelize(model => model.get(getterOptions)) +}) + +mapper.createMap(User, UserVm); +mapper.map(user, UserVm, User); +``` diff --git a/packages/sequelize/README.md b/packages/sequelize/README.md index 1901dd0e2..c537346e5 100644 --- a/packages/sequelize/README.md +++ b/packages/sequelize/README.md @@ -38,7 +38,7 @@ yarn add --dev @types/sequelize @automapper/types - `valueGetter` is an optional getter that, if passed in, will be used to extract the value of the model after instantiation. By default, it will use `sequelize#Model.get()` if it's available. ```ts -import { classes } from '@automapper/classes'; +import { sequelize } from '@automapper/sequelize'; const mapper = createMapper({ ..., From bbdd895afaca40238a6affdec1de0fe3f7e99435 Mon Sep 17 00:00:00 2001 From: Chau Tran Date: Fri, 5 Mar 2021 22:37:31 -0600 Subject: [PATCH 2/6] feat(types): add postMap to MapPlugin --- packages/sequelize/src/lib/types.ts | 0 packages/types/src/plugin.ts | 11 +++++++++++ 2 files changed, 11 insertions(+) create mode 100644 packages/sequelize/src/lib/types.ts diff --git a/packages/sequelize/src/lib/types.ts b/packages/sequelize/src/lib/types.ts new file mode 100644 index 000000000..e69de29bb diff --git a/packages/types/src/plugin.ts b/packages/types/src/plugin.ts index e99d05b8a..44d3cbfb2 100644 --- a/packages/types/src/plugin.ts +++ b/packages/types/src/plugin.ts @@ -54,6 +54,17 @@ export interface MapPlugin { destinationObj?: TDestination ): [sourceInstance: TSource, destinationInstance: TDestination]; + /** + * An optional post-map function to post-process the destination after map + * + * @param destination - a key to be used to identify the information about a particular Destination + * @param destinationObj - a plain object that takes the shape of the destination + */ + postMap? = any>( + destination: TKey, + destinationObj?: TDestination + ): TDestination; + /** * An optional pre-mapArray function to prepare the sourceArray before mapArray * From 9552516db1a73e630d2983789800dd60b1728a99 Mon Sep 17 00:00:00 2001 From: Chau Tran Date: Fri, 5 Mar 2021 22:38:36 -0600 Subject: [PATCH 3/6] feat(sequelize): add postMap to instantiate a Model instance from map result --- packages/sequelize/src/index.ts | 1 + packages/sequelize/src/lib/sequelize.ts | 28 ++++++++++++++----------- packages/sequelize/src/lib/types.ts | 18 ++++++++++++++++ 3 files changed, 35 insertions(+), 12 deletions(-) diff --git a/packages/sequelize/src/index.ts b/packages/sequelize/src/index.ts index 9c50fdd02..05dd031f4 100644 --- a/packages/sequelize/src/index.ts +++ b/packages/sequelize/src/index.ts @@ -1 +1,2 @@ export * from './lib/sequelize'; +export * from './lib/types'; diff --git a/packages/sequelize/src/lib/sequelize.ts b/packages/sequelize/src/lib/sequelize.ts index 23531fe3d..8e2a10a60 100644 --- a/packages/sequelize/src/lib/sequelize.ts +++ b/packages/sequelize/src/lib/sequelize.ts @@ -2,18 +2,14 @@ import type { Constructible } from '@automapper/classes'; import { classes } from '@automapper/classes'; import type { Dictionary, MapPluginInitializer } from '@automapper/types'; import type { Model } from 'sequelize'; +import { SequelizeInitializerOptions } from './types'; -export const sequelize: < - TGetterResult extends Record = any, - TModel extends Model = Model ->( - valueGetter?: (model: TModel) => TGetterResult -) => MapPluginInitializer = < - TGetterResult extends Record = any, - TModel extends Model = Model ->( - valueGetter?: (model: TModel) => TGetterResult -) => (errorHandler) => { +export const sequelize: ( + options: SequelizeInitializerOptions +) => MapPluginInitializer = ({ + valueGetter, + init, +}: SequelizeInitializerOptions) => (errorHandler) => { const originalClasses = classes(errorHandler); return { @@ -23,7 +19,7 @@ export const sequelize: < obj?: TInstanceModel ) { const original = originalClasses.instantiate(model, obj); - const instance = (original[0] as unknown) as TModel; + const instance = (original[0] as unknown) as Model; original[0] = (valueGetter ? valueGetter(instance) : instance.get @@ -31,5 +27,13 @@ export const sequelize: < : instance) as TInstanceModel; return original; }, + postMap = any>( + destination: Constructible, + destinationObj?: TModel + ): TModel { + return init + ? init((destination as unknown) as Model, destinationObj) + : new destination(destinationObj); + }, }; }; diff --git a/packages/sequelize/src/lib/types.ts b/packages/sequelize/src/lib/types.ts index e69de29bb..0690e674a 100644 --- a/packages/sequelize/src/lib/types.ts +++ b/packages/sequelize/src/lib/types.ts @@ -0,0 +1,18 @@ +import type { Dictionary } from '@automapper/types'; +import type { Model } from 'sequelize'; + +export interface SequelizeInitializerOptions { + valueGetter?: < + TGetterResult extends Record = any, + TModel extends Model = Model + >( + model: TModel + ) => TGetterResult; + init?: < + TDestination extends Dictionary = any, + TModel extends Model = Model + >( + destination: TModel, + destinationObj: TDestination + ) => TDestination; +} From fb227929bc47445f0db669a8aa5c36e2b51b5f82 Mon Sep 17 00:00:00 2001 From: Chau Tran Date: Fri, 5 Mar 2021 22:38:56 -0600 Subject: [PATCH 4/6] feat(core): use postMap if available --- packages/core/src/lib/create-mapper/create-mapper.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/core/src/lib/create-mapper/create-mapper.ts b/packages/core/src/lib/create-mapper/create-mapper.ts index ac3ba598c..26d7b5d82 100644 --- a/packages/core/src/lib/create-mapper/create-mapper.ts +++ b/packages/core/src/lib/create-mapper/create-mapper.ts @@ -57,7 +57,7 @@ export function createMapper({ return sourceObj; } - const { preMap } = plugin; + const { preMap, postMap } = plugin; // run preMap if available const [sourceInstance] = preMap @@ -79,13 +79,15 @@ export function createMapper({ 'extraArguments' in destinationObjOrOptions)) || destinationObjOrOptions == null ) { - return mapReturn( + const result = mapReturn( sourceInstance ?? sourceObj, mapping!, destinationObjOrOptions as MapOptions, this, errorHandler ); + + return postMap ? postMap.bind(plugin)(destination, result) : result; } mapMutate( @@ -96,6 +98,9 @@ export function createMapper({ errorHandler, destinationObjOrOptions ); + if (postMap) { + destinationObjOrOptions = postMap(destination, destinationObjOrOptions); + } }, mapAsync( sourceObj: Record, From 18971db85c6b4e03f6c78b1952914bf0d43285bc Mon Sep 17 00:00:00 2001 From: Chau Tran Date: Fri, 5 Mar 2021 22:42:00 -0600 Subject: [PATCH 5/6] docs: modify docs on sequelize --- .../plugins-system/introduce-to-sequelize.md | 40 +++++++++++++++++-- packages/sequelize/README.md | 37 +++++++++++++++-- 2 files changed, 70 insertions(+), 7 deletions(-) diff --git a/docs-site/docs/plugins-system/introduce-to-sequelize.md b/docs-site/docs/plugins-system/introduce-to-sequelize.md index 2f48e07d6..075b0ba86 100644 --- a/docs-site/docs/plugins-system/introduce-to-sequelize.md +++ b/docs-site/docs/plugins-system/introduce-to-sequelize.md @@ -16,14 +16,48 @@ yarn add @automapper/sequelize ## Usage +- `@automapper/sequelize` provides `sequelize` as a `(options: SequelizeInitializerOptions) => MapPluginInitializer`. Pass `sequelize()` to `createMapper` to create + a `Mapper` that uses `sequelize` plugin. + +```ts +export interface SequelizeInitializerOptions { + valueGetter?: < + TGetterResult extends Record = any, + TModel extends Model = Model + >( + model: TModel + ) => TGetterResult; + init?: < + TDestination extends Dictionary = any, + TModel extends Model = Model + >( + destination: TModel, + destinationObj: TDestination + ) => TDestination; +} +``` + +- `valueGetter` is an optional getter that, if passed in, will be used to extract the value of the model after instantiation. By default, it will use `sequelize#Model.get()` if it's available. +- `init` is an optional init function that, if passed in, will be used to instantiate a `Sequelize#Model` after map. By default, it will use `new Model(mapResult)` + ```ts import { sequelize } from '@automapper/sequelize'; +import { Model } from 'sequelize-typescript'; const mapper = createMapper({ ..., - pluginInitializer: sequelize() // or sequelize(model => model.get(getterOptions)) + pluginInitializer: sequelize() + /** + * or + * sequelize({ + * valueGetter: model => model.get(getterOptions), + * init: (model, mapResult) => model.init(mapResult, initOptions) + * }) + */ }) -mapper.createMap(User, UserVm); -mapper.map(user, UserVm, User); +class User extends Model {} + +mapper.createMap(UserVm, User); +mapper.map(userVm, User, UserVm); ``` diff --git a/packages/sequelize/README.md b/packages/sequelize/README.md index c537346e5..d7c1d1b18 100644 --- a/packages/sequelize/README.md +++ b/packages/sequelize/README.md @@ -32,21 +32,50 @@ yarn add --dev @types/sequelize @automapper/types ## Usage -- `@automapper/sequelize` provides `sequelize` as a `(valueGetter) => MapPluginInitializer`. Pass `sequelize()` to `createMapper` to create +- `@automapper/sequelize` provides `sequelize` as a `(options: SequelizeInitializerOptions) => MapPluginInitializer`. Pass `sequelize()` to `createMapper` to create a `Mapper` that uses `sequelize` plugin. +```ts +export interface SequelizeInitializerOptions { + valueGetter?: < + TGetterResult extends Record = any, + TModel extends Model = Model + >( + model: TModel + ) => TGetterResult; + init?: < + TDestination extends Dictionary = any, + TModel extends Model = Model + >( + destination: TModel, + destinationObj: TDestination + ) => TDestination; +} +``` + - `valueGetter` is an optional getter that, if passed in, will be used to extract the value of the model after instantiation. By default, it will use `sequelize#Model.get()` if it's available. +- `init` is an optional init function that, if passed in, will be used to instantiate a `Sequelize#Model` after map. By default, it will use `new Model(mapResult)` ```ts import { sequelize } from '@automapper/sequelize'; +import { Model } from 'sequelize-typescript'; const mapper = createMapper({ ..., - pluginInitializer: sequelize() // or sequelize(model => model.get(getterOptions)) + pluginInitializer: sequelize() + /** + * or + * sequelize({ + * valueGetter: model => model.get(getterOptions), + * init: (model, mapResult) => model.init(mapResult, initOptions) + * }) + */ }) -mapper.createMap(User, UserVm); -mapper.map(user, UserVm, User); +class User extends Model {} + +mapper.createMap(UserVm, User); +mapper.map(userVm, User, UserVm); ``` Read more about this plugin on [sequelize documentation](https://automapperts.netlify.app/docs/plugins-system/introduce-to-sequelize) From 29aa4cc758f23cdb4d7d48cf83f26c790411eb89 Mon Sep 17 00:00:00 2001 From: Chau Tran Date: Fri, 5 Mar 2021 22:42:15 -0600 Subject: [PATCH 6/6] Prepare release 3.2.0 --- CHANGELOG.md | 8 ++++++++ package-lock.json | 2 +- package.json | 2 +- .../classes/experimental/transformer-plugin/package.json | 2 +- packages/classes/package.json | 2 +- packages/core/package.json | 2 +- packages/nestjs/package.json | 2 +- packages/pojos/package.json | 2 +- packages/sequelize/package.json | 2 +- packages/types/package.json | 2 +- 10 files changed, 17 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ee03fb29..93f98545b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +# [3.2.0](https://github.com/nartc/mapper/compare/3.1.0...3.2.0) (2021-03-06) + +### Features + +- **core:** use postMap if available ([fb22792](https://github.com/nartc/mapper/commit/fb227929bc47445f0db669a8aa5c36e2b51b5f82)) +- **sequelize:** add postMap to instantiate a Model instance from map result ([9552516](https://github.com/nartc/mapper/commit/9552516db1a73e630d2983789800dd60b1728a99)) +- **types:** add postMap to MapPlugin ([bbdd895](https://github.com/nartc/mapper/commit/bbdd895afaca40238a6affdec1de0fe3f7e99435)) + # [3.1.0](https://github.com/nartc/mapper/compare/3.0.11...3.1.0) (2021-03-06) ### Bug Fixes diff --git a/package-lock.json b/package-lock.json index 3fc956c75..a5c2c363f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "automapper", - "version": "3.1.0", + "version": "3.2.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 7983fb9c8..04fdeac51 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "automapper", - "version": "3.1.0", + "version": "3.2.0", "license": "MIT", "scripts": { "nx": "nx", diff --git a/packages/classes/experimental/transformer-plugin/package.json b/packages/classes/experimental/transformer-plugin/package.json index 58419ecba..877244571 100644 --- a/packages/classes/experimental/transformer-plugin/package.json +++ b/packages/classes/experimental/transformer-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@automapper/classes/experimental/transformer-plugin", - "version": "3.1.0", + "version": "3.2.0", "sideEffects": false, "publishConfig": { "access": "public" diff --git a/packages/classes/package.json b/packages/classes/package.json index 5538357aa..a5290f631 100644 --- a/packages/classes/package.json +++ b/packages/classes/package.json @@ -1,6 +1,6 @@ { "name": "@automapper/classes", - "version": "3.1.0", + "version": "3.2.0", "peerDependencies": { "reflect-metadata": "~0.1.13" }, diff --git a/packages/core/package.json b/packages/core/package.json index ab6bc5abd..5a60f7e1c 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@automapper/core", - "version": "3.1.0", + "version": "3.2.0", "sideEffects": false, "engines": { "node": ">=10.0.0" diff --git a/packages/nestjs/package.json b/packages/nestjs/package.json index 06fd344ba..352880d5f 100644 --- a/packages/nestjs/package.json +++ b/packages/nestjs/package.json @@ -1,6 +1,6 @@ { "name": "@automapper/nestjs", - "version": "3.1.0", + "version": "3.2.0", "peerDependencies": { "@nestjs/common": "^7.0.0", "@nestjs/core": "^7.0.0" diff --git a/packages/pojos/package.json b/packages/pojos/package.json index a397071b4..cccd83ed4 100644 --- a/packages/pojos/package.json +++ b/packages/pojos/package.json @@ -1,6 +1,6 @@ { "name": "@automapper/pojos", - "version": "3.1.0", + "version": "3.2.0", "sideEffects": false, "engines": { "node": ">=10.0.0" diff --git a/packages/sequelize/package.json b/packages/sequelize/package.json index 149531fa9..ce7462aec 100644 --- a/packages/sequelize/package.json +++ b/packages/sequelize/package.json @@ -1,6 +1,6 @@ { "name": "@automapper/sequelize", - "version": "3.1.0", + "version": "3.2.0", "peerDependencies": { "reflect-metadata": "~0.1.13", "sequelize": "~6.5.0" diff --git a/packages/types/package.json b/packages/types/package.json index 50f4eed63..7084d8b22 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@automapper/types", - "version": "3.1.0", + "version": "3.2.0", "sideEffects": false, "engines": { "node": ">=10.0.0"