@tsed/mikro-orm 7.0.0-beta.11 → 7.0.0-beta.14

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.
Files changed (55) hide show
  1. package/jest.config.js +4 -4
  2. package/lib/cjs/MikroOrmModule.d.ts +7 -3
  3. package/lib/cjs/MikroOrmModule.js +22 -6
  4. package/lib/cjs/MikroOrmModule.js.map +1 -1
  5. package/lib/cjs/decorators/entityManager.d.ts +2 -2
  6. package/lib/cjs/decorators/entityManager.js +1 -1
  7. package/lib/cjs/decorators/entityManager.js.map +1 -1
  8. package/lib/cjs/decorators/orm.d.ts +1 -1
  9. package/lib/cjs/decorators/transactional.d.ts +1 -1
  10. package/lib/cjs/index.d.ts +1 -1
  11. package/lib/cjs/index.js +1 -1
  12. package/lib/cjs/index.js.map +1 -1
  13. package/lib/cjs/interceptors/TransactionalInterceptor.d.ts +8 -4
  14. package/lib/cjs/interceptors/TransactionalInterceptor.js +42 -43
  15. package/lib/cjs/interceptors/TransactionalInterceptor.js.map +1 -1
  16. package/lib/cjs/services/MikroOrmContext.d.ts +9 -0
  17. package/lib/cjs/services/MikroOrmContext.js +26 -0
  18. package/lib/cjs/services/MikroOrmContext.js.map +1 -0
  19. package/lib/cjs/services/MikroOrmFactory.d.ts +3 -1
  20. package/lib/cjs/services/MikroOrmFactory.js +9 -7
  21. package/lib/cjs/services/MikroOrmFactory.js.map +1 -1
  22. package/lib/cjs/services/MikroOrmRegistry.d.ts +2 -0
  23. package/lib/cjs/services/MikroOrmRegistry.js +12 -6
  24. package/lib/cjs/services/MikroOrmRegistry.js.map +1 -1
  25. package/lib/esm/MikroOrmModule.js +23 -7
  26. package/lib/esm/MikroOrmModule.js.map +1 -1
  27. package/lib/esm/decorators/entityManager.js +1 -1
  28. package/lib/esm/decorators/entityManager.js.map +1 -1
  29. package/lib/esm/index.js +1 -1
  30. package/lib/esm/index.js.map +1 -1
  31. package/lib/esm/interceptors/TransactionalInterceptor.js +42 -43
  32. package/lib/esm/interceptors/TransactionalInterceptor.js.map +1 -1
  33. package/lib/esm/services/MikroOrmContext.js +23 -0
  34. package/lib/esm/services/MikroOrmContext.js.map +1 -0
  35. package/lib/esm/services/MikroOrmFactory.js +10 -8
  36. package/lib/esm/services/MikroOrmFactory.js.map +1 -1
  37. package/lib/esm/services/MikroOrmRegistry.js +12 -6
  38. package/lib/esm/services/MikroOrmRegistry.js.map +1 -1
  39. package/lib/types/MikroOrmModule.d.ts +7 -3
  40. package/lib/types/decorators/entityManager.d.ts +2 -2
  41. package/lib/types/decorators/orm.d.ts +1 -1
  42. package/lib/types/decorators/transactional.d.ts +1 -1
  43. package/lib/types/index.d.ts +1 -1
  44. package/lib/types/interceptors/TransactionalInterceptor.d.ts +8 -4
  45. package/lib/types/services/MikroOrmContext.d.ts +9 -0
  46. package/lib/types/services/MikroOrmFactory.d.ts +3 -1
  47. package/lib/types/services/MikroOrmRegistry.d.ts +2 -0
  48. package/package.json +18 -15
  49. package/readme.md +40 -3
  50. package/lib/cjs/services/DBContext.d.ts +0 -9
  51. package/lib/cjs/services/DBContext.js +0 -37
  52. package/lib/cjs/services/DBContext.js.map +0 -1
  53. package/lib/esm/services/DBContext.js +0 -34
  54. package/lib/esm/services/DBContext.js.map +0 -1
  55. package/lib/types/services/DBContext.d.ts +0 -9
@@ -1 +1 @@
1
- {"version":3,"file":"MikroOrmModule.js","sourceRoot":"","sources":["../../src/MikroOrmModule.ts"],"names":[],"mappings":";AAAA,OAAO,EAAC,aAAa,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAqB,gBAAgB,EAAC,MAAM,UAAU,CAAC;AAEtG,OAAO,EAAC,gBAAgB,EAAC,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAC,SAAS,EAAC,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EAAC,aAAa,EAAC,MAAM,0BAA0B,CAAC;AAmBvD,IAAa,cAAc,GAA3B,MAAa,cAAc;IAOlB,KAAK,CAAC,OAAO;QAClB,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;QAEnF,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC9B,CAAC;IAEM,UAAU;QACf,OAAO,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,CAAC;IACvC,CAAC;CACF,CAAA;AAdC;IADC,QAAQ,CAAC,UAAU,EAAE,EAAE,CAAC;;gDACa;AAGtC;IADC,MAAM,EAAE;8BAC2B,gBAAgB;wDAAC;AAL1C,cAAc;IAJ1B,MAAM,CAAC;QACN,OAAO,EAAE,CAAC,SAAS,EAAE,gBAAgB,CAAC;QACtC,IAAI,EAAE,CAAC,aAAa,EAAE,gBAAgB,CAAC;KACxC,CAAC;GACW,cAAc,CAgB1B;SAhBY,cAAc;AAkB3B,uGAAuG;AACvG,gBAAgB,CAAC,EAAC,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,IAAI,EAAC,CAAC,CAAC","sourcesContent":["import {Configuration, Constant, Inject, Module, OnDestroy, OnInit, registerProvider} from \"@tsed/di\";\nimport {Options} from \"@mikro-orm/core\";\nimport {MikroOrmRegistry} from \"./services/MikroOrmRegistry\";\nimport {DBContext} from \"./services/DBContext\";\nimport {RetryStrategy} from \"./services/RetryStrategy\";\n\ndeclare global {\n // eslint-disable-next-line @typescript-eslint/no-namespace\n namespace TsED {\n interface Configuration {\n /**\n * The the ORM configuration, entity metadata.\n * If you omit the `options` parameter, your CLI config will be used.\n */\n mikroOrm?: Options[];\n }\n }\n}\n\n@Module({\n imports: [DBContext, MikroOrmRegistry],\n deps: [Configuration, MikroOrmRegistry]\n})\nexport class MikroOrmModule implements OnDestroy, OnInit {\n @Constant(\"mikroOrm\", [])\n private readonly settings!: Options[];\n\n @Inject()\n private readonly mikroOrmRegistry!: MikroOrmRegistry;\n\n public async $onInit(): Promise<void> {\n const promises = this.settings.map((opts) => this.mikroOrmRegistry.register(opts));\n\n await Promise.all(promises);\n }\n\n public $onDestroy(): Promise<void> {\n return this.mikroOrmRegistry.clear();\n }\n}\n\n// TODO: the IoC container should provide null or undefined by default until tsedio/tsed#1694 is closed\nregisterProvider({provide: RetryStrategy, useValue: null});\n"]}
1
+ {"version":3,"file":"MikroOrmModule.js","sourceRoot":"","sources":["../../src/MikroOrmModule.ts"],"names":[],"mappings":";AAAA,OAAO,4BAA4B,CAAC;AACpC,OAAO,EAAoB,QAAQ,EAAa,MAAM,EAAE,MAAM,EAAqB,gBAAgB,EAAC,MAAM,UAAU,CAAC;AAErH,OAAO,EAAC,gBAAgB,EAAC,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAC,aAAa,EAAC,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAC,yBAAyB,EAAC,MAAM,qCAAqC,CAAC;AAC9E,OAAO,EAAC,eAAe,EAAC,MAAM,4BAA4B,CAAC;AAkB3D,IAAa,cAAc,GAA3B,MAAa,cAAc;IAER,QAAQ,CAAa;IAGrB,QAAQ,CAAoB;IAG5B,OAAO,CAAmB;IAEpC,KAAK,CAAC,OAAO;QAClB,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;QAE3E,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC9B,CAAC;IAEM,UAAU;QACf,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;IAC/B,CAAC;IAEM,kBAAkB,CAAC,IAAqC,EAAE,CAAY;QAC3E,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IACxC,CAAC;IAEO,aAAa,CAAC,IAAqC;QACzD,MAAM,SAAS,GAAG,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QAC9C,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAEhD,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC1C,CAAC;CACF,CAAA;AA5BC;IADC,QAAQ,CAAC,UAAU,EAAE,EAAE,CAAC;;gDACa;AAGtC;IADC,MAAM,EAAE;8BACmB,gBAAgB;gDAAC;AAG7C;IADC,MAAM,EAAE;8BACkB,eAAe;+CAAC;AARhC,cAAc;IAH1B,MAAM,CAAC;QACN,eAAe,EAAE,CAAC,yBAAyB,CAAC;KAC7C,CAAC;GACW,cAAc,CA8B1B;SA9BY,cAAc;AAgC3B,uGAAuG;AACvG,gBAAgB,CAAC,EAAC,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,IAAI,EAAC,CAAC,CAAC","sourcesContent":["import \"./services/MikroOrmFactory\";\nimport {AlterRunInContext, Constant, DIContext, Inject, Module, OnDestroy, OnInit, registerProvider} from \"@tsed/di\";\nimport {Options} from \"@mikro-orm/core\";\nimport {MikroOrmRegistry} from \"./services/MikroOrmRegistry\";\nimport {RetryStrategy} from \"./services/RetryStrategy\";\nimport {OptimisticLockErrorFilter} from \"./filters/OptimisticLockErrorFilter\";\nimport {MikroOrmContext} from \"./services/MikroOrmContext\";\n\ndeclare global {\n // eslint-disable-next-line @typescript-eslint/no-namespace\n namespace TsED {\n interface Configuration {\n /**\n * The the ORM configuration, entity metadata.\n * If you omit the `options` parameter, your CLI config will be used.\n */\n mikroOrm?: Options[];\n }\n }\n}\n\n@Module({\n responseFilters: [OptimisticLockErrorFilter]\n})\nexport class MikroOrmModule implements OnDestroy, OnInit, AlterRunInContext {\n @Constant(\"mikroOrm\", [])\n private readonly settings!: Options[];\n\n @Inject()\n private readonly registry!: MikroOrmRegistry;\n\n @Inject()\n private readonly context!: MikroOrmContext;\n\n public async $onInit(): Promise<void> {\n const promises = this.settings.map((opts) => this.registry.register(opts));\n\n await Promise.all(promises);\n }\n\n public $onDestroy(): Promise<void> {\n return this.registry.clear();\n }\n\n public $alterRunInContext(next: (...args: unknown[]) => unknown, _: DIContext): () => unknown | Promise<() => unknown> {\n return () => this.createContext(next);\n }\n\n private createContext(next: (...args: unknown[]) => unknown): unknown {\n const instances = [...this.registry.values()];\n const managers = instances.map((orm) => orm.em);\n\n return this.context.run(managers, next);\n }\n}\n\n// TODO: the IoC container should provide null or undefined by default until tsedio/tsed#1694 is closed\nregisterProvider({provide: RetryStrategy, useValue: null});\n"]}
@@ -6,7 +6,7 @@ import { MikroOrmRegistry } from "../services/MikroOrmRegistry.js";
6
6
  * @decorator
