@tsed/mikro-orm 6.96.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.
Files changed (88) hide show
  1. package/jest.config.js +14 -0
  2. package/lib/cjs/MikroOrmModule.d.ts +19 -0
  3. package/lib/cjs/MikroOrmModule.js +31 -0
  4. package/lib/cjs/MikroOrmModule.js.map +1 -0
  5. package/lib/cjs/decorators/connection.d.ts +1 -0
  6. package/lib/cjs/decorators/connection.js +8 -0
  7. package/lib/cjs/decorators/connection.js.map +1 -0
  8. package/lib/cjs/decorators/index.d.ts +2 -0
  9. package/lib/cjs/decorators/index.js +6 -0
  10. package/lib/cjs/decorators/index.js.map +1 -0
  11. package/lib/cjs/decorators/transactional.d.ts +2 -0
  12. package/lib/cjs/decorators/transactional.js +8 -0
  13. package/lib/cjs/decorators/transactional.js.map +1 -0
  14. package/lib/cjs/filters/OptimisticLockErrorFilter.d.ts +5 -0
  15. package/lib/cjs/filters/OptimisticLockErrorFilter.js +20 -0
  16. package/lib/cjs/filters/OptimisticLockErrorFilter.js.map +1 -0
  17. package/lib/cjs/filters/index.d.ts +1 -0
  18. package/lib/cjs/filters/index.js +5 -0
  19. package/lib/cjs/filters/index.js.map +1 -0
  20. package/lib/cjs/index.d.ts +5 -0
  21. package/lib/cjs/index.js +9 -0
  22. package/lib/cjs/index.js.map +1 -0
  23. package/lib/cjs/interceptors/TransactionalInterceptor.d.ts +16 -0
  24. package/lib/cjs/interceptors/TransactionalInterceptor.js +64 -0
  25. package/lib/cjs/interceptors/TransactionalInterceptor.js.map +1 -0
  26. package/lib/cjs/interceptors/index.d.ts +1 -0
  27. package/lib/cjs/interceptors/index.js +5 -0
  28. package/lib/cjs/interceptors/index.js.map +1 -0
  29. package/lib/cjs/services/DBContext.d.ts +9 -0
  30. package/lib/cjs/services/DBContext.js +37 -0
  31. package/lib/cjs/services/DBContext.js.map +1 -0
  32. package/lib/cjs/services/MikroOrmFactory.d.ts +5 -0
  33. package/lib/cjs/services/MikroOrmFactory.js +24 -0
  34. package/lib/cjs/services/MikroOrmFactory.js.map +1 -0
  35. package/lib/cjs/services/MikroOrmRegistry.d.ts +14 -0
  36. package/lib/cjs/services/MikroOrmRegistry.js +51 -0
  37. package/lib/cjs/services/MikroOrmRegistry.js.map +1 -0
  38. package/lib/cjs/services/RetryStrategy.d.ts +3 -0
  39. package/lib/cjs/services/RetryStrategy.js +3 -0
  40. package/lib/cjs/services/RetryStrategy.js.map +1 -0
  41. package/lib/cjs/services/index.d.ts +4 -0
  42. package/lib/cjs/services/index.js +8 -0
  43. package/lib/cjs/services/index.js.map +1 -0
  44. package/lib/esm/MikroOrmModule.js +28 -0
  45. package/lib/esm/MikroOrmModule.js.map +1 -0
  46. package/lib/esm/decorators/connection.js +4 -0
  47. package/lib/esm/decorators/connection.js.map +1 -0
  48. package/lib/esm/decorators/index.js +3 -0
  49. package/lib/esm/decorators/index.js.map +1 -0
  50. package/lib/esm/decorators/transactional.js +4 -0
  51. package/lib/esm/decorators/transactional.js.map +1 -0
  52. package/lib/esm/filters/OptimisticLockErrorFilter.js +17 -0
  53. package/lib/esm/filters/OptimisticLockErrorFilter.js.map +1 -0
  54. package/lib/esm/filters/index.js +2 -0
  55. package/lib/esm/filters/index.js.map +1 -0
  56. package/lib/esm/index.js +6 -0
  57. package/lib/esm/index.js.map +1 -0
  58. package/lib/esm/interceptors/TransactionalInterceptor.js +61 -0
  59. package/lib/esm/interceptors/TransactionalInterceptor.js.map +1 -0
  60. package/lib/esm/interceptors/index.js +2 -0
  61. package/lib/esm/interceptors/index.js.map +1 -0
  62. package/lib/esm/services/DBContext.js +34 -0
  63. package/lib/esm/services/DBContext.js.map +1 -0
  64. package/lib/esm/services/MikroOrmFactory.js +21 -0
  65. package/lib/esm/services/MikroOrmFactory.js.map +1 -0
  66. package/lib/esm/services/MikroOrmRegistry.js +48 -0
  67. package/lib/esm/services/MikroOrmRegistry.js.map +1 -0
  68. package/lib/esm/services/RetryStrategy.js +2 -0
  69. package/lib/esm/services/RetryStrategy.js.map +1 -0
  70. package/lib/esm/services/index.js +5 -0
  71. package/lib/esm/services/index.js.map +1 -0
  72. package/lib/types/MikroOrmModule.d.ts +19 -0
  73. package/lib/types/decorators/connection.d.ts +1 -0
  74. package/lib/types/decorators/index.d.ts +2 -0
  75. package/lib/types/decorators/transactional.d.ts +2 -0
  76. package/lib/types/filters/OptimisticLockErrorFilter.d.ts +5 -0
  77. package/lib/types/filters/index.d.ts +1 -0
  78. package/lib/types/index.d.ts +5 -0
  79. package/lib/types/interceptors/TransactionalInterceptor.d.ts +16 -0
  80. package/lib/types/interceptors/index.d.ts +1 -0
  81. package/lib/types/services/DBContext.d.ts +9 -0
  82. package/lib/types/services/MikroOrmFactory.d.ts +5 -0
  83. package/lib/types/services/MikroOrmRegistry.d.ts +14 -0
  84. package/lib/types/services/RetryStrategy.d.ts +3 -0
  85. package/lib/types/services/index.d.ts +4 -0
  86. package/package.json +49 -0
  87. package/readme.md +237 -0
  88. package/tsconfig.compile.esm.json +23 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC","sourcesContent":["export * from \"./decorators\";\nexport * from \"./filters\";\nexport * from \"./interceptors\";\nexport * from \"./services\";\nexport * from \"./MikroOrmModule\";\n"]}
@@ -0,0 +1,61 @@
1
+ import { __decorate, __metadata, __param } from "tslib";
2
+ import { DBContext, MikroOrmRegistry } from "../services";
3
+ import { Inject, Interceptor } from "@tsed/di";
4
+ let TransactionalInterceptor = class TransactionalInterceptor {
5
+ constructor(registry, context) {
6
+ this.registry = registry;
7
+ this.context = context;
8
+ }
9
+ async intercept(context, next) {
10
+ const options = this.extractContextName(context);
11
+ const ctx = this.context.getContext();
12
+ if (!ctx) {
13
+ return this.runWithinNewCtx(next, options);
14
+ }
15
+ if (ctx.has(options.connectionName)) {
16
+ return next();
17
+ }
18
+ return this.runUnderCtx(next, ctx, options);
19
+ }
20
+ runWithinNewCtx(next, options) {
21
+ const ctx = new Map();
22
+ return this.runUnderCtx(next, ctx, options);
23
+ }
24
+ runUnderCtx(next, ctx, options) {
25
+ const orm = this.registry.get(options.connectionName);
26
+ const em = orm.em.fork(true, true);
27
+ ctx.set(em.name, em);
28
+ const runInTransaction = () => this.executeInTransaction(options.connectionName, next);
29
+ return this.context.run(ctx, () => (options.retryStrategy ? options.retryStrategy.acquire(runInTransaction) : runInTransaction()));
30
+ }
31
+ extractContextName(context) {
32
+ const options = context.options || {};
33
+ let connectionName;
34
+ let retryStrategy;
35
+ if (typeof options === "string") {
36
+ connectionName = options;
37
+ }
38
+ else if (options) {
39
+ connectionName = options.connectionName;
40
+ retryStrategy = options.retryStrategy;
41
+ }
42
+ if (!connectionName) {
43
+ connectionName = "default";
44
+ }
45
+ return { connectionName, retryStrategy };
46
+ }
47
+ async executeInTransaction(connectionName, next) {
48
+ const em = this.context.get(connectionName);
49
+ const result = await next();
50
+ await (em === null || em === void 0 ? void 0 : em.flush());
51
+ return result;
52
+ }
53
+ };
54
+ TransactionalInterceptor = __decorate([
55
+ Interceptor(),
56
+ __param(0, Inject()),
57
+ __param(1, Inject()),
58
+ __metadata("design:paramtypes", [MikroOrmRegistry, DBContext])
59
+ ], TransactionalInterceptor);
60
+ export { TransactionalInterceptor };
61
+ //# sourceMappingURL=TransactionalInterceptor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TransactionalInterceptor.js","sourceRoot":"","sources":["../../../src/interceptors/TransactionalInterceptor.ts"],"names":[],"mappings":"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","sourcesContent":["import {DBContext, MikroOrmRegistry, RetryStrategy} from \"../services\";\nimport {Inject, Interceptor, InterceptorContext, InterceptorMethods, InterceptorNext} from \"@tsed/di\";\nimport {EntityManager} from \"@mikro-orm/core\";\n\nexport interface TransactionOptions {\n connectionName?: string;\n retryStrategy?: RetryStrategy;\n}\n\n@Interceptor()\nexport class TransactionalInterceptor implements InterceptorMethods {\n constructor(@Inject() private readonly registry: MikroOrmRegistry, @Inject() private readonly context: DBContext) {}\n\n public async intercept(context: InterceptorContext<unknown>, next: InterceptorNext): Promise<unknown> {\n const options = this.extractContextName(context);\n\n const ctx = this.context.getContext();\n\n if (!ctx) {\n return this.runWithinNewCtx(next, options);\n }\n\n if (ctx.has(options.connectionName!)) {\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.connectionName);\n const em = orm.em.fork(true, true);\n\n ctx.set(em.name, em);\n\n const runInTransaction = () => this.executeInTransaction(options.connectionName!, next);\n\n return this.context.run(ctx, () => (options.retryStrategy ? options.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 connectionName: string | undefined;\n let retryStrategy: RetryStrategy | undefined;\n\n if (typeof options === \"string\") {\n connectionName = options;\n } else if (options) {\n connectionName = options.connectionName;\n retryStrategy = options.retryStrategy;\n }\n\n if (!connectionName) {\n connectionName = \"default\";\n }\n\n return {connectionName, retryStrategy};\n }\n\n private async executeInTransaction(connectionName: string, next: InterceptorNext): Promise<unknown> {\n const em = this.context.get(connectionName);\n\n const result = await next();\n\n await em?.flush();\n\n return result;\n }\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export * from "./TransactionalInterceptor";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/interceptors/index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAC","sourcesContent":["export * from \"./TransactionalInterceptor\";\n"]}
@@ -0,0 +1,34 @@
1
+ import { __decorate, __metadata } from "tslib";
2
+ import { Injectable } from "@tsed/di";
3
+ import { AsyncLocalStorage } from "async_hooks";
4
+ let DBContext = class DBContext {
5
+ constructor() {
6
+ this.storage = new AsyncLocalStorage();
7
+ if (AsyncLocalStorage) {
8
+ this.storage = new AsyncLocalStorage();
9
+ }
10
+ else {
11
+ throw new Error(`AsyncLocalStorage is not available for your Node.js version (${process.versions.node}).`);
12
+ }
13
+ }
14
+ run(ctx, callback) {
15
+ return this.storage.run(ctx, callback);
16
+ }
17
+ getContext() {
18
+ return this.storage.getStore();
19
+ }
20
+ get(contextName) {
21
+ const context = this.getContext();
22
+ return context === null || context === void 0 ? void 0 : context.get(contextName);
23
+ }
24
+ has(contextName) {
25
+ const context = this.getContext();
26
+ return !!(context === null || context === void 0 ? void 0 : context.has(contextName));
27
+ }
28
+ };
29
+ DBContext = __decorate([
30
+ Injectable(),
31
+ __metadata("design:paramtypes", [])
32
+ ], DBContext);
33
+ export { DBContext };
34
+ //# sourceMappingURL=DBContext.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DBContext.js","sourceRoot":"","sources":["../../../src/services/DBContext.ts"],"names":[],"mappings":";AAAA,OAAO,EAAC,UAAU,EAAC,MAAM,UAAU,CAAC;AAEpC,OAAO,EAAC,iBAAiB,EAAC,MAAM,aAAa,CAAC;AAG9C,IAAa,SAAS,GAAtB,MAAa,SAAS;IAGpB;QAFiB,YAAO,GAAG,IAAI,iBAAiB,EAA8B,CAAC;QAG7E,IAAI,iBAAiB,EAAE;YACrB,IAAI,CAAC,OAAO,GAAG,IAAI,iBAAiB,EAAE,CAAC;SACxC;aAAM;YACL,MAAM,IAAI,KAAK,CAAC,gEAAgE,OAAO,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,CAAC;SAC5G;IACH,CAAC;IAEM,GAAG,CAAI,GAA+B,EAAE,QAA+B;QAC5E,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACzC,CAAC;IAEM,UAAU;QACf,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;IACjC,CAAC;IAEM,GAAG,CAAC,WAAmB;QAC5B,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QAElC,OAAO,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,GAAG,CAAC,WAAW,CAAC,CAAC;IACnC,CAAC;IAEM,GAAG,CAAC,WAAmB;QAC5B,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QAElC,OAAO,CAAC,CAAC,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,GAAG,CAAC,WAAW,CAAC,CAAA,CAAC;IACrC,CAAC;CACF,CAAA;AA9BY,SAAS;IADrB,UAAU,EAAE;;GACA,SAAS,CA8BrB;SA9BY,SAAS","sourcesContent":["import {Injectable} from \"@tsed/di\";\nimport {EntityManager} from \"@mikro-orm/core\";\nimport {AsyncLocalStorage} from \"async_hooks\";\n\n@Injectable()\nexport class DBContext {\n private readonly storage = new AsyncLocalStorage<Map<string, EntityManager>>();\n\n constructor() {\n if (AsyncLocalStorage) {\n this.storage = new AsyncLocalStorage();\n } else {\n throw new Error(`AsyncLocalStorage is not available for your Node.js version (${process.versions.node}).`);\n }\n }\n\n public run<R>(ctx: Map<string, EntityManager>, callback: (...args: any[]) => R): R {\n return this.storage.run(ctx, callback);\n }\n\n public getContext(): Map<string, EntityManager> | undefined {\n return this.storage.getStore();\n }\n\n public get(contextName: string): EntityManager | undefined {\n const context = this.getContext();\n\n return context?.get(contextName);\n }\n\n public has(contextName: string): boolean {\n const context = this.getContext();\n\n return !!context?.has(contextName);\n }\n}\n"]}
@@ -0,0 +1,21 @@
1
+ import { __decorate, __metadata } from "tslib";
2
+ import { DBContext } from "./DBContext";
3
+ import { MikroORM } from "@mikro-orm/core";
4
+ import { Inject, Injectable } from "@tsed/di";
5
+ let MikroOrmFactory = class MikroOrmFactory {
6
+ create(connectionOptions) {
7
+ return MikroORM.init({
8
+ ...connectionOptions,
9
+ context: (name) => this.dbContext.get(name)
10
+ });
11
+ }
12
+ };
13
+ __decorate([
14
+ Inject(),
15
+ __metadata("design:type", DBContext)
16
+ ], MikroOrmFactory.prototype, "dbContext", void 0);
17
+ MikroOrmFactory = __decorate([
18
+ Injectable()
19
+ ], MikroOrmFactory);
20
+ export { MikroOrmFactory };
21
+ //# sourceMappingURL=MikroOrmFactory.js.map
@@ -0,0 +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,iBAA0B;QACtC,OAAO,QAAQ,CAAC,IAAI,CAAC;YACnB,GAAG,iBAAiB;YACpB,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(connectionOptions: Options): Promise<MikroORM> {\n return MikroORM.init({\n ...connectionOptions,\n context: (name: string) => this.dbContext.get(name)\n });\n }\n}\n"]}
@@ -0,0 +1,48 @@
1
+ import { __decorate, __metadata, __param } from "tslib";
2
+ import { MikroOrmFactory } from "./MikroOrmFactory";
3
+ import { Inject, Injectable, InjectorService } from "@tsed/di";
4
+ import { catchAsyncError, getValue } from "@tsed/core";
5
+ let MikroOrmRegistry = class MikroOrmRegistry {
6
+ constructor(injector, mikroOrmFactory) {
7
+ this.injector = injector;
8
+ this.mikroOrmFactory = mikroOrmFactory;
9
+ this.connections = new Map();
10
+ }
11
+ async createConnection(connectionOptions) {
12
+ const connectionName = getValue(connectionOptions, "contextName", "default");
13
+ if (this.has(connectionName)) {
14
+ return this.get(connectionName);
15
+ }
16
+ this.injector.logger.info(`Create connection with MikroOrm to database: %s`, connectionName);
17
+ this.injector.logger.debug(`options: %j`, connectionOptions);
18
+ const connection = await this.mikroOrmFactory.create(connectionOptions);
19
+ this.connections.set(connectionName, connection);
20
+ this.injector.logger.info(`Connected with MikroOrm to database: %s`, connectionName);
21
+ return connection;
22
+ }
23
+ get(id = "default") {
24
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
25
+ return this.connections.get(id);
26
+ }
27
+ has(id = "default") {
28
+ return this.connections.has(id);
29
+ }
30
+ async closeConnections() {
31
+ const connections = [...this.connections.values()];
32
+ await Promise.all(connections.map((connection) => catchAsyncError(() => this.dispose(connection))));
33
+ this.connections.clear();
34
+ }
35
+ async dispose(connection) {
36
+ if (await connection.isConnected()) {
37
+ await connection.close(false);
38
+ }
39
+ }
40
+ };
41
+ MikroOrmRegistry = __decorate([
42
+ Injectable(),
43
+ __param(0, Inject()),
44
+ __param(1, Inject()),
45
+ __metadata("design:paramtypes", [InjectorService, MikroOrmFactory])
46
+ ], MikroOrmRegistry);
47
+ export { MikroOrmRegistry };
48
+ //# sourceMappingURL=MikroOrmRegistry.js.map
@@ -0,0 +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,EAAE,eAAe,EAAC,MAAM,UAAU,CAAC;AAE7D,OAAO,EAAC,eAAe,EAAE,QAAQ,EAAC,MAAM,YAAY,CAAC;AAGrD,IAAa,gBAAgB,GAA7B,MAAa,gBAAgB;IAG3B,YAAuC,QAAyB,EAA6B,eAAgC;QAAtF,aAAQ,GAAR,QAAQ,CAAiB;QAA6B,oBAAe,GAAf,eAAe,CAAiB;QAF5G,gBAAW,GAAG,IAAI,GAAG,EAAoB,CAAC;IAEqE,CAAC;IAE1H,KAAK,CAAC,gBAAgB,CAA2B,iBAA6B;QACnF,MAAM,cAAc,GAAG,QAAQ,CAAS,iBAAiB,EAAE,aAAa,EAAE,SAAS,CAAC,CAAC;QAErF,IAAI,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE;YAC5B,OAAO,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;SACjC;QAED,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,iDAAiD,EAAE,cAAc,CAAC,CAAC;QAC7F,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,EAAE,iBAAiB,CAAC,CAAC;QAE7D,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;QAExE,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;QAEjD,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,yCAAyC,EAAE,cAAc,CAAC,CAAC;QAErF,OAAO,UAAU,CAAC;IACpB,CAAC;IAEM,GAAG,CAAC,KAAa,SAAS;QAC/B,oEAAoE;QACpE,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAE,CAAC;IACnC,CAAC;IAEM,GAAG,CAAC,KAAa,SAAS;QAC/B,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAClC,CAAC;IAEM,KAAK,CAAC,gBAAgB;QAC3B,MAAM,WAAW,GAAG,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC;QAEnD,MAAM,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,UAAoB,EAAE,EAAE,CAAC,eAAe,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;QAE9G,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;IAC3B,CAAC;IAEO,KAAK,CAAC,OAAO,CAAC,UAAoB;QACxC,IAAI,MAAM,UAAU,CAAC,WAAW,EAAE,EAAE;YAClC,MAAM,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;SAC/B;IACH,CAAC;CACF,CAAA;AA9CY,gBAAgB;IAD5B,UAAU,EAAE;IAIE,WAAA,MAAM,EAAE,CAAA;IAA8C,WAAA,MAAM,EAAE,CAAA;qCAA1B,eAAe,EAA8C,eAAe;GAHlH,gBAAgB,CA8C5B;SA9CY,gBAAgB","sourcesContent":["import {MikroOrmFactory} from \"./MikroOrmFactory\";\nimport {Inject, Injectable, InjectorService} from \"@tsed/di\";\nimport {IDatabaseDriver as DatabaseDriver, MikroORM, Options} from \"@mikro-orm/core\";\nimport {catchAsyncError, getValue} from \"@tsed/core\";\n\n@Injectable()\nexport class MikroOrmRegistry {\n private readonly connections = new Map<string, MikroORM>();\n\n constructor(@Inject() private readonly injector: InjectorService, @Inject() private readonly mikroOrmFactory: MikroOrmFactory) {}\n\n public async createConnection<T extends DatabaseDriver>(connectionOptions: Options<T>): Promise<MikroORM> {\n const connectionName = getValue<string>(connectionOptions, \"contextName\", \"default\");\n\n if (this.has(connectionName)) {\n return this.get(connectionName);\n }\n\n this.injector.logger.info(`Create connection with MikroOrm to database: %s`, connectionName);\n this.injector.logger.debug(`options: %j`, connectionOptions);\n\n const connection = await this.mikroOrmFactory.create(connectionOptions);\n\n this.connections.set(connectionName, connection);\n\n this.injector.logger.info(`Connected with MikroOrm to database: %s`, connectionName);\n\n return connection;\n }\n\n public get(id: string = \"default\"): MikroORM {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return this.connections.get(id)!;\n }\n\n public has(id: string = \"default\"): boolean {\n return this.connections.has(id);\n }\n\n public async closeConnections(): Promise<void> {\n const connections = [...this.connections.values()];\n\n await Promise.all(connections.map((connection: MikroORM) => catchAsyncError(() => this.dispose(connection))));\n\n this.connections.clear();\n }\n\n private async dispose(connection: MikroORM): Promise<void> {\n if (await connection.isConnected()) {\n await connection.close(false);\n }\n }\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=RetryStrategy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RetryStrategy.js","sourceRoot":"","sources":["../../../src/services/RetryStrategy.ts"],"names":[],"mappings":"","sourcesContent":["export interface RetryStrategy {\n acquire<T extends (...args: unknown[]) => unknown>(task: T): Promise<ReturnType<T>>;\n}\n"]}
@@ -0,0 +1,5 @@
1
+ export * from "./DBContext";
2
+ export * from "./MikroOrmFactory";
3
+ export * from "./MikroOrmRegistry";
4
+ export * from "./RetryStrategy";
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/services/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC","sourcesContent":["export * from \"./DBContext\";\nexport * from \"./MikroOrmFactory\";\nexport * from \"./MikroOrmRegistry\";\nexport * from \"./RetryStrategy\";\n"]}
@@ -0,0 +1,19 @@
1
+ import { OnDestroy, OnInit } from "@tsed/di";
2
+ import { Options } from "@mikro-orm/core";
3
+ declare global {
4
+ namespace TsED {
5
+ interface Configuration {
6
+ /**
7
+ * The the ORM configuration, entity metadata.
8
+ * If you omit the `options` parameter, your CLI config will be used.
9
+ */
10
+ mikroOrm?: Options[];
11
+ }
12
+ }
13
+ }
14
+ export declare class MikroOrmModule implements OnDestroy, OnInit {
15
+ private readonly settings;
16
+ private readonly mikroOrmRegistry;
17
+ $onInit(): Promise<void>;
18
+ $onDestroy(): Promise<void>;
19
+ }
@@ -0,0 +1 @@
1
+ export declare const Connection: (connectionName?: string | undefined) => PropertyDecorator;
@@ -0,0 +1,2 @@
1
+ export * from "./transactional";
2
+ export * from "./connection";
@@ -0,0 +1,2 @@
1
+ import { TransactionOptions } from "../interceptors";
2
+ export declare const Transactional: (connectionOrOptions?: string | TransactionOptions | undefined) => MethodDecorator;
@@ -0,0 +1,5 @@
1
+ import { ExceptionFilterMethods, PlatformContext } from "@tsed/common";
2
+ import { OptimisticLockError } from "@mikro-orm/core";
3
+ export declare class OptimisticLockErrorFilter implements ExceptionFilterMethods<OptimisticLockError> {
4
+ catch(exception: OptimisticLockError, ctx: PlatformContext): void;
5
+ }
@@ -0,0 +1 @@
1
+ export * from "./OptimisticLockErrorFilter";
@@ -0,0 +1,5 @@
1
+ export * from "./decorators";
2
+ export * from "./filters";
3
+ export * from "./interceptors";
4
+ export * from "./services";
5
+ export * from "./MikroOrmModule";
@@ -0,0 +1,16 @@
1
+ import { DBContext, MikroOrmRegistry, RetryStrategy } from "../services";
2
+ import { InterceptorContext, InterceptorMethods, InterceptorNext } from "@tsed/di";
3
+ export interface TransactionOptions {
4
+ connectionName?: string;
5
+ retryStrategy?: RetryStrategy;
6
+ }
7
+ export declare class TransactionalInterceptor implements InterceptorMethods {
8
+ private readonly registry;
9
+ private readonly context;
10
+ constructor(registry: MikroOrmRegistry, context: DBContext);
11
+ intercept(context: InterceptorContext<unknown>, next: InterceptorNext): Promise<unknown>;
12
+ private runWithinNewCtx;
13
+ private runUnderCtx;
14
+ private extractContextName;
15
+ private executeInTransaction;
16
+ }
@@ -0,0 +1 @@
1
+ export * from "./TransactionalInterceptor";
@@ -0,0 +1,9 @@
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
+ getContext(): Map<string, EntityManager> | undefined;
7
+ get(contextName: string): EntityManager | undefined;
8
+ has(contextName: string): boolean;
9
+ }
@@ -0,0 +1,5 @@
1
+ import { MikroORM, Options } from "@mikro-orm/core";
2
+ export declare class MikroOrmFactory {
3
+ private readonly dbContext;
4
+ create(connectionOptions: Options): Promise<MikroORM>;
5
+ }
@@ -0,0 +1,14 @@
1
+ import { MikroOrmFactory } from "./MikroOrmFactory";
2
+ import { InjectorService } from "@tsed/di";
3
+ import { IDatabaseDriver as DatabaseDriver, MikroORM, Options } from "@mikro-orm/core";
4
+ export declare class MikroOrmRegistry {
5
+ private readonly injector;
6
+ private readonly mikroOrmFactory;
7
+ private readonly connections;
8
+ constructor(injector: InjectorService, mikroOrmFactory: MikroOrmFactory);
9
+ createConnection<T extends DatabaseDriver>(connectionOptions: Options<T>): Promise<MikroORM>;
10
+ get(id?: string): MikroORM;
11
+ has(id?: string): boolean;
12
+ closeConnections(): Promise<void>;
13
+ private dispose;
14
+ }
@@ -0,0 +1,3 @@
1
+ export interface RetryStrategy {
2
+ acquire<T extends (...args: unknown[]) => unknown>(task: T): Promise<ReturnType<T>>;
3
+ }
@@ -0,0 +1,4 @@
1
+ export * from "./DBContext";
2
+ export * from "./MikroOrmFactory";
3
+ export * from "./MikroOrmRegistry";
4
+ export * from "./RetryStrategy";
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "@tsed/mikro-orm",
3
+ "version": "6.96.0",
4
+ "description": "MikroORM package for Ts.ED framework",
5
+ "private": false,
6
+ "source": "./src/index.ts",
7
+ "main": "./lib/cjs/index.js",
8
+ "typings": "./lib/types/index.d.ts",
9
+ "exports": {
10
+ "types": "./lib/types/index.d.ts",
11
+ "import": "./lib/esm/index.js",
12
+ "require": "./lib/cjs/index.js",
13
+ "default": "./lib/esm/index.js"
14
+ },
15
+ "scripts": {
16
+ "build": "yarn run build:esm && yarn run build:cjs",
17
+ "build:cjs": "tsc --build tsconfig.compile.json",
18
+ "build:esm": "tsc --build tsconfig.compile.esm.json",
19
+ "test": "cross-env NODE_ENV=test jest"
20
+ },
21
+ "dependencies": {
22
+ "tslib": "2.2.0"
23
+ },
24
+ "devDependencies": {
25
+ "@mikro-orm/core": "^4.5.9",
26
+ "@mikro-orm/mongodb": "^4.5.9",
27
+ "@tsed/common": "6.96.0",
28
+ "@tsed/core": "6.96.0",
29
+ "@tsed/di": "6.96.0",
30
+ "@tsed/json-mapper": "6.96.0",
31
+ "@tsed/schema": "6.96.0",
32
+ "ts-mockito": "^2.6.1"
33
+ },
34
+ "peerDependencies": {
35
+ "@mikro-orm/core": ">=4.5.9",
36
+ "@tsed/common": "^6.96.0",
37
+ "@tsed/core": "^6.96.0",
38
+ "@tsed/di": "^6.96.0",
39
+ "@tsed/json-mapper": "^6.96.0",
40
+ "@tsed/schema": "^6.96.0"
41
+ },
42
+ "repository": "https://github.com/tsedio/tsed",
43
+ "bugs": {
44
+ "url": "https://github.com/tsedio/tsed/issues"
45
+ },
46
+ "homepage": "https://github.com/tsedio/tsed/tree/production/packages/orm/mikro-orm",
47
+ "author": "Romain Lenzotti",
48
+ "license": "MIT"
49
+ }
package/readme.md ADDED
@@ -0,0 +1,237 @@
1
+ <p style="text-align: center" align="center">
2
+ <a href="https://tsed.io" target="_blank"><img src="https://tsed.io/tsed-og.png" width="200" alt="Ts.ED logo"/></a>
3
+ </p>
4
+
5
+ <div align="center">
6
+ <h1>MikroORM</h1>
7
+
8
+ [![Build & Release](https://github.com/tsedio/tsed/workflows/Build%20&%20Release/badge.svg)](https://github.com/tsedio/tsed/actions?query=workflow%3A%22Build+%26+Release%22)
9
+ [![PR Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/tsedio/tsed/blob/master/CONTRIBUTING.md)
10
+ [![Coverage Status](https://coveralls.io/repos/github/tsedio/tsed/badge.svg?branch=production)](https://coveralls.io/github/tsedio/tsed?branch=production)
11
+ [![npm version](https://badge.fury.io/js/%40tsed%2Fcommon.svg)](https://badge.fury.io/js/%40tsed%2Fcommon)
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
+ [![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)
15
+
16
+ </div>
17
+
18
+ <div align="center">
19
+ <a href="https://tsed.io/">Website</a>
20
+ <span>&nbsp;&nbsp;•&nbsp;&nbsp;</span>
21
+ <a href="https://tsed.io/getting-started/">Getting started</a>
22
+ <span>&nbsp;&nbsp;•&nbsp;&nbsp;</span>
23
+ <a href="https://api.tsed.io/rest/slack/tsedio/tsed">Slack</a>
24
+ <span>&nbsp;&nbsp;•&nbsp;&nbsp;</span>
25
+ <a href="https://twitter.com/TsED_io">Twitter</a>
26
+ </div>
27
+
28
+ <hr />
29
+
30
+ A package of Ts.ED framework. See website: https://tsed.io/tutorials/mikro-orm
31
+
32
+ ## Feature
33
+
34
+ Currently, `@tsed/mikro-orm` allows you:
35
+
36
+ - Configure one or more MikroOrm connections via the `@ServerSettings` configuration. All databases will be initialized
37
+ when the server starts during the server's `OnInit` phase.
38
+ - Use the Entity MikroOrm as Model for Controllers, AJV Validation and Swagger.
39
+
40
+ ## Installation
41
+
42
+ To begin, install the MikroOrm module for TS.ED:
43
+
44
+ ```bash
45
+ npm install --save @tsed/mikro-orm
46
+ npm install --save @mikro-orm/core
47
+ ```
48
+
49
+ Then import `@tsed/mikro-orm` in your Server:
50
+
51
+ ```typescript
52
+ import {Configuration} from "@tsed/common";
53
+ import {MikroOrmModule} from "@tsed/mikro-orm";
54
+
55
+ @Configuration({
56
+ imports: [MikroOrmModule],
57
+ mikroOrm: [
58
+ {
59
+ contextName: 'default',
60
+ type: 'postgres',
61
+ ...,
62
+
63
+ entities: [
64
+ `${__dirname}/entity/*{.ts,.js}`
65
+ ]
66
+ },
67
+ {
68
+ contextName: 'mongo',
69
+ type: 'mongo',
70
+ ...
71
+ }
72
+ ]
73
+ })
74
+ export class Server {
75
+
76
+ }
77
+ ```
78
+
79
+ For more information about MikroOrm look his documentation [here](https://mikro-orm.io/docs);
80
+
81
+ ## Obtain a connection
82
+
83
+ `Connection` decorator lets you retrieve an instance of MikroOrm Connection.
84
+
85
+ ```typescript
86
+ import {Injectable, AfterRoutesInit} from "@tsed/common";
87
+ import {Connection} from "@tsed/mikro-orm";
88
+ import {MikroORM} from "@mikro-orm/core";
89
+
90
+ @Injectable()
91
+ export class UsersService {
92
+ @Connection()
93
+ private readonly connection!: MikroORM;
94
+
95
+ async create(user: User): Promise<User> {
96
+
97
+ // do something
98
+ // ...
99
+ // Then save
100
+ await this.connection.em.persistAndFlush(user);
101
+ console.log("Saved a new user with id: " + user.id);
102
+
103
+ return user;
104
+ }
105
+
106
+ async find(): Promise<User[]> {
107
+ const users = await this.connection.em.find(User, {});
108
+ console.log("Loaded users: ", users);
109
+
110
+ return users;
111
+ }
112
+ }
113
+ ```
114
+
115
+ ## Use Entity with Controller
116
+
117
+ To begin, we need to define an Entity MikroOrm like this and use Ts.ED Decorator to define the JSON Schema.
118
+
119
+ ```typescript
120
+ import {Property, MaxLength, Required} from "@tsed/common";
121
+ import {Entity, Property, PrimaryKey, Property as Column} from "@mikro-orm/core";
122
+
123
+ @Entity()
124
+ export class User {
125
+
126
+ @PrimaryKey()
127
+ @Property()
128
+ id: number;
129
+
130
+ @Column()
131
+ @MaxLength(100)
132
+ @Required()
133
+ firstName: string;
134
+
135
+ @Column()
136
+ @MaxLength(100)
137
+ @Required()
138
+ lastName: string;
139
+
140
+ @Column()
141
+ @Mininum(0)
142
+ @Maximum(100)
143
+ age: number;
144
+ }
145
+ ```
146
+
147
+ Now, the model is correctly defined and can be used with a [Controller](https://tsed.io/docs/controllers.html)
148
+ , [AJV validation](tutorials/ajv.md),
149
+ [Swagger](tutorials/swagger.md) and [MikroOrm](https://mikro-orm.io/docs/defining-entities).
150
+
151
+ We can use this model with a Controller like that:
152
+
153
+ ```typescript
154
+ import {Controller, Post, BodyParams, Inject, Post, Get} from "@tsed/common";
155
+
156
+ @Controller("/users")
157
+ export class UsersCtrl {
158
+ @Inject()
159
+ private usersService: UsersService;
160
+
161
+ @Post("/")
162
+ create(@BodyParams() user: User): Promise<User> {
163
+ return this.usersService.create(user);
164
+ }
165
+
166
+ @Get("/")
167
+ getList(): Promise<User[]> {
168
+ return this.usersService.find();
169
+ }
170
+ }
171
+ ```
172
+
173
+ ## Transactions and Request context
174
+
175
+ As mentioned in the [docs](https://mikro-orm.io/docs/identity-map), we need to isolate a state for each request. That is
176
+ handled automatically thanks to the `AsyncLocalStorage` registered via interceptor.
177
+
178
+ We can use the `@Transactional()` decorator, which will register a new request context for your method and execute it
179
+ inside the context.
180
+
181
+ ```typescript
182
+ import {Controller, Post, BodyParams, Inject, Get} from "@tsed/common";
183
+ import {Transactional} from "@tsed/mikro-orm";
184
+
185
+ @Controller("/users")
186
+ export class UsersCtrl {
187
+ @Inject()
188
+ private usersService: UsersService;
189
+
190
+ @Post("/")
191
+ @Transactional()
192
+ create(@BodyParams() user: User): Promise<User> {
193
+ return this.usersService.create(user);
194
+ }
195
+
196
+ @Get("/")
197
+ getList(): Promise<User[]> {
198
+ return this.usersService.find();
199
+ }
200
+ }
201
+ ```
202
+
203
+ ## Contributors
204
+
205
+ Please read [contributing guidelines here](https://tsed.io/CONTRIBUTING.html)
206
+
207
+ <a href="https://github.com/tsedio/ts-express-decorators/graphs/contributors"><img src="https://opencollective.com/tsed/contributors.svg?width=890" /></a>
208
+
209
+ ## Backers
210
+
211
+ Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/tsed#backer)]
212
+
213
+ <a href="https://opencollective.com/tsed#backers" target="_blank"><img src="https://opencollective.com/tsed/backers.svg?width=890"></a>
214
+
215
+ ## Sponsors
216
+
217
+ Support this project by becoming a sponsor. Your logo will show up here with a link to your
218
+ website. [[Become a sponsor](https://opencollective.com/tsed#sponsor)]
219
+
220
+ ## License
221
+
222
+ The MIT License (MIT)
223
+
224
+ Copyright (c) 2016 - 2018 Romain Lenzotti
225
+
226
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
227
+ documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
228
+ rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
229
+ persons to whom the Software is furnished to do so, subject to the following conditions:
230
+
231
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
232
+ Software.
233
+
234
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
235
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
236
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
237
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.