@mikro-orm/nestjs 5.0.0 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -176,6 +176,29 @@ export class MyService {
176
176
  }
177
177
  ```
178
178
 
179
+ ## Serialization caveat
180
+
181
+ [NestJS built-in serialization](https://docs.nestjs.com/techniques/serialization) relies on [class-transformer](https://github.com/typestack/class-transformer). Since MikroORM wraps every single entity relation in a `Reference` or a `Collection` instance (for type-safety), this will make the built-in `ClassSerializerInterceptor` blind to any wrapped relations. In other words, if you return MikroORM entities from your HTTP or WebSocket handlers, all of their relations will NOT be serialized.
182
+
183
+ Luckily, MikroORM provides a [serialization API](https://mikro-orm.io/docs/serializing) which can be used in lieu of `ClassSerializerInterceptor`.
184
+
185
+ ```typescript
186
+ @Entity()
187
+ export class Book {
188
+
189
+ @Property({ hidden: true }) // --> Equivalent of class-transformer's `@Exclude`
190
+ hiddenField: number = Date.now();
191
+
192
+ @Property({ persist: false }) // --> Will only exist in memory (and will be serialized). Similar to class-transformer's `@Expose()`
193
+ count?: number;
194
+
195
+ @ManyToOne({ serializer: value => value.name, serializedName: 'authorName' }) // Equivalent of class-transformer's `@Transform()`
196
+ author: Author;
197
+
198
+ }
199
+
200
+ ```
201
+
179
202
  ## Using `AsyncLocalStorage` for request context
180
203
 
181
204
  > Since v5 AsyncLocalStorage is used inside RequestContext helper so this section is no longer valid.
@@ -269,7 +292,7 @@ the Nest.js DI container.
269
292
  `**./author.entity.ts**`
270
293
 
271
294
  ```ts