7
7
  * @mikroOrm
8
8
  */
9
- export const EntityManager = (contextName) => Inject(MikroOrmRegistry, (registry) => { var _a; return (_a = registry.get(contextName)) === null || _a === void 0 ? void 0 : _a.em; });
9
+ export const EntityManager = (contextName) => Inject(MikroOrmRegistry, (registry) => registry.get(contextName)?.em);
10
10
  /**
11
11
  * Get the entity manager for the given context name.
12
12
  * @param {String} connectionName
@@ -1 +1 @@
1
- {"version":3,"file":"entityManager.js","sourceRoot":"","sources":["../../../src/decorators/entityManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,UAAU,CAAC;AAChC,OAAO,EAAC,gBAAgB,EAAC,MAAM,8BAA8B,CAAC;AAE9D;;;;;GAKG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,WAAoB,EAAqB,EAAE,CACvE,MAAM,CAAC,gBAAgB,EAAE,CAAC,QAA0B,EAAE,EAAE,WAAC,OAAA,MAAA,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAC,0CAAE,EAAE,CAAA,EAAA,CAAsB,CAAC;AAE/G;;;;;GAKG;AACH,MAAM,CAAC,MAAM,EAAE,GAAG,aAAa,CAAC","sourcesContent":["import {Inject} from \"@tsed/di\";\nimport {MikroOrmRegistry} from \"../services/MikroOrmRegistry\";\n\n/**\n * Get the entity manager for the given context name.\n * @param {String} contextName\n * @decorator\n * @mikroOrm\n */\nexport const EntityManager = (contextName?: string): PropertyDecorator =>\n Inject(MikroOrmRegistry, (registry: MikroOrmRegistry) => registry.get(contextName)?.em) as PropertyDecorator;\n\n/**\n * Get the entity manager for the given context name.\n * @param {String} connectionName\n * @decorator\n * @mikroOrm\n */\nexport const Em = EntityManager;\n"]}
1
+ {"version":3,"file":"entityManager.js","sourceRoot":"","sources":["../../../src/decorators/entityManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,UAAU,CAAC;AAChC,OAAO,EAAC,gBAAgB,EAAC,MAAM,8BAA8B,CAAC;AAE9D;;;;;GAKG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,WAAoB,EAAqB,EAAE,CACvE,MAAM,CAAC,gBAAgB,EAAE,CAAC,QAA0B,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,EAAE,CAAsB,CAAC;AAE/G;;;;;GAKG;AACH,MAAM,CAAC,MAAM,EAAE,GAAG,aAAa,CAAC","sourcesContent":["import {Inject} from \"@tsed/di\";\nimport {MikroOrmRegistry} from \"../services/MikroOrmRegistry\";\n\n/**\n * Get the entity manager for the given context name.\n * @param {String} contextName\n * @decorator\n * @mikroOrm\n */\nexport const EntityManager = (contextName?: string): PropertyDecorator =>\n Inject(MikroOrmRegistry, (registry: MikroOrmRegistry) => registry.get(contextName)?.em) as PropertyDecorator;\n\n/**\n * Get the entity manager for the given context name.\n * @param {String} connectionName\n * @decorator\n * @mikroOrm\n */\nexport const Em = EntityManager;\n"]}
package/lib/esm/index.js CHANGED
@@ -7,7 +7,7 @@ export * from "./decorators/orm.js";
7
7
  export * from "./decorators/transactional.js";
8
8
  export * from "./filters/OptimisticLockErrorFilter.js";
9
9
  export * from "./interceptors/TransactionalInterceptor.js";
10
- export * from "./services/DBContext.js";
10
+ export * from "./services/MikroOrmContext.js";
11
11
  export * from "./services/MikroOrmFactory.js";
12
12
  export * from "./services/MikroOrmRegistry.js";
13
13
  export * from "./services/RetryStrategy.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,kBAAkB,CAAC;AACjC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,kBAAkB,CAAC;AACjC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,qCAAqC,CAAC;AACpD,cAAc,yCAAyC,CAAC;AACxD,cAAc,sBAAsB,CAAC;AACrC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,0BAA0B,CAAC","sourcesContent":["/**\n * @file Automatically generated by barrelsby.\n */\n\nexport * from \"./MikroOrmModule\";\nexport * from \"./decorators/entityManager\";\nexport * from \"./decorators/orm\";\nexport * from \"./decorators/transactional\";\nexport * from \"./filters/OptimisticLockErrorFilter\";\nexport * from \"./interceptors/TransactionalInterceptor\";\nexport * from \"./services/DBContext\";\nexport * from \"./services/MikroOrmFactory\";\nexport * from \"./services/MikroOrmRegistry\";\nexport * from \"./services/RetryStrategy\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,kBAAkB,CAAC;AACjC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,kBAAkB,CAAC;AACjC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,qCAAqC,CAAC;AACpD,cAAc,yCAAyC,CAAC;AACxD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,0BAA0B,CAAC","sourcesContent":["/**\n * @file Automatically generated by barrelsby.\n */\n\nexport * from \"./MikroOrmModule\";\nexport * from \"./decorators/entityManager\";\nexport * from \"./decorators/orm\";\nexport * from \"./decorators/transactional\";\nexport * from \"./filters/OptimisticLockErrorFilter\";\nexport * from \"./interceptors/TransactionalInterceptor\";\nexport * from \"./services/MikroOrmContext\";\nexport * from \"./services/MikroOrmFactory\";\nexport * from \"./services/MikroOrmRegistry\";\nexport * from \"./services/RetryStrategy\";\n"]}
@@ -1,10 +1,15 @@
1
1
  import { __decorate, __metadata, __param } from "tslib";
2
2
  import { Inject, Interceptor } from "@tsed/di";
3
3
  import { Logger } from "@tsed/logger";
4
- import { MikroOrmRegistry } from "../services/MikroOrmRegistry.js";
5
- import { DBContext } from "../services/DBContext.js";
6
4
  import { RetryStrategy } from "../services/RetryStrategy.js";
5
+ import { MikroOrmContext } from "../services/MikroOrmContext.js";
6
+ import { MikroOrmRegistry } from "../services/MikroOrmRegistry.js";
7
+ import { IsolationLevel } from "@mikro-orm/core";
7
8
  let TransactionalInterceptor = class TransactionalInterceptor {
9
+ registry;
10
+ context;
11
+ logger;
12
+ retryStrategy;
8
13
  constructor(registry, context, logger, retryStrategy) {
9
14
  this.registry = registry;
10
15
  this.context = context;
@@ -16,65 +21,59 @@ let TransactionalInterceptor = class TransactionalInterceptor {
16
21
  if (options.retry && !this.retryStrategy) {
17
22
  this.logger.warn(`To retry a transaction you have to implement a "${RetryStrategy.description}" interface`);
18
23
  }
19
- const ctx = this.context.entries();
20
- if (!ctx) {
21
- return this.runWithinNewCtx(next, options);
24
+ if (this.context.has(options.contextName)) {
25
+ return this.runWithinCtx(next, options);
22
26
  }
23
- if (ctx.has(options.contextName)) {
24
- return next();
25
- }
26
- return this.runUnderCtx(next, ctx, options);
27
+ return this.runWithinNewCtx(next, options);
27
28
  }
28
- runWithinNewCtx(next, options) {
29
- const ctx = new Map();
30
- return this.runUnderCtx(next, ctx, options);
29
+ runWithinCtx(next, options) {
30
+ const callback = () => this.executeInTransaction(next, options);
31
+ return options.retry && this.retryStrategy ? this.retryStrategy.acquire(callback) : callback();
31
32
  }
32
- runUnderCtx(next, ctx, options) {
33
+ runWithinNewCtx(next, options) {
33
34
  const orm = this.registry.get(options.contextName);
34
35
  if (!orm) {
35
36
  throw new Error(`No such context: ${options.contextName}. Please register a corresponding MikroOrm instance using '@Configuration()' decorator.`);
36
37
  }
37
- /**
38
- * The fork method signature has been changed since v5.x,
39
- * which might lead to unexpected behavior while using the @Transactional() decorator.
40
- *
41
- * ```diff
42
- * - fork(clear = true, useContext = false): D[typeof EntityManagerType]
43
- * + fork(options: ForkOptions = {}): D[typeof EntityManagerType] {
44
- * ```
45
- *
46
- * To ensure backward compatibility with v4.x and add support for v5.x, provided the following workaround:
47
- */
48
- const em = orm.em.fork({ clear: true, useContext: true }, true);
49
- ctx.set(em.name, em);
50
- const runInTransaction = () => this.executeInTransaction(options.contextName, next);
51
- return this.context.run(ctx, () => { var _a; return (options.retry ? (_a = this.retryStrategy) === null || _a === void 0 ? void 0 : _a.acquire(runInTransaction) : runInTransaction()); });
38
+ return this.context.run([orm.em], () => this.runWithinCtx(next, options));
52
39
  }
53
40
  extractContextName(context) {
54
- var _a;
55
- const options = context.options || {};
41
+ const options = (context.options || {});
42
+ let isolationLevel;
43
+ let disabled;
56
44
  let contextName;
45
+ let flushMode;
57
46
  let retry;
58
47
  if (typeof options === "string") {
59
48
  contextName = options;
60
49
  }
61
50
  else if (options) {
62
- contextName = (_a = options.contextName) !== null && _a !== void 0 ? _a : options.connectionName;
51
+ contextName = options.contextName;
52
+ isolationLevel = options.isolationLevel;
63
53
  retry = options.retry;
54
+ disabled = options.disabled;
55
+ flushMode = options.flushMode;
64
56
  }
65
- if (!contextName) {
66
- contextName = "default";
57
+ return {
58
+ flushMode,
59
+ retry: retry ?? false,
60
+ disabled: disabled ?? false,
61
+ contextName: contextName ?? "default",
62
+ isolationLevel: isolationLevel ?? IsolationLevel.READ_COMMITTED
63
+ };
64
+ }
65
+ async executeInTransaction(next, options) {
66
+ const manager = this.context.get(options.contextName);
67
+ if (!manager) {
68
+ throw new Error(`No such context: ${options.contextName}. Please check if the async context is lost in one of the asynchronous operations.`);
67
69
  }
68
- if (!retry) {
69
- retry = false;
70
+ if (options.disabled) {
71
+ return next();
70
72
  }
71
- return { contextName, retry };
72
- }
73
- async executeInTransaction(contextName, next) {
74
- const em = this.context.get(contextName);
75
- const result = await next();
76
- await (em === null || em === void 0 ? void 0 : em.flush());
77
- return result;
73
+ return manager.transactional(() => next(), {
74
+ flushMode: options.flushMode,
75
+ isolationLevel: options.isolationLevel
76
+ });
78
77
  }
79
78
  };
80
79
  TransactionalInterceptor = __decorate([
@@ -84,7 +83,7 @@ TransactionalInterceptor = __decorate([
84
83
  __param(2, Inject()),
85
84
  __param(3, Inject(RetryStrategy)),
86
85
  __metadata("design:paramtypes", [MikroOrmRegistry,
87
- DBContext,
86
+ MikroOrmContext,
88
87
  Logger, Object])
89
88
  ], TransactionalInterceptor);
90
89
  export { TransactionalInterceptor };
@@ -1 +1 @@
1
- {"version":3,"file":"TransactionalInterceptor.js","sourceRoot":"","sources":["../../../src/interceptors/TransactionalInterceptor.ts"],"names":[],"mappings":"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","sourcesContent":["import {Inject, Interceptor, InterceptorContext, InterceptorMethods, InterceptorNext} from \"@tsed/di\";\nimport {EntityManager} from \"@mikro-orm/core\";\nimport {Logger} from \"@tsed/logger\";\nimport {MikroOrmRegistry} from \"../services/MikroOrmRegistry\";\nimport {DBContext} from \"../services/DBContext\";\nimport {RetryStrategy} from \"../services/RetryStrategy\";\n\nexport interface TransactionOptions {\n retry?: boolean;\n contextName?: string;\n}\n\n@Interceptor()\nexport class TransactionalInterceptor implements InterceptorMethods {\n constructor(\n @Inject() private readonly registry: MikroOrmRegistry,\n @Inject() private readonly context: DBContext,\n @Inject() private readonly logger: Logger,\n @Inject(RetryStrategy)\n private readonly retryStrategy?: RetryStrategy\n ) {}\n\n public async intercept(context: InterceptorContext<unknown>, next: InterceptorNext): Promise<unknown> {\n const options = this.extractContextName(context);\n\n if (options.retry && !this.retryStrategy) {\n this.logger.warn(`To retry a transaction you have to implement a \"${RetryStrategy.description}\" interface`);\n }\n\n const ctx = this.context.entries();\n\n if (!ctx) {\n return this.runWithinNewCtx(next, options);\n }\n\n if (ctx.has(options.contextName!)) {\n return next();\n }\n\n return this.runUnderCtx(next, ctx, options);\n }\n\n private runWithinNewCtx(next: InterceptorNext, options: TransactionOptions): Promise<unknown> | unknown {\n const ctx = new Map<string, EntityManager>();\n\n return this.runUnderCtx(next, ctx, options);\n }\n\n private runUnderCtx(next: InterceptorNext, ctx: Map<string, EntityManager>, options: TransactionOptions): Promise<unknown> | unknown {\n const orm = this.registry.get(options.contextName);\n\n if (!orm) {\n throw new Error(\n `No such context: ${options.contextName}. Please register a corresponding MikroOrm instance using '@Configuration()' decorator.`\n );\n }\n\n /**\n * The fork method signature has been changed since v5.x,\n * which might lead to unexpected behavior while using the @Transactional() decorator.\n *\n * ```diff\n * - fork(clear = true, useContext = false): D[typeof EntityManagerType]\n * + fork(options: ForkOptions = {}): D[typeof EntityManagerType] {\n * ```\n *\n * To ensure backward compatibility with v4.x and add support for v5.x, provided the following workaround:\n */\n const em = (\n orm.em.fork as (clearOrForkOptions?: boolean | {clear?: boolean; useContext?: boolean}, useContext?: boolean) => EntityManager\n )({clear: true, useContext: true}, true);\n\n ctx.set(em.name, em);\n\n const runInTransaction = () => this.executeInTransaction(options.contextName!, next);\n\n return this.context.run(ctx, () => (options.retry ? this.retryStrategy?.acquire(runInTransaction) : runInTransaction()));\n }\n\n private extractContextName(context: InterceptorContext<unknown>): TransactionOptions {\n const options = context.options || ({} as Partial<TransactionOptions> | string);\n\n let contextName: string | undefined;\n let retry: boolean | undefined;\n\n if (typeof options === \"string\") {\n contextName = options;\n } else if (options) {\n contextName = options.contextName ?? options.connectionName;\n retry = options.retry;\n }\n\n if (!contextName) {\n contextName = \"default\";\n }\n\n if (!retry) {\n retry = false;\n }\n\n return {contextName, retry};\n }\n\n private async executeInTransaction(contextName: string, next: InterceptorNext): Promise<unknown> {\n const em = this.context.get(contextName);\n\n const result = await next();\n\n await em?.flush();\n\n return result;\n }\n}\n"]}
1
+ {"version":3,"file":"TransactionalInterceptor.js","sourceRoot":"","sources":["../../../src/interceptors/TransactionalInterceptor.ts"],"names":[],"mappings":"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","sourcesContent":["import {Inject, Interceptor, InterceptorContext, InterceptorMethods, InterceptorNext} from \"@tsed/di\";\nimport {Logger} from \"@tsed/logger\";\nimport {RetryStrategy} from \"../services/RetryStrategy\";\nimport {MikroOrmContext} from \"../services/MikroOrmContext\";\nimport {MikroOrmRegistry} from \"../services/MikroOrmRegistry\";\nimport {FlushMode, IsolationLevel} from \"@mikro-orm/core\";\n\nexport interface TransactionOptions {\n retry?: boolean;\n disabled?: boolean;\n isolationLevel?: IsolationLevel;\n flushMode?: FlushMode;\n contextName?: string;\n}\n\ntype TransactionSettings = Required<Omit<TransactionOptions, \"connectionName\" | \"flushMode\">> & {flushMode?: FlushMode};\n\n@Interceptor()\nexport class TransactionalInterceptor implements InterceptorMethods {\n constructor(\n @Inject() private readonly registry: MikroOrmRegistry,\n @Inject() private readonly context: MikroOrmContext,\n @Inject() private readonly logger: Logger,\n @Inject(RetryStrategy)\n private readonly retryStrategy?: RetryStrategy\n ) {}\n\n public async intercept(context: InterceptorContext<unknown>, next: InterceptorNext): Promise<unknown> {\n const options = this.extractContextName(context);\n\n if (options.retry && !this.retryStrategy) {\n this.logger.warn(`To retry a transaction you have to implement a \"${RetryStrategy.description}\" interface`);\n }\n\n if (this.context.has(options.contextName)) {\n return this.runWithinCtx(next, options);\n }\n\n return this.runWithinNewCtx(next, options);\n }\n\n private runWithinCtx(next: InterceptorNext, options: TransactionSettings): Promise<unknown> | unknown {\n const callback = () => this.executeInTransaction(next, options);\n\n return options.retry && this.retryStrategy ? this.retryStrategy.acquire(callback) : callback();\n }\n\n private runWithinNewCtx(next: InterceptorNext, options: TransactionSettings): Promise<unknown> | unknown {\n const orm = this.registry.get(options.contextName);\n\n if (!orm) {\n throw new Error(\n `No such context: ${options.contextName}. Please register a corresponding MikroOrm instance using '@Configuration()' decorator.`\n );\n }\n\n return this.context.run([orm.em], () => this.runWithinCtx(next, options));\n }\n\n private extractContextName(context: InterceptorContext<unknown>): TransactionSettings {\n const options = (context.options || {}) as TransactionOptions | string;\n\n let isolationLevel: IsolationLevel | undefined;\n let disabled: boolean | undefined;\n let contextName: string | undefined;\n let flushMode: FlushMode | undefined;\n let retry: boolean | undefined;\n\n if (typeof options === \"string\") {\n contextName = options;\n } else if (options) {\n contextName = options.contextName;\n isolationLevel = options.isolationLevel;\n retry = options.retry;\n disabled = options.disabled;\n flushMode = options.flushMode;\n }\n\n return {\n flushMode,\n retry: retry ?? false,\n disabled: disabled ?? false,\n contextName: contextName ?? \"default\",\n isolationLevel: isolationLevel ?? IsolationLevel.READ_COMMITTED\n };\n }\n\n private async executeInTransaction(next: InterceptorNext, options: TransactionSettings): Promise<unknown> {\n const manager = this.context.get(options.contextName);\n\n if (!manager) {\n throw new Error(\n `No such context: ${options.contextName}. Please check if the async context is lost in one of the asynchronous operations.`\n );\n }\n\n if (options.disabled) {\n return next();\n }\n\n return manager.transactional(() => next(), {\n flushMode: options.flushMode,\n isolationLevel: options.isolationLevel\n });\n }\n}\n"]}
@@ -0,0 +1,23 @@
1
+ import { __decorate } from "tslib";
2
+ import { Injectable } from "@tsed/di";
3
+ import { RequestContext } from "@mikro-orm/core";
4
+ /**
5
+ * @internal Since 2022-06-20.
6
+ */
7
+ let MikroOrmContext = class MikroOrmContext {
8
+ run(managers, task) {
9
+ return RequestContext.createAsync(managers, task);
10
+ }
11
+ get(contextName) {
12
+ return RequestContext.getEntityManager(contextName);
13
+ }
14
+ has(contextName) {
15
+ const manager = this.get(contextName);
16
+ return !!manager;
17
+ }
18
+ };
19
+ MikroOrmContext = __decorate([
20
+ Injectable()
21
+ ], MikroOrmContext);
22
+ export { MikroOrmContext };
23
+ //# sourceMappingURL=MikroOrmContext.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MikroOrmContext.js","sourceRoot":"","sources":["../../../src/services/MikroOrmContext.ts"],"names":[],"mappings":";AAAA,OAAO,EAAC,UAAU,EAAC,MAAM,UAAU,CAAC;AACpC,OAAO,EAAgB,cAAc,EAAC,MAAM,iBAAiB,CAAC;AAE9D;;GAEG;AAEH,IAAa,eAAe,GAA5B,MAAa,eAAe;IACnB,GAAG,CAAC,QAAyB,EAAE,IAAqC;QACzE,OAAO,cAAc,CAAC,WAAW,CAAC,QAAQ,EAAE,IAAW,CAAC,CAAC;IAC3D,CAAC;IAEM,GAAG,CAAC,WAAoB;QAC7B,OAAO,cAAc,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC;IACtD,CAAC;IAEM,GAAG,CAAC,WAAoB;QAC7B,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QAEtC,OAAO,CAAC,CAAC,OAAO,CAAC;IACnB,CAAC;CACF,CAAA;AAdY,eAAe;IAD3B,UAAU,EAAE;GACA,eAAe,CAc3B;SAdY,eAAe","sourcesContent":["import {Injectable} from \"@tsed/di\";\nimport {EntityManager, RequestContext} from \"@mikro-orm/core\";\n\n/**\n * @internal Since 2022-06-20.\n */\n@Injectable()\nexport class MikroOrmContext {\n public run(managers: EntityManager[], task: (...args: unknown[]) => unknown): Promise<unknown> {\n return RequestContext.createAsync(managers, task as any);\n }\n\n public get(contextName?: string): EntityManager | undefined {\n return RequestContext.getEntityManager(contextName);\n }\n\n public has(contextName?: string): boolean {\n const manager = this.get(contextName);\n\n return !!manager;\n }\n}\n"]}
@@ -1,21 +1,23 @@
1
- import { __decorate, __metadata } from "tslib";
2
- import { DBContext } from "./DBContext.js";
1
+ import { __decorate, __metadata, __param } from "tslib";
3
2
  import { MikroORM } from "@mikro-orm/core";
4
3
  import { Inject, Injectable } from "@tsed/di";
4
+ import { MikroOrmContext } from "./MikroOrmContext.js";
5
5
  let MikroOrmFactory = class MikroOrmFactory {
6
+ context;
7
+ constructor(context) {
8
+ this.context = context;
9
+ }
6
10
  create(options) {
7
11
  return MikroORM.init({
8
12
  ...options,
9
- context: (name) => this.dbContext.get(name)
13
+ context: (name) => this.context.get(name)
10
14
  });
11
15
  }
12
16
  };
13
- __decorate([
14
- Inject(),
15
- __metadata("design:type", DBContext)
16
- ], MikroOrmFactory.prototype, "dbContext", void 0);
17
17
  MikroOrmFactory = __decorate([
18
- Injectable()
18
+ Injectable(),
19
+ __param(0, Inject()),
20
+ __metadata("design:paramtypes", [MikroOrmContext])
19
21
  ], MikroOrmFactory);
20
22
  export { MikroOrmFactory };
21
23
  //# sourceMappingURL=MikroOrmFactory.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MikroOrmFactory.js","sourceRoot":"","sources":["../../../src/services/MikroOrmFactory.ts"],"names":[],"mappings":";AAAA,OAAO,EAAC,SAAS,EAAC,MAAM,aAAa,CAAC;AACtC,OAAO,EAAC,QAAQ,EAAU,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAC,MAAM,EAAE,UAAU,EAAC,MAAM,UAAU,CAAC;AAG5C,IAAa,eAAe,GAA5B,MAAa,eAAe;IAInB,MAAM,CAAC,OAAgB;QAC5B,OAAO,QAAQ,CAAC,IAAI,CAAC;YACnB,GAAG,OAAO;YACV,OAAO,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;SACpD,CAAC,CAAC;IACL,CAAC;CACF,CAAA;AARC;IADC,MAAM,EAAE;8BACoB,SAAS;kDAAC;AAF5B,eAAe;IAD3B,UAAU,EAAE;GACA,eAAe,CAU3B;SAVY,eAAe","sourcesContent":["import {DBContext} from \"./DBContext\";\nimport {MikroORM, Options} from \"@mikro-orm/core\";\nimport {Inject, Injectable} from \"@tsed/di\";\n\n@Injectable()\nexport class MikroOrmFactory {\n @Inject()\n private readonly dbContext!: DBContext;\n\n public create(options: Options): Promise<MikroORM> {\n return MikroORM.init({\n ...options,\n context: (name: string) => this.dbContext.get(name)\n });\n }\n}\n"]}
1
+ {"version":3,"file":"MikroOrmFactory.js","sourceRoot":"","sources":["../../../src/services/MikroOrmFactory.ts"],"names":[],"mappings":";AAAA,OAAO,EAAC,QAAQ,EAAU,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAC,MAAM,EAAE,UAAU,EAAC,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAC;AAGlD,IAAa,eAAe,GAA5B,MAAa,eAAe;IACa;IAAvC,YAAuC,OAAwB;QAAxB,YAAO,GAAP,OAAO,CAAiB;IAAG,CAAC;IAE5D,MAAM,CAAC,OAAgB;QAC5B,OAAO,QAAQ,CAAC,IAAI,CAAC;YACnB,GAAG,OAAO;YACV,OAAO,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;SAClD,CAAC,CAAC;IACL,CAAC;CACF,CAAA;AATY,eAAe;IAD3B,UAAU,EAAE;IAEE,WAAA,MAAM,EAAE,CAAA;qCAA2B,eAAe;GADpD,eAAe,CAS3B;SATY,eAAe","sourcesContent":["import {MikroORM, Options} from \"@mikro-orm/core\";\nimport {Inject, Injectable} from \"@tsed/di\";\nimport {MikroOrmContext} from \"./MikroOrmContext\";\n\n@Injectable()\nexport class MikroOrmFactory {\n constructor(@Inject() private readonly context: MikroOrmContext) {}\n\n public create(options: Options): Promise<MikroORM> {\n return MikroORM.init({\n ...options,\n context: (name: string) => this.context.get(name)\n });\n }\n}\n"]}
@@ -4,13 +4,16 @@ import { Inject, Injectable } from "@tsed/di";
4
4
  import { catchAsyncError, getValue } from "@tsed/core";
5
5
  import { Logger } from "@tsed/logger";
6
6
  let MikroOrmRegistry = class MikroOrmRegistry {
7
+ logger;
8
+ mikroOrmFactory;
9
+ DEFAULT_CONTEXT_NAME = "default";
10
+ instances = new Map();
7
11
  constructor(logger, mikroOrmFactory) {
8
12
  this.logger = logger;
9
13
  this.mikroOrmFactory = mikroOrmFactory;
10
- this.instances = new Map();
11
14
  }
12
15
  async register(options) {
13
- const contextName = getValue(options, "contextName", "default");
16
+ const contextName = getValue(options, "contextName", this.DEFAULT_CONTEXT_NAME);
14
17
  if (this.has(contextName)) {
15
18
  return this.get(contextName);
16
19
  }
@@ -21,11 +24,14 @@ let MikroOrmRegistry = class MikroOrmRegistry {
21
24
  this.logger.info(`Connected with MikroOrm to database: %s`, contextName);
22
25
  return instance;
23
26
  }
24
- get(contextName = "default") {
25
- return this.instances.get(contextName);
27
+ get(contextName) {
28
+ return this.instances.get(contextName ?? this.DEFAULT_CONTEXT_NAME);
26
29
  }
27
- has(contextName = "default") {
28
- return this.instances.has(contextName);
30
+ has(contextName) {
31
+ return this.instances.has(contextName ?? this.DEFAULT_CONTEXT_NAME);
32
+ }
33
+ values() {
34
+ return this.instances.values();
29
35
  }
30
36
  async clear() {
31
37
  const instances = [...this.instances.values()];
@@ -1 +1 @@
1
- {"version":3,"file":"MikroOrmRegistry.js","sourceRoot":"","sources":["../../../src/services/MikroOrmRegistry.ts"],"names":[],"mappings":";AAAA,OAAO,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAC,MAAM,EAAE,UAAU,EAAC,MAAM,UAAU,CAAC;AAE5C,OAAO,EAAC,eAAe,EAAE,QAAQ,EAAC,MAAM,YAAY,CAAC;AACrD,OAAO,EAAC,MAAM,EAAC,MAAM,cAAc,CAAC;AAGpC,IAAa,gBAAgB,GAA7B,MAAa,gBAAgB;IAG3B,YAAuC,MAAc,EAA6B,eAAgC;QAA3E,WAAM,GAAN,MAAM,CAAQ;QAA6B,oBAAe,GAAf,eAAe,CAAiB;QAFjG,cAAS,GAAG,IAAI,GAAG,EAAoB,CAAC;IAE4D,CAAC;IAE/G,KAAK,CAAC,QAAQ,CAA2B,OAAmB;QACjE,MAAM,WAAW,GAAG,QAAQ,CAAS,OAAO,EAAE,aAAa,EAAE,SAAS,CAAC,CAAC;QAExE,IAAI,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE;YACzB,OAAO,IAAI,CAAC,GAAG,CAAC,WAAW,CAAE,CAAC;SAC/B;QAED,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,iDAAiD,EAAE,WAAW,CAAC,CAAC;QACjF,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;QAE1C,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAE5D,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;QAE1C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,yCAAyC,EAAE,WAAW,CAAC,CAAC;QAEzE,OAAO,QAAQ,CAAC;IAClB,CAAC;IAEM,GAAG,CAAC,cAAsB,SAAS;QACxC,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IACzC,CAAC;IAEM,GAAG,CAAC,cAAsB,SAAS;QACxC,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IACzC,CAAC;IAEM,KAAK,CAAC,KAAK;QAChB,MAAM,SAAS,GAAG,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;QAE/C,MAAM,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,QAAkB,EAAE,EAAE,CAAC,eAAe,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QAExG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;IACzB,CAAC;IAEO,KAAK,CAAC,OAAO,CAAC,QAAkB;QACtC,IAAI,MAAM,QAAQ,CAAC,WAAW,EAAE,EAAE;YAChC,MAAM,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;SAC7B;IACH,CAAC;CACF,CAAA;AA7CY,gBAAgB;IAD5B,UAAU,EAAE;IAIE,WAAA,MAAM,EAAE,CAAA;IAAmC,WAAA,MAAM,EAAE,CAAA;qCAAjB,MAAM,EAA8C,eAAe;GAHvG,gBAAgB,CA6C5B;SA7CY,gBAAgB","sourcesContent":["import {MikroOrmFactory} from \"./MikroOrmFactory\";\nimport {Inject, Injectable} from \"@tsed/di\";\nimport {IDatabaseDriver as DatabaseDriver, MikroORM, Options} from \"@mikro-orm/core\";\nimport {catchAsyncError, getValue} from \"@tsed/core\";\nimport {Logger} from \"@tsed/logger\";\n\n@Injectable()\nexport class MikroOrmRegistry {\n private readonly instances = new Map<string, MikroORM>();\n\n constructor(@Inject() private readonly logger: Logger, @Inject() private readonly mikroOrmFactory: MikroOrmFactory) {}\n\n public async register<T extends DatabaseDriver>(options: Options<T>): Promise<MikroORM> {\n const contextName = getValue<string>(options, \"contextName\", \"default\");\n\n if (this.has(contextName)) {\n return this.get(contextName)!;\n }\n\n this.logger.info(`Create connection with MikroOrm to database: %s`, contextName);\n this.logger.debug(`options: %j`, options);\n\n const instance = await this.mikroOrmFactory.create(options);\n\n this.instances.set(contextName, instance);\n\n this.logger.info(`Connected with MikroOrm to database: %s`, contextName);\n\n return instance;\n }\n\n public get(contextName: string = \"default\"): MikroORM | undefined {\n return this.instances.get(contextName);\n }\n\n public has(contextName: string = \"default\"): boolean {\n return this.instances.has(contextName);\n }\n\n public async clear(): Promise<void> {\n const instances = [...this.instances.values()];\n\n await Promise.all(instances.map((instance: MikroORM) => catchAsyncError(() => this.dispose(instance))));\n\n this.instances.clear();\n }\n\n private async dispose(instance: MikroORM): Promise<void> {\n if (await instance.isConnected()) {\n await instance.close(false);\n }\n }\n}\n"]}
1
+ {"version":3,"file":"MikroOrmRegistry.js","sourceRoot":"","sources":["../../../src/services/MikroOrmRegistry.ts"],"names":[],"mappings":";AAAA,OAAO,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAC,MAAM,EAAE,UAAU,EAAC,MAAM,UAAU,CAAC;AAE5C,OAAO,EAAC,eAAe,EAAE,QAAQ,EAAC,MAAM,YAAY,CAAC;AACrD,OAAO,EAAC,MAAM,EAAC,MAAM,cAAc,CAAC;AAGpC,IAAa,gBAAgB,GAA7B,MAAa,gBAAgB;IAIY;IAA2C;IAHjE,oBAAoB,GAAG,SAAS,CAAC;IACjC,SAAS,GAAG,IAAI,GAAG,EAAoB,CAAC;IAEzD,YAAuC,MAAc,EAA6B,eAAgC;QAA3E,WAAM,GAAN,MAAM,CAAQ;QAA6B,oBAAe,GAAf,eAAe,CAAiB;IAAG,CAAC;IAE/G,KAAK,CAAC,QAAQ,CAA2B,OAAmB;QACjE,MAAM,WAAW,GAAG,QAAQ,CAAS,OAAO,EAAE,aAAa,EAAE,IAAI,CAAC,oBAAoB,CAAC,CAAC;QAExF,IAAI,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE;YACzB,OAAO,IAAI,CAAC,GAAG,CAAC,WAAW,CAAE,CAAC;SAC/B;QAED,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,iDAAiD,EAAE,WAAW,CAAC,CAAC;QACjF,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;QAE1C,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAE5D,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;QAE1C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,yCAAyC,EAAE,WAAW,CAAC,CAAC;QAEzE,OAAO,QAAQ,CAAC;IAClB,CAAC;IAEM,GAAG,CAAC,WAAoB;QAC7B,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,WAAW,IAAI,IAAI,CAAC,oBAAoB,CAAC,CAAC;IACtE,CAAC;IAEM,GAAG,CAAC,WAAoB;QAC7B,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,WAAW,IAAI,IAAI,CAAC,oBAAoB,CAAC,CAAC;IACtE,CAAC;IAEM,MAAM;QACX,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC;IACjC,CAAC;IAEM,KAAK,CAAC,KAAK;QAChB,MAAM,SAAS,GAAG,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;QAE/C,MAAM,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,QAAkB,EAAE,EAAE,CAAC,eAAe,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QAExG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;IACzB,CAAC;IAEO,KAAK,CAAC,OAAO,CAAC,QAAkB;QACtC,IAAI,MAAM,QAAQ,CAAC,WAAW,EAAE,EAAE;YAChC,MAAM,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;SAC7B;IACH,CAAC;CACF,CAAA;AAlDY,gBAAgB;IAD5B,UAAU,EAAE;IAKE,WAAA,MAAM,EAAE,CAAA;IAAmC,WAAA,MAAM,EAAE,CAAA;qCAAjB,MAAM,EAA8C,eAAe;GAJvG,gBAAgB,CAkD5B;SAlDY,gBAAgB","sourcesContent":["import {MikroOrmFactory} from \"./MikroOrmFactory\";\nimport {Inject, Injectable} from \"@tsed/di\";\nimport {IDatabaseDriver as DatabaseDriver, MikroORM, Options} from \"@mikro-orm/core\";\nimport {catchAsyncError, getValue} from \"@tsed/core\";\nimport {Logger} from \"@tsed/logger\";\n\n@Injectable()\nexport class MikroOrmRegistry {\n private readonly DEFAULT_CONTEXT_NAME = \"default\";\n private readonly instances = new Map<string, MikroORM>();\n\n constructor(@Inject() private readonly logger: Logger, @Inject() private readonly mikroOrmFactory: MikroOrmFactory) {}\n\n public async register<T extends DatabaseDriver>(options: Options<T>): Promise<MikroORM> {\n const contextName = getValue<string>(options, \"contextName\", this.DEFAULT_CONTEXT_NAME);\n\n if (this.has(contextName)) {\n return this.get(contextName)!;\n }\n\n this.logger.info(`Create connection with MikroOrm to database: %s`, contextName);\n this.logger.debug(`options: %j`, options);\n\n const instance = await this.mikroOrmFactory.create(options);\n\n this.instances.set(contextName, instance);\n\n this.logger.info(`Connected with MikroOrm to database: %s`, contextName);\n\n return instance;\n }\n\n public get(contextName?: string): MikroORM | undefined {\n return this.instances.get(contextName ?? this.DEFAULT_CONTEXT_NAME);\n }\n\n public has(contextName?: string): boolean {\n return this.instances.has(contextName ?? this.DEFAULT_CONTEXT_NAME);\n }\n\n public values(): IterableIterator<MikroORM> {\n return this.instances.values();\n }\n\n public async clear(): Promise<void> {\n const instances = [...this.instances.values()];\n\n await Promise.all(instances.map((instance: MikroORM) => catchAsyncError(() => this.dispose(instance))));\n\n this.instances.clear();\n }\n\n private async dispose(instance: MikroORM): Promise<void> {\n if (await instance.isConnected()) {\n await instance.close(false);\n }\n }\n}\n"]}
@@ -1,4 +1,5 @@
1
- import { OnDestroy, OnInit } from "@tsed/di";
1
+ import "./services/MikroOrmFactory";
2
+ import { AlterRunInContext, DIContext, OnDestroy, OnInit } from "@tsed/di";
2
3
  import { Options } from "@mikro-orm/core";
3
4
  declare global {
4
5
  namespace TsED {
@@ -11,9 +12,12 @@ declare global {
11
12
  }
12
13
  }
13
14
  }
14
- export declare class MikroOrmModule implements OnDestroy, OnInit {
15
+ export declare class MikroOrmModule implements OnDestroy, OnInit, AlterRunInContext {
15
16
  private readonly settings;
16
- private readonly mikroOrmRegistry;
17
+ private readonly registry;
18
+ private readonly context;
17
19
  $onInit(): Promise<void>;
18
20
  $onDestroy(): Promise<void>;
21
+ $alterRunInContext(next: (...args: unknown[]) => unknown, _: DIContext): () => unknown | Promise<() => unknown>;
22
+ private createContext;
19
23
  }
@@ -4,11 +4,11 @@
4
4
  * @decorator
5
5
  * @mikroOrm
6
6
  */
7
- export declare const EntityManager: (contextName?: string | undefined) => PropertyDecorator;
7
+ export declare const EntityManager: (contextName?: string) => PropertyDecorator;
8
8
  /**
9
9
  * Get the entity manager for the given context name.
10
10
  * @param {String} connectionName
11
11
  * @decorator
12
12
  * @mikroOrm
13
13
  */
14
- export declare const Em: (contextName?: string | undefined) => PropertyDecorator;
14
+ export declare const Em: (contextName?: string) => PropertyDecorator;
@@ -2,4 +2,4 @@
2
2
  * Get the ORM for the given context name.
3
3
  * @param {String} contextName
4
4
  */
5
- export declare const Orm: (contextName?: string | undefined) => PropertyDecorator;
5
+ export declare const Orm: (contextName?: string) => PropertyDecorator;
@@ -3,4 +3,4 @@ import { TransactionOptions } from "../interceptors/TransactionalInterceptor";
3
3
  * Register a new request context for your method and execute it inside the context.
4
4
  * @param {String | TransactionOptions} contextNameOrOptions
5
5
  */
6
- export declare const Transactional: (contextNameOrOptions?: string | TransactionOptions | undefined) => MethodDecorator;
6
+ export declare const Transactional: (contextNameOrOptions?: string | TransactionOptions) => MethodDecorator;
@@ -7,7 +7,7 @@ export * from "./decorators/orm";
7
7
  export * from "./decorators/transactional";
8
8
  export * from "./filters/OptimisticLockErrorFilter";
9
9
  export * from "./interceptors/TransactionalInterceptor";
10
- export * from "./services/DBContext";
10
+ export * from "./services/MikroOrmContext";
11
11
  export * from "./services/MikroOrmFactory";
12
12
  export * from "./services/MikroOrmRegistry";
13
13
  export * from "./services/RetryStrategy";
@@ -1,10 +1,14 @@
1
1
  import { InterceptorContext, InterceptorMethods, InterceptorNext } from "@tsed/di";
2
2
  import { Logger } from "@tsed/logger";
3
- import { MikroOrmRegistry } from "../services/MikroOrmRegistry";
4
- import { DBContext } from "../services/DBContext";
5
3
  import { RetryStrategy } from "../services/RetryStrategy";
4
+ import { MikroOrmContext } from "../services/MikroOrmContext";
5
+ import { MikroOrmRegistry } from "../services/MikroOrmRegistry";
6
+ import { FlushMode, IsolationLevel } from "@mikro-orm/core";
6
7
  export interface TransactionOptions {
7
8
  retry?: boolean;
9
+ disabled?: boolean;
10
+ isolationLevel?: IsolationLevel;
11
+ flushMode?: FlushMode;
8
12
  contextName?: string;
9
13
  }
10
14
  export declare class TransactionalInterceptor implements InterceptorMethods {
@@ -12,10 +16,10 @@ export declare class TransactionalInterceptor implements InterceptorMethods {
12
16
  private readonly context;
13
17
  private readonly logger;
14
18
  private readonly retryStrategy?;
15
- constructor(registry: MikroOrmRegistry, context: DBContext, logger: Logger, retryStrategy?: RetryStrategy | undefined);
19
+ constructor(registry: MikroOrmRegistry, context: MikroOrmContext, logger: Logger, retryStrategy?: RetryStrategy | undefined);
16
20
  intercept(context: InterceptorContext<unknown>, next: InterceptorNext): Promise<unknown>;
21
+ private runWithinCtx;
17
22
  private runWithinNewCtx;
18
- private runUnderCtx;
19
23
  private extractContextName;
20
24
  private executeInTransaction;
21
25
  }
@@ -0,0 +1,9 @@
1
+ import { EntityManager } from "@mikro-orm/core";
2
+ /**
3
+ * @internal Since 2022-06-20.
4
+ */
5
+ export declare class MikroOrmContext {
6
+ run(managers: EntityManager[], task: (...args: unknown[]) => unknown): Promise<unknown>;
7
+ get(contextName?: string): EntityManager | undefined;
8
+ has(contextName?: string): boolean;
9
+ }
@@ -1,5 +1,7 @@
1
1
  import { MikroORM, Options } from "@mikro-orm/core";
2
+ import { MikroOrmContext } from "./MikroOrmContext";
2
3
  export declare class MikroOrmFactory {
3
- private readonly dbContext;
4
+ private readonly context;
5
+ constructor(context: MikroOrmContext);
4
6
  create(options: Options): Promise<MikroORM>;
5
7
  }
@@ -4,11 +4,13 @@ import { Logger } from "@tsed/logger";
4
4
  export declare class MikroOrmRegistry {
5
5
  private readonly logger;
6
6
  private readonly mikroOrmFactory;
7
+ private readonly DEFAULT_CONTEXT_NAME;
7
8
  private readonly instances;
8
9
  constructor(logger: Logger, mikroOrmFactory: MikroOrmFactory);
9
10
  register<T extends DatabaseDriver>(options: Options<T>): Promise<MikroORM>;
10
11
  get(contextName?: string): MikroORM | undefined;
11
12
  has(contextName?: string): boolean;
13
+ values(): IterableIterator<MikroORM>;
12
14
  clear(): Promise<void>;
13
15
  private dispose;
14
16
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tsed/mikro-orm",
3
- "version": "7.0.0-beta.11",
3
+ "version": "7.0.0-beta.14",
4
4
  "description": "MikroORM package for Ts.ED framework",
5
5
  "private": false,
6
6
  "source": "./src/index.ts",
@@ -21,26 +21,26 @@
21
21
  "test": "cross-env NODE_ENV=test jest"
22
22
  },
23
23
  "dependencies": {
24
- "tslib": "2.3.1"
24
+ "tslib": "2.4.0"
25
25
  },
26
26
  "devDependencies": {
27
- "@mikro-orm/core": "^4.5.9",
28
- "@mikro-orm/mongodb": "^4.5.9",
29
- "@tsed/common": "7.0.0-beta.11",
30
- "@tsed/core": "7.0.0-beta.11",
31
- "@tsed/di": "7.0.0-beta.11",
32
- "@tsed/json-mapper": "7.0.0-beta.11",
27
+ "@mikro-orm/core": "^5.2.2",
28
+ "@mikro-orm/mongodb": "^5.2.2",
29
+ "@tsed/common": "7.0.0-beta.14",
30
+ "@tsed/core": "7.0.0-beta.14",
31
+ "@tsed/di": "7.0.0-beta.14",
32
+ "@tsed/json-mapper": "7.0.0-beta.14",
33
33
  "@tsed/logger": ">=6.1.1",
34
- "@tsed/schema": "7.0.0-beta.11",
35
- "@tsed/testing-mongoose": "7.0.0-beta.11",
34
+ "@tsed/schema": "7.0.0-beta.14",
35
+ "@tsed/testing-mongoose": "7.0.0-beta.14",
36
36
  "ts-mockito": "^2.6.1"
37
37
  },
38
38
  "peerDependencies": {
39
39
  "@mikro-orm/core": ">=4.5.9",
40
- "@tsed/common": "^7.0.0-beta.11",
41
- "@tsed/core": "^7.0.0-beta.11",
42
- "@tsed/di": "^7.0.0-beta.11",
43
- "@tsed/logger": ">=6.1.1"
40
+ "@tsed/common": "^7.0.0-beta.14",
41
+ "@tsed/core": "^7.0.0-beta.14",
42
+ "@tsed/di": "^7.0.0-beta.14",
43
+ "@tsed/logger": ">=6.2.0"
44
44
  },
45
45
  "repository": "https://github.com/tsedio/tsed",
46
46
  "bugs": {
@@ -48,5 +48,8 @@
48
48
  },
49
49
  "homepage": "https://github.com/tsedio/tsed/tree/beta/packages/orm/mikro-orm",
50
50
  "author": "Romain Lenzotti",
51
- "license": "MIT"
51
+ "license": "MIT",
52
+ "publishConfig": {
53
+ "tag": "beta"
54
+ }
52
55
  }
package/readme.md CHANGED
@@ -11,7 +11,8 @@
11
11
  [![npm version](https://badge.fury.io/js/%40tsed%2Fcommon.svg)](https://badge.fury.io/js/%40tsed%2Fcommon)
12
12
  [![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)
13
13
  [![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier)
14
- [![backers](https://opencollective.com/tsed/tiers/badge.svg)](https://opencollective.com/tsed)
14
+ [![github](https://img.shields.io/static/v1?label=Github%20sponsor&message=%E2%9D%A4&logo=GitHub&color=%23fe8e86)](https://github.com/sponsors/romakita)
15
+ [![opencollective](https://img.shields.io/static/v1?label=OpenCollective%20sponsor&message=%E2%9D%A4&logo=OpenCollective&color=%23fe8e86)](https://opencollective.com/tsed)
15
16
 
16
17
  </div>
17
18
 
@@ -131,7 +132,7 @@ export class UsersService {
131
132
 
132
133
  It's also possible to inject an ORM by its context name:
133
134
 
134
- ```ts
135
+ ```typescript
135
136
  import {Injectable} from "@tsed/di";
136
137
 
137
138
  @Injectable()
@@ -272,11 +273,47 @@ export class UsersCtrl {
272
273
  }
273
274
  ```
274
275
 
276
+ By default, `IsolationLevel.READ_COMMITTED` is used. You can override it, specifying the isolation level for the transaction by supplying it as the `isolationLevel` parameter in the `@Transactional` decorator:
277
+
278
+ ```typescript
279
+ @Post("/")
280
+ @Transactional({isolationLevel: IsolationLevel.SERIALIZABLE})
281
+ create(@BodyParams() user: User): Promise<User> {
282
+ return this.usersService.create(user);
283
+ }
284
+ ```
285
+
286
+ The MikroORM supports the standard isolation levels such as `SERIALIZABLE` or `REPEATABLE READ`, the full list of available options see [here](https://mikro-orm.io/docs/transactions#isolation-levels).
287
+
288
+ You can also set the [flushing strategy](https://mikro-orm.io/docs/unit-of-work#flush-modes) for the transaction by setting the `flushMode`:
289
+
290
+ ```typescript
291
+ @Post("/")
292
+ @Transactional({flushMode: FlushMode.AUTO})
293
+ create(@BodyParams() user: User): Promise<User> {
294
+ return this.usersService.create(user);
295
+ }
296
+ ```
297
+
298
+ In some cases, you might need to avoid an explicit transaction, but preserve an async context to prevent the usage of the global identity map. For example, starting with v3.4, the MongoDB driver supports transactions. Yet, you have to use a replica set, otherwise, the driver will raise an exception.
299
+
300
+ To prevent `@Transactional()` use of an explicit transaction, you just need to set the `disabled` field to `true`:
301
+
302
+ ```typescript
303
+ @Post("/")
304
+ @Transactional({disabled: true})
305
+ create(@BodyParams() user: User): Promise<User> {
306
+ return this.usersService.create(user);
307
+ }
308
+ ```
309
+
310
+ ## Retry policy
311
+
275
312
  By default, the automatic retry policy is disabled. You can implement your own to match the business requirements and the nature of the failure. For some noncritical operations, it is better to fail as soon as possible rather than retry a coupe of times. For example, in an interactive web application, it is better to fail right after a smaller number of retries with only a short delay between retry attempts, and display a message to the user (for example, "please try again later").
276
313
 
277
314
  The `@Transactional()` decorator allows you to enable a retry policy for the particular resources. You just need to implement the `RetryStrategy` interface and use `registerProvider()` or `@OverrideProvider()` to register it in the IoC container. Below you can find an example to handle occurred optimistic locks based on [an exponential backoff retry strategy](https://en.wikipedia.org/wiki/Exponential_backoff).
278
315
 
279
- ```ts
316
+ ```typescript
280
317
  import {OptimisticLockError} from "@mikro-orm/core";
281
318
  import {RetryStrategy} from "@tsed/mikro-orm";
282
319
 
@@ -1,9 +0,0 @@
1
- import { EntityManager } from "@mikro-orm/core";
2
- export declare class DBContext {
3
- private readonly storage;
4
- constructor();
5
- run<R>(ctx: Map<string, EntityManager>, callback: (...args: any[]) => R): R;
6
- entries(): Map<string, EntityManager> | undefined;
7
- get(contextName: string): EntityManager | undefined;
8
- has(contextName: string): boolean;
9
- }