272
- @Entity()
295
+ @Entity({ customRepository: () => AuthorRepository })
273
296
  export class Author {
274
297
 
275
298
  // to allow inference in `em.getRepository()`
@@ -281,7 +304,6 @@ export class Author {
281
304
  `**./author.repository.ts**`
282
305
 
283
306
  ```ts
284
- @Repository(Author)
285
307
  export class AuthorRepository extends EntityRepository<Author> {
286
308
 
287
309
  // your custom methods...
package/index.js CHANGED
@@ -1,7 +1,11 @@
1
1
  "use strict";
2
2
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
3
  if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
5
9
  }) : (function(o, m, k, k2) {
6
10
  if (k2 === undefined) k2 = k;
7
11
  o[k2] = m[k];
@@ -1,7 +1,11 @@
1
1
  "use strict";
2
2
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
3
  if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
5
9
  }) : (function(o, m, k, k2) {
6
10
  if (k2 === undefined) k2 = k;
7
11
  o[k2] = m[k];
@@ -63,8 +67,8 @@ let MikroOrmCoreModule = MikroOrmCoreModule_1 = class MikroOrmCoreModule {
63
67
  { provide: mikro_orm_common_1.MIKRO_ORM_MODULE_OPTIONS, useValue: options || {} },
64
68
  (0, mikro_orm_providers_1.createMikroOrmProvider)(contextName),
65
69
  (0, mikro_orm_providers_1.createEntityManagerProvider)(options?.scope, core_1.EntityManager, contextName),
66
- ...(knex ? [(0, mikro_orm_providers_1.createEntityManagerProvider)(options?.scope, contextName ? (0, mikro_orm_common_1.getEntityManagerToken)(contextName) : knex.SqlEntityManager, contextName)] : []),
67
- ...(mongo ? [(0, mikro_orm_providers_1.createEntityManagerProvider)(options?.scope, contextName ? (0, mikro_orm_common_1.getEntityManagerToken)(contextName) : mongo.MongoEntityManager, contextName)] : []),
70
+ ...(knex ? [(0, mikro_orm_providers_1.createEntityManagerProvider)(options?.scope, knex.SqlEntityManager, contextName)] : []),
71
+ ...(mongo ? [(0, mikro_orm_providers_1.createEntityManagerProvider)(options?.scope, mongo.MongoEntityManager, contextName)] : []),
68
72
  ],
69
73
  exports: [
70
74
  contextName ? (0, mikro_orm_common_1.getMikroORMToken)(contextName) : core_1.MikroORM,
@@ -86,8 +90,8 @@ let MikroOrmCoreModule = MikroOrmCoreModule_1 = class MikroOrmCoreModule {
86
90
  ...(0, mikro_orm_providers_1.createAsyncProviders)({ ...options, contextName: options.contextName }),
87
91
  (0, mikro_orm_providers_1.createMikroOrmProvider)(contextName),
88
92
  (0, mikro_orm_providers_1.createEntityManagerProvider)(options.scope, core_1.EntityManager, contextName),
89
- ...(knex ? [(0, mikro_orm_providers_1.createEntityManagerProvider)(options?.scope, contextName ? (0, mikro_orm_common_1.getEntityManagerToken)(contextName) : knex.SqlEntityManager, contextName)] : []),
90
- ...(mongo ? [(0, mikro_orm_providers_1.createEntityManagerProvider)(options?.scope, contextName ? (0, mikro_orm_common_1.getEntityManagerToken)(contextName) : mongo.MongoEntityManager, contextName)] : []),
93
+ ...(knex ? [(0, mikro_orm_providers_1.createEntityManagerProvider)(options?.scope, knex.SqlEntityManager, contextName)] : []),
94
+ ...(mongo ? [(0, mikro_orm_providers_1.createEntityManagerProvider)(options?.scope, mongo.MongoEntityManager, contextName)] : []),
91
95
  ],
92
96
  exports: [
93
97
  contextName ? (0, mikro_orm_common_1.getMikroORMToken)(contextName) : core_1.MikroORM,
@@ -1,7 +1,6 @@
1
- import type { AnyEntity, EntityName } from '@mikro-orm/core';
1
+ import type { EntityName } from '@mikro-orm/core';
2
2
  import { Logger } from '@nestjs/common';
3
3
  export declare const MIKRO_ORM_MODULE_OPTIONS: unique symbol;
4
- export declare const REGISTERED_ENTITIES: Set<EntityName<AnyEntity<any>>>;
5
4
  export declare const CONTEXT_NAMES: string[];
6
5
  export declare const logger: Logger;
7
6
  export declare const getMikroORMToken: (name: string) => string;
@@ -1,10 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.InjectRepository = exports.getRepositoryToken = exports.InjectEntityManager = exports.getEntityManagerToken = exports.InjectMikroORM = exports.getMikroORMToken = exports.logger = exports.CONTEXT_NAMES = exports.REGISTERED_ENTITIES = exports.MIKRO_ORM_MODULE_OPTIONS = void 0;
3
+ exports.InjectRepository = exports.getRepositoryToken = exports.InjectEntityManager = exports.getEntityManagerToken = exports.InjectMikroORM = exports.getMikroORMToken = exports.logger = exports.CONTEXT_NAMES = exports.MIKRO_ORM_MODULE_OPTIONS = void 0;
4
4
  const core_1 = require("@mikro-orm/core");
5
5
  const common_1 = require("@nestjs/common");
6
6
  exports.MIKRO_ORM_MODULE_OPTIONS = Symbol('mikro-orm-module-options');
7
- exports.REGISTERED_ENTITIES = new Set();
8
7
  exports.CONTEXT_NAMES = [];
9
8
  exports.logger = new common_1.Logger(core_1.MikroORM.name);
10
9
  const getMikroORMToken = (name) => `${name}_MikroORM`;
@@ -0,0 +1,7 @@
1
+ import type { AnyEntity, EntityName } from '@mikro-orm/core';
2
+ export declare class MikroOrmEntitiesStorage {
3
+ private static readonly storage;
4
+ static addEntity(entity: EntityName<AnyEntity>, contextName?: string): void;
5
+ static getEntities(contextName?: string): never[] | IterableIterator<EntityName<AnyEntity<any>>>;
6
+ static clear(contextName?: string): void;
7
+ }
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MikroOrmEntitiesStorage = void 0;
4
+ class MikroOrmEntitiesStorage {
5
+ static addEntity(entity, contextName = 'default') {
6
+ let set = this.storage.get(contextName);
7
+ if (!set) {
8
+ set = new Set();
9
+ this.storage.set(contextName, set);
10
+ }
11
+ set.add(entity);
12
+ }
13
+ static getEntities(contextName = 'default') {
14
+ return this.storage.get(contextName)?.values() || [];
15
+ }
16
+ static clear(contextName = 'default') {
17
+ const set = this.storage.get(contextName);
18
+ if (!set) {
19
+ return;
20
+ }
21
+ set.clear();
22
+ }
23
+ }
24
+ exports.MikroOrmEntitiesStorage = MikroOrmEntitiesStorage;
25
+ MikroOrmEntitiesStorage.storage = new Map();
@@ -1,11 +1,9 @@
1
1
  import type { AnyEntity, EntityName } from '@mikro-orm/core';
2
2
  import type { DynamicModule } from '@nestjs/common';
3
- import type { MikroOrmModuleAsyncOptions, MikroOrmModuleSyncOptions, MikroOrmMiddlewareModuleOptions } from './typings';
3
+ import type { MikroOrmModuleAsyncOptions, MikroOrmModuleSyncOptions, MikroOrmMiddlewareModuleOptions, MikroOrmModuleFeatureOptions } from './typings';
4
4
  export declare class MikroOrmModule {
5
5
  static forRoot(options?: MikroOrmModuleSyncOptions): DynamicModule;
6
6
  static forRootAsync(options: MikroOrmModuleAsyncOptions): DynamicModule;
7
- static forFeature(options: EntityName<AnyEntity>[] | {
8
- entities?: EntityName<AnyEntity>[];
9
- }, contextName?: string): DynamicModule;
7
+ static forFeature(options: EntityName<AnyEntity>[] | MikroOrmModuleFeatureOptions, contextName?: string): DynamicModule;
10
8
  static forMiddleware(options?: MikroOrmMiddlewareModuleOptions): DynamicModule;
11
9
  }
@@ -12,8 +12,8 @@ const core_1 = require("@mikro-orm/core");
12
12
  const common_1 = require("@nestjs/common");
13
13
  const mikro_orm_providers_1 = require("./mikro-orm.providers");
14
14
  const mikro_orm_core_module_1 = require("./mikro-orm-core.module");
15
- const mikro_orm_common_1 = require("./mikro-orm.common");
16
15
  const mikro_orm_middleware_module_1 = require("./mikro-orm-middleware.module");
16
+ const mikro_orm_entities_storage_1 = require("./mikro-orm.entities.storage");
17
17
  let MikroOrmModule = MikroOrmModule_1 = class MikroOrmModule {
18
18
  static forRoot(options) {
19
19
  return {
@@ -29,10 +29,11 @@ let MikroOrmModule = MikroOrmModule_1 = class MikroOrmModule {
29
29
  }
30
30
  static forFeature(options, contextName) {
31
31
  const entities = Array.isArray(options) ? options : (options.entities || []);
32
- const providers = (0, mikro_orm_providers_1.createMikroOrmRepositoryProviders)(entities, contextName);
32
+ const name = (Array.isArray(options) || contextName) ? contextName : options.contextName;
33
+ const providers = (0, mikro_orm_providers_1.createMikroOrmRepositoryProviders)(entities, name);
33
34
  for (const e of entities) {
34
35
  if (!core_1.Utils.isString(e)) {
35
- mikro_orm_common_1.REGISTERED_ENTITIES.add(e);
36
+ mikro_orm_entities_storage_1.MikroOrmEntitiesStorage.addEntity(e, name);
36
37
  }
37
38
  }
38
39
  return {
@@ -1,10 +1,10 @@
1
1
  import type { AnyEntity, EntityName } from '@mikro-orm/core';
2
2
  import { EntityManager } from '@mikro-orm/core';
3
3
  import type { MikroOrmModuleAsyncOptions } from './typings';
4
- import type { Provider } from '@nestjs/common';
4
+ import type { Provider, Type } from '@nestjs/common';
5
5
  import { Scope } from '@nestjs/common';
6
6
  export declare function createMikroOrmProvider(contextName?: string): Provider;
7
- export declare function createEntityManagerProvider(scope?: Scope, entityManager?: any, contextName?: string): Provider<EntityManager>;
7
+ export declare function createEntityManagerProvider(scope?: Scope, entityManager?: Type, contextName?: string): Provider<EntityManager>;
8
8
  export declare function createMikroOrmAsyncOptionsProvider(options: MikroOrmModuleAsyncOptions): Provider;
9
9
  export declare function createAsyncProviders(options: MikroOrmModuleAsyncOptions): Provider[];
10
10
  export declare function createMikroOrmRepositoryProviders(entities: EntityName<AnyEntity>[], contextName?: string): Provider[];
@@ -4,16 +4,17 @@ exports.createMikroOrmRepositoryProviders = exports.createAsyncProviders = expor
4
4
  const mikro_orm_common_1 = require("./mikro-orm.common");
5
5
  const core_1 = require("@mikro-orm/core");
6
6
  const common_1 = require("@nestjs/common");
7
+ const mikro_orm_entities_storage_1 = require("./mikro-orm.entities.storage");
7
8
  function createMikroOrmProvider(contextName) {
8
9
  return {
9
10
  provide: contextName ? (0, mikro_orm_common_1.getMikroORMToken)(contextName) : core_1.MikroORM,
10
11
  useFactory: async (options) => {
11
12
  if (options?.autoLoadEntities) {
12
- options.entities = [...(options.entities || []), ...mikro_orm_common_1.REGISTERED_ENTITIES.values()];
13
- options.entitiesTs = [...(options.entitiesTs || []), ...mikro_orm_common_1.REGISTERED_ENTITIES.values()];
13
+ options.entities = [...(options.entities || []), ...mikro_orm_entities_storage_1.MikroOrmEntitiesStorage.getEntities(contextName)];
14
+ options.entitiesTs = [...(options.entitiesTs || []), ...mikro_orm_entities_storage_1.MikroOrmEntitiesStorage.getEntities(contextName)];
14
15
  delete options.autoLoadEntities;
15
16
  }
16
- mikro_orm_common_1.REGISTERED_ENTITIES.clear();
17
+ mikro_orm_entities_storage_1.MikroOrmEntitiesStorage.clear(contextName);
17
18
  if (!options || Object.keys(options).length === 0) {
18
19
  const config = await core_1.ConfigurationLoader.getConfiguration();
19
20
  config.set('logger', mikro_orm_common_1.logger.log.bind(mikro_orm_common_1.logger));
@@ -26,14 +27,8 @@ function createMikroOrmProvider(contextName) {
26
27
  }
27
28
  exports.createMikroOrmProvider = createMikroOrmProvider;
28
29
  function createEntityManagerProvider(scope = common_1.Scope.DEFAULT, entityManager = core_1.EntityManager, contextName) {
29
- function getProvide() {
30
- if (core_1.Utils.isString(entityManager)) {
31
- return entityManager;
32
- }
33
- return contextName ? (0, mikro_orm_common_1.getEntityManagerToken)(contextName) : entityManager;
34
- }
35
30
  return {
36
- provide: getProvide(),
31
+ provide: contextName ? (0, mikro_orm_common_1.getEntityManagerToken)(contextName) : entityManager,
37
32
  scope,
38
33
  useFactory: (orm) => scope === common_1.Scope.DEFAULT ? orm.em : orm.em.fork(),
39
34
  inject: [contextName ? (0, mikro_orm_common_1.getMikroORMToken)(contextName) : core_1.MikroORM],
@@ -44,7 +39,12 @@ function createMikroOrmAsyncOptionsProvider(options) {
44
39
  if (options.useFactory) {
45
40
  return {
46
41
  provide: mikro_orm_common_1.MIKRO_ORM_MODULE_OPTIONS,
47
- useFactory: options.useFactory,
42
+ useFactory: (...args) => {
43
+ const factoryOptions = options.useFactory(...args);
44
+ return options.contextName
45
+ ? { contextName: options.contextName, ...factoryOptions }
46
+ : factoryOptions;
47
+ },
48
48
  inject: options.inject || [],
49
49
  };
50
50
  }
@@ -54,7 +54,7 @@ function createMikroOrmAsyncOptionsProvider(options) {
54
54
  }
55
55
  return {
56
56
  provide: mikro_orm_common_1.MIKRO_ORM_MODULE_OPTIONS,
57
- useFactory: async (optionsFactory) => await optionsFactory.createMikroOrmOptions(),
57
+ useFactory: async (optionsFactory) => await optionsFactory.createMikroOrmOptions(options.contextName),
58
58
  inject,
59
59
  };
60
60
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikro-orm/nestjs",
3
- "version": "5.0.0",
3
+ "version": "5.1.0",
4
4
  "license": "MIT",
5
5
  "author": {
6
6
  "name": "Martin Adamek",
@@ -43,8 +43,8 @@
43
43
  "@mikro-orm/core": "^5.0.0",
44
44
  "@mikro-orm/knex": "^5.0.0",
45
45
  "@mikro-orm/mongodb": "^5.0.0",
46
- "@nestjs/common": "^8.0.0",
47
- "@nestjs/core": "^8.0.0"
46
+ "@nestjs/common": "^8.0.0 || ^9.0.0",
47
+ "@nestjs/core": "^8.0.0 || ^9.0.0"
48
48
  },
49
49
  "peerDependenciesMeta": {
50
50
  "@mikro-orm/knex": {
@@ -55,28 +55,28 @@
55
55
  }
56
56
  },
57
57
  "devDependencies": {
58
- "@mikro-orm/core": "^5.0.3",
59
- "@mikro-orm/sqlite": "^5.0.3",
60
- "@mikro-orm/mongodb": "^5.0.3",
61
- "@mikro-orm/knex": "^5.0.3",
62
- "@nestjs/common": "^8.2.6",
63
- "@nestjs/core": "^8.2.6",
64
- "@nestjs/platform-express": "^8.2.6",
65
- "@nestjs/testing": "^8.2.6",
66
- "@types/jest": "^27.4.0",
58
+ "@mikro-orm/core": "^5.2.3",
59
+ "@mikro-orm/knex": "^5.2.3",
60
+ "@mikro-orm/mongodb": "^5.2.3",
61
+ "@mikro-orm/sqlite": "^5.2.3",
62
+ "@nestjs/common": "^9.0.1",
63
+ "@nestjs/core": "^9.0.1",
64
+ "@nestjs/platform-express": "^9.0.1",
65
+ "@nestjs/testing": "^9.0.1",
66
+ "@types/jest": "^28.0.0",
67
67
  "@types/node": "^17.0.17",
68
68
  "@types/supertest": "^2.0.11",
69
- "@typescript-eslint/eslint-plugin": "~5.12.0",
70
- "@typescript-eslint/parser": "~5.12.0",
69
+ "@typescript-eslint/eslint-plugin": "~5.26.0",
70
+ "@typescript-eslint/parser": "~5.26.0",
71
71
  "conventional-changelog": "^3.1.25",
72
72
  "conventional-changelog-cli": "^2.2.2",
73
73
  "eslint": "^8.9.0",
74
- "jest": "^27.5.1",
74
+ "jest": "^28.0.0",
75
75
  "rxjs": "^7.5.4",
76
76
  "supertest": "^6.2.2",
77
- "ts-jest": "^27.1.3",
77
+ "ts-jest": "^28.0.0",
78
78
  "ts-node": "^10.5.0",
79
- "typescript": "4.5.5"
79
+ "typescript": "4.6.4"
80
80
  },
81
81
  "commitlint": {
82
82
  "extends": [
package/typings.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { IDatabaseDriver, Options } from '@mikro-orm/core';
1
+ import type { AnyEntity, EntityName, IDatabaseDriver, Options } from '@mikro-orm/core';
2
2
  import type { MiddlewareConsumer, ModuleMetadata, Scope, Type } from '@nestjs/common';
3
3
  import type { AbstractHttpAdapter } from '@nestjs/core';
4
4
  export interface NestMiddlewareConsumer extends MiddlewareConsumer {
@@ -21,8 +21,12 @@ export declare type MikroOrmModuleOptions<D extends IDatabaseDriver = IDatabaseD
21
21
  registerRequestContext?: boolean;
22
22
  autoLoadEntities?: boolean;
23
23
  } & Options<D> & MikroOrmMiddlewareModuleOptions;
24
+ export interface MikroOrmModuleFeatureOptions {
25
+ entities?: EntityName<AnyEntity>[];
26
+ contextName?: string;
27
+ }
24
28
  export interface MikroOrmOptionsFactory<D extends IDatabaseDriver = IDatabaseDriver> {
25
- createMikroOrmOptions(): Promise<MikroOrmModuleOptions<D>> | MikroOrmModuleOptions<D>;
29
+ createMikroOrmOptions(contextName?: string): Promise<MikroOrmModuleOptions<D>> | MikroOrmModuleOptions<D>;
26
30
  }
27
31
  export interface MikroOrmModuleSyncOptions extends MikroOrmModuleOptions, MikroOrmNestScopeOptions {
28
32
  }
@@ -30,7 +34,7 @@ export interface MikroOrmModuleAsyncOptions<D extends IDatabaseDriver = IDatabas
30
34
  contextName?: string;
31
35
  useExisting?: Type<MikroOrmOptionsFactory<D>>;
32
36
  useClass?: Type<MikroOrmOptionsFactory<D>>;
33
- useFactory?: (...args: any[]) => Promise<MikroOrmModuleOptions<D>> | MikroOrmModuleOptions<D>;
37
+ useFactory?: (...args: any[]) => Promise<Omit<MikroOrmModuleOptions<D>, 'contextName'>> | Omit<MikroOrmModuleOptions<D>, 'contextName'>;
34
38
  inject?: any[];
35
39
  }
36
40
  export {};