@opra/nestjs 0.0.5

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 (52) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +2 -0
  3. package/cjs/constants.js +7 -0
  4. package/cjs/decorators/context.decorator.js +30 -0
  5. package/cjs/enums/handler-paramtype.enum.js +12 -0
  6. package/cjs/factories/params.factory.js +29 -0
  7. package/cjs/factories/service.factory.js +164 -0
  8. package/cjs/index.js +9 -0
  9. package/cjs/interfaces/opra-execution-context.js +10 -0
  10. package/cjs/interfaces/opra-module-options.interface.js +2 -0
  11. package/cjs/opra-core.module.js +149 -0
  12. package/cjs/opra.module.js +25 -0
  13. package/cjs/package.json +3 -0
  14. package/cjs/services/nest-explorer.js +35 -0
  15. package/cjs/services/service-loader.js +88 -0
  16. package/cjs/types.js +2 -0
  17. package/cjs/utils/class.utils.js +25 -0
  18. package/cjs/utils/function.utils.js +23 -0
  19. package/cjs/utils/param.utils.js +22 -0
  20. package/esm/constants.d.ts +4 -0
  21. package/esm/constants.js +4 -0
  22. package/esm/decorators/context.decorator.d.ts +25 -0
  23. package/esm/decorators/context.decorator.js +27 -0
  24. package/esm/enums/handler-paramtype.enum.d.ts +8 -0
  25. package/esm/enums/handler-paramtype.enum.js +9 -0
  26. package/esm/factories/params.factory.d.ts +4 -0
  27. package/esm/factories/params.factory.js +25 -0
  28. package/esm/factories/service.factory.d.ts +15 -0
  29. package/esm/factories/service.factory.js +161 -0
  30. package/esm/index.d.ts +5 -0
  31. package/esm/index.js +6 -0
  32. package/esm/interfaces/opra-execution-context.d.ts +6 -0
  33. package/esm/interfaces/opra-execution-context.js +7 -0
  34. package/esm/interfaces/opra-module-options.interface.d.ts +49 -0
  35. package/esm/interfaces/opra-module-options.interface.js +1 -0
  36. package/esm/opra-core.module.d.ts +18 -0
  37. package/esm/opra-core.module.js +146 -0
  38. package/esm/opra.module.d.ts +6 -0
  39. package/esm/opra.module.js +22 -0
  40. package/esm/services/nest-explorer.d.ts +6 -0
  41. package/esm/services/nest-explorer.js +31 -0
  42. package/esm/services/service-loader.d.ts +18 -0
  43. package/esm/services/service-loader.js +84 -0
  44. package/esm/types.d.ts +2 -0
  45. package/esm/types.js +1 -0
  46. package/esm/utils/class.utils.d.ts +4 -0
  47. package/esm/utils/class.utils.js +19 -0
  48. package/esm/utils/function.utils.d.ts +1 -0
  49. package/esm/utils/function.utils.js +19 -0
  50. package/esm/utils/param.utils.d.ts +8 -0
  51. package/esm/utils/param.utils.js +18 -0
  52. package/package.json +73 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022 Panates
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,2 @@
1
+ # OPRA
2
+ Open Protocol for Restful Api
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PARAM_ARGS_METADATA = exports.OPRA_INITIALIZER = exports.OPRA_MODULE_ID = exports.OPRA_MODULE_OPTIONS = void 0;
4
+ exports.OPRA_MODULE_OPTIONS = 'opra:module_options';
5
+ exports.OPRA_MODULE_ID = 'opra:module_id';
6
+ exports.OPRA_INITIALIZER = 'opra_initializer';
7
+ exports.PARAM_ARGS_METADATA = '__routeArguments__';
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Query = exports.Service = exports.Response = exports.Request = exports.Context = void 0;
4
+ const handler_paramtype_enum_js_1 = require("../enums/handler-paramtype.enum.js");
5
+ const param_utils_js_1 = require("../utils/param.utils.js");
6
+ /**
7
+ * Handler method parameter decorator. Populates the decorated
8
+ * parameter with the value of `ExecutionContext`.
9
+ */
10
+ exports.Context = (0, param_utils_js_1.createOpraParamDecorator)(handler_paramtype_enum_js_1.HandlerParamType.CONTEXT);
11
+ /**
12
+ * Handler method parameter decorator. Populates the decorated
13
+ * parameter with the value of `ExecutionRequest`.
14
+ */
15
+ exports.Request = (0, param_utils_js_1.createOpraParamDecorator)(handler_paramtype_enum_js_1.HandlerParamType.REQUEST);
16
+ /**
17
+ * Handler method parameter decorator. Populates the decorated
18
+ * parameter with the value of `ExecutionResponse`.
19
+ */
20
+ exports.Response = (0, param_utils_js_1.createOpraParamDecorator)(handler_paramtype_enum_js_1.HandlerParamType.RESPONSE);
21
+ /**
22
+ * Handler method parameter decorator. Populates the decorated
23
+ * parameter with the value of `OpraService`.
24
+ */
25
+ exports.Service = (0, param_utils_js_1.createOpraParamDecorator)(handler_paramtype_enum_js_1.HandlerParamType.SERVICE);
26
+ /**
27
+ * Handler method parameter decorator. Populates the decorated
28
+ * parameter with the value of `OpraService`.
29
+ */
30
+ exports.Query = (0, param_utils_js_1.createOpraParamDecorator)(handler_paramtype_enum_js_1.HandlerParamType.QUERY);
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HandlerParamType = void 0;
4
+ var HandlerParamType;
5
+ (function (HandlerParamType) {
6
+ HandlerParamType[HandlerParamType["CONTEXT"] = 0] = "CONTEXT";
7
+ HandlerParamType[HandlerParamType["SERVICE"] = 1] = "SERVICE";
8
+ HandlerParamType[HandlerParamType["REQUEST"] = 2] = "REQUEST";
9
+ HandlerParamType[HandlerParamType["QUERY"] = 3] = "QUERY";
10
+ HandlerParamType[HandlerParamType["RESPONSE"] = 4] = "RESPONSE";
11
+ HandlerParamType[HandlerParamType["USER_CONTEXT"] = 5] = "USER_CONTEXT";
12
+ })(HandlerParamType = exports.HandlerParamType || (exports.HandlerParamType = {}));
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OpraParamsFactory = void 0;
4
+ const handler_paramtype_enum_js_1 = require("../enums/handler-paramtype.enum.js");
5
+ class OpraParamsFactory {
6
+ exchangeKeyForValue(type, data, args) {
7
+ if (!args) {
8
+ return null;
9
+ }
10
+ args = Array.isArray(args) ? args : [];
11
+ switch (type) {
12
+ case handler_paramtype_enum_js_1.HandlerParamType.CONTEXT:
13
+ return args[3];
14
+ case handler_paramtype_enum_js_1.HandlerParamType.SERVICE:
15
+ return args[3].service;
16
+ case handler_paramtype_enum_js_1.HandlerParamType.REQUEST:
17
+ return args[3].request;
18
+ case handler_paramtype_enum_js_1.HandlerParamType.QUERY:
19
+ return args[3].request.query;
20
+ case handler_paramtype_enum_js_1.HandlerParamType.RESPONSE:
21
+ return args[3].response;
22
+ case handler_paramtype_enum_js_1.HandlerParamType.USER_CONTEXT:
23
+ return args[3].userContext;
24
+ default:
25
+ return null;
26
+ }
27
+ }
28
+ }
29
+ exports.OpraParamsFactory = OpraParamsFactory;
@@ -0,0 +1,164 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ServiceFactory = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const lodash_1 = tslib_1.__importDefault(require("lodash"));
6
+ const common_1 = require("@nestjs/common");
7
+ const core_1 = require("@nestjs/core");
8
+ const external_context_creator_1 = require("@nestjs/core/helpers/external-context-creator");
9
+ const injector_1 = require("@nestjs/core/injector/injector");
10
+ const internal_core_module_1 = require("@nestjs/core/injector/internal-core-module");
11
+ const request_constants_1 = require("@nestjs/core/router/request/request-constants");
12
+ const core_2 = require("@opra/core");
13
+ const schema_1 = require("@opra/schema");
14
+ const constants_js_1 = require("../constants.js");
15
+ const handler_paramtype_enum_js_1 = require("../enums/handler-paramtype.enum.js");
16
+ const nest_explorer_js_1 = require("../services/nest-explorer.js");
17
+ const function_utils_js_1 = require("../utils/function.utils.js");
18
+ const params_factory_js_1 = require("./params.factory.js");
19
+ const entityHandlers = ['search', 'create', 'read', 'update', 'updateMany', 'delete', 'deleteMany'];
20
+ const noOpFunction = () => void 0;
21
+ let ServiceFactory = class ServiceFactory {
22
+ paramsFactory = new params_factory_js_1.OpraParamsFactory();
23
+ injector = new injector_1.Injector();
24
+ modulesContainer;
25
+ externalContextCreator;
26
+ explorerService;
27
+ async generateService(rootModule, moduleOptions, contextType) {
28
+ const info = { title: '', version: '', ...moduleOptions.info };
29
+ info.title = info.title || 'Untitled service';
30
+ info.version = info.version || '1';
31
+ const serviceArgs = {
32
+ info,
33
+ types: [],
34
+ resources: [],
35
+ };
36
+ const wrappers = this.explorerService.exploreResourceWrappers(rootModule);
37
+ for (const wrapper of wrappers) {
38
+ const instance = wrapper.instance;
39
+ const resourceDef = Reflect.getMetadata(core_2.RESOURCE_METADATA, instance.constructor);
40
+ /* istanbul ignore next */
41
+ if (!resourceDef)
42
+ continue;
43
+ serviceArgs.resources.push(instance);
44
+ /* Wrap resolver functions */
45
+ const prototype = Object.getPrototypeOf(instance);
46
+ const isRequestScoped = !wrapper.isDependencyTreeStatic();
47
+ if (schema_1.OpraSchema.isEntityResource(resourceDef)) {
48
+ for (const x of entityHandlers) {
49
+ const fn = instance[x];
50
+ if (typeof fn === 'function') {
51
+ const methodName = fn.name || x;
52
+ const callback = this._createContextCallback(instance, prototype, wrapper, rootModule, methodName, isRequestScoped, undefined, contextType);
53
+ const newFn = instance[x] = (ctx) => {
54
+ switch (ctx.type) {
55
+ case 'http':
56
+ const http = ctx.switchToHttp();
57
+ return callback(http.getRequest().getInstance(), http.getResponse().getInstance(), noOpFunction, ctx);
58
+ default:
59
+ throw new Error(`"${ctx.type}" context type is not implemented yet`);
60
+ }
61
+ };
62
+ if (methodName && newFn.name !== methodName)
63
+ Object.defineProperty(newFn, 'name', {
64
+ configurable: false,
65
+ writable: false,
66
+ enumerable: true,
67
+ value: methodName
68
+ });
69
+ }
70
+ }
71
+ }
72
+ }
73
+ return await core_2.OpraService.create(serviceArgs);
74
+ }
75
+ _createContextCallback(instance, prototype, wrapper, moduleRef, methodName, isRequestScoped, transform = lodash_1.default.identity, contextType) {
76
+ const paramsFactory = this.paramsFactory;
77
+ if (isRequestScoped) {
78
+ return async (...args) => {
79
+ const opraContext = paramsFactory.exchangeKeyForValue(handler_paramtype_enum_js_1.HandlerParamType.CONTEXT, undefined, args);
80
+ const contextId = this.getContextId(opraContext);
81
+ this.registerContextProvider(opraContext, contextId);
82
+ const contextInstance = await this.injector.loadPerContext(instance, moduleRef, moduleRef.providers, contextId);
83
+ const callback = this.externalContextCreator.create(contextInstance, transform(contextInstance[methodName]), methodName, constants_js_1.PARAM_ARGS_METADATA, paramsFactory, contextId, wrapper.id, undefined, // contextOptions
84
+ opraContext.type);
85
+ return callback(...args);
86
+ };
87
+ }
88
+ return this.externalContextCreator.create(instance, prototype[methodName], methodName, constants_js_1.PARAM_ARGS_METADATA, paramsFactory, undefined, undefined, undefined, // contextOptions
89
+ contextType);
90
+ }
91
+ // noinspection JSMethodCanBeStatic
92
+ getContextId(gqlContext) {
93
+ const numberOfArguments = (0, function_utils_js_1.getNumberOfArguments)(core_1.ContextIdFactory.getByRequest);
94
+ if (numberOfArguments === 2) {
95
+ // @ts-ignore
96
+ const contextId = core_1.ContextIdFactory.getByRequest(gqlContext, ['req']);
97
+ if (!gqlContext[request_constants_1.REQUEST_CONTEXT_ID]) {
98
+ Object.defineProperty(gqlContext, request_constants_1.REQUEST_CONTEXT_ID, {
99
+ value: contextId,
100
+ enumerable: false,
101
+ configurable: false,
102
+ writable: false,
103
+ });
104
+ }
105
+ return contextId;
106
+ }
107
+ else {
108
+ // TODO remove in the next version (backward-compatibility layer)
109
+ // Left for backward compatibility purposes
110
+ let contextId;
111
+ if (gqlContext && gqlContext[request_constants_1.REQUEST_CONTEXT_ID]) {
112
+ contextId = gqlContext[request_constants_1.REQUEST_CONTEXT_ID];
113
+ }
114
+ else if (gqlContext &&
115
+ gqlContext.req &&
116
+ gqlContext.req[request_constants_1.REQUEST_CONTEXT_ID]) {
117
+ contextId = gqlContext.req[request_constants_1.REQUEST_CONTEXT_ID];
118
+ }
119
+ else {
120
+ contextId = (0, core_1.createContextId)();
121
+ Object.defineProperty(gqlContext, request_constants_1.REQUEST_CONTEXT_ID, {
122
+ value: contextId,
123
+ enumerable: false,
124
+ configurable: false,
125
+ writable: false,
126
+ });
127
+ }
128
+ return contextId;
129
+ }
130
+ }
131
+ registerContextProvider(request, contextId) {
132
+ const coreModuleArray = [...this.modulesContainer.entries()]
133
+ .filter(
134
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
135
+ ([key, { metatype }]) => metatype && metatype.name === internal_core_module_1.InternalCoreModule.name)
136
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
137
+ .map(([key, value]) => value);
138
+ const coreModuleRef = lodash_1.default.head(coreModuleArray);
139
+ if (!coreModuleRef) {
140
+ return;
141
+ }
142
+ const wrapper = coreModuleRef.getProviderByKey(core_1.REQUEST);
143
+ wrapper.setInstanceByContextId(contextId, {
144
+ instance: request,
145
+ isResolved: true,
146
+ });
147
+ }
148
+ };
149
+ tslib_1.__decorate([
150
+ (0, common_1.Inject)(),
151
+ tslib_1.__metadata("design:type", core_1.ModulesContainer)
152
+ ], ServiceFactory.prototype, "modulesContainer", void 0);
153
+ tslib_1.__decorate([
154
+ (0, common_1.Inject)(),
155
+ tslib_1.__metadata("design:type", external_context_creator_1.ExternalContextCreator)
156
+ ], ServiceFactory.prototype, "externalContextCreator", void 0);
157
+ tslib_1.__decorate([
158
+ (0, common_1.Inject)(),
159
+ tslib_1.__metadata("design:type", nest_explorer_js_1.NestExplorer)
160
+ ], ServiceFactory.prototype, "explorerService", void 0);
161
+ ServiceFactory = tslib_1.__decorate([
162
+ (0, common_1.Injectable)()
163
+ ], ServiceFactory);
164
+ exports.ServiceFactory = ServiceFactory;
package/cjs/index.js ADDED
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ require("reflect-metadata");
5
+ tslib_1.__exportStar(require("./opra.module.js"), exports);
6
+ tslib_1.__exportStar(require("./decorators/context.decorator.js"), exports);
7
+ tslib_1.__exportStar(require("./interfaces/opra-execution-context.js"), exports);
8
+ tslib_1.__exportStar(require("./interfaces/opra-module-options.interface.js"), exports);
9
+ // export * as Api from './decorators/api.ns.js';
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OpraExecutionContext = void 0;
4
+ var OpraExecutionContext;
5
+ (function (OpraExecutionContext) {
6
+ function from(source) {
7
+ return source.getArgByIndex(4);
8
+ }
9
+ OpraExecutionContext.from = from;
10
+ })(OpraExecutionContext = exports.OpraExecutionContext || (exports.OpraExecutionContext = {}));
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,149 @@
1
+ "use strict";
2
+ var OpraCoreModule_1;
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.OpraCoreModule = void 0;
5
+ const tslib_1 = require("tslib");
6
+ const crypto = tslib_1.__importStar(require("crypto"));
7
+ const common_1 = require("@nestjs/common");
8
+ const core_1 = require("@nestjs/core");
9
+ const metadata_scanner_1 = require("@nestjs/core/metadata-scanner");
10
+ const i18n_1 = require("@opra/i18n");
11
+ const constants_js_1 = require("./constants.js");
12
+ const service_factory_js_1 = require("./factories/service.factory.js");
13
+ const nest_explorer_js_1 = require("./services/nest-explorer.js");
14
+ const service_loader_js_1 = require("./services/service-loader.js");
15
+ let OpraCoreModule = OpraCoreModule_1 = class OpraCoreModule {
16
+ httpAdapterHost;
17
+ modulesContainer;
18
+ options;
19
+ opraServiceLoader;
20
+ constructor(httpAdapterHost, modulesContainer, options, opraServiceLoader) {
21
+ this.httpAdapterHost = httpAdapterHost;
22
+ this.modulesContainer = modulesContainer;
23
+ this.options = options;
24
+ this.opraServiceLoader = opraServiceLoader;
25
+ }
26
+ static forRoot(options) {
27
+ return {
28
+ module: OpraCoreModule_1,
29
+ imports: [...(options.imports || [])],
30
+ providers: [
31
+ ...(options.providers || []),
32
+ {
33
+ provide: constants_js_1.OPRA_MODULE_OPTIONS,
34
+ useValue: options,
35
+ },
36
+ {
37
+ provide: constants_js_1.OPRA_INITIALIZER,
38
+ useClass: service_loader_js_1.OpraServiceLoader
39
+ },
40
+ this.createI18nProvider()
41
+ ],
42
+ exports: [...(options.exports || [])]
43
+ };
44
+ }
45
+ static forRootAsync(asyncOptions) {
46
+ return {
47
+ module: OpraCoreModule_1,
48
+ imports: [...(asyncOptions.imports || [])],
49
+ providers: [
50
+ ...(asyncOptions.providers || []),
51
+ {
52
+ provide: constants_js_1.OPRA_MODULE_ID,
53
+ useValue: crypto.randomUUID()
54
+ },
55
+ {
56
+ provide: constants_js_1.OPRA_INITIALIZER,
57
+ useClass: service_loader_js_1.OpraServiceLoader
58
+ },
59
+ ...this.createAsyncProviders(asyncOptions),
60
+ this.createI18nProvider(),
61
+ ]
62
+ };
63
+ }
64
+ static createI18nProvider() {
65
+ return {
66
+ provide: i18n_1.I18n,
67
+ inject: [constants_js_1.OPRA_MODULE_OPTIONS],
68
+ useFactory: async (options) => {
69
+ const opts = options.i18n;
70
+ const initOptions = {
71
+ lng: opts?.lng,
72
+ fallbackLng: opts?.fallbackLng,
73
+ defaultNS: opts?.defaultNS,
74
+ resources: opts?.resources,
75
+ resourceDirs: opts?.resourceDirs
76
+ };
77
+ const instance = i18n_1.I18n.createInstance();
78
+ await instance.init(initOptions);
79
+ return instance;
80
+ }
81
+ };
82
+ }
83
+ static createAsyncProviders(asyncOptions) {
84
+ if (asyncOptions.useExisting || asyncOptions.useFactory)
85
+ return [this.createAsyncOptionsProvider(asyncOptions)];
86
+ if (asyncOptions.useClass)
87
+ return [
88
+ this.createAsyncOptionsProvider(asyncOptions),
89
+ {
90
+ provide: asyncOptions.useClass,
91
+ useClass: asyncOptions.useClass
92
+ }
93
+ ];
94
+ throw new Error('Invalid configuration. Must provide useFactory, useClass or useExisting');
95
+ }
96
+ static createAsyncOptionsProvider(asyncOptions) {
97
+ if (asyncOptions.useFactory) {
98
+ return {
99
+ provide: constants_js_1.OPRA_MODULE_OPTIONS,
100
+ useFactory: asyncOptions.useFactory,
101
+ inject: asyncOptions.inject || []
102
+ };
103
+ }
104
+ const useClass = asyncOptions.useClass || asyncOptions.useExisting;
105
+ if (useClass) {
106
+ return {
107
+ provide: constants_js_1.OPRA_MODULE_OPTIONS,
108
+ useFactory: (optionsFactory) => optionsFactory.createOptions(),
109
+ inject: [useClass]
110
+ };
111
+ }
112
+ throw new Error('Invalid configuration. Must provide useFactory, useClass or useExisting');
113
+ }
114
+ async onModuleInit() {
115
+ const httpAdapter = this.httpAdapterHost?.httpAdapter;
116
+ if (!httpAdapter)
117
+ return;
118
+ const opraModule = (() => {
119
+ for (const m of this.modulesContainer.values()) {
120
+ for (const imp of m.imports.values()) {
121
+ for (const prv of imp.providers.values())
122
+ if (prv.instance === this) {
123
+ return imp;
124
+ }
125
+ }
126
+ }
127
+ })();
128
+ if (opraModule) {
129
+ await this.opraServiceLoader.initialize(opraModule);
130
+ }
131
+ }
132
+ async onModuleDestroy() {
133
+ await this.opraServiceLoader.stop();
134
+ }
135
+ };
136
+ OpraCoreModule = OpraCoreModule_1 = tslib_1.__decorate([
137
+ (0, common_1.Module)({
138
+ providers: [
139
+ service_factory_js_1.ServiceFactory,
140
+ metadata_scanner_1.MetadataScanner,
141
+ nest_explorer_js_1.NestExplorer
142
+ ]
143
+ }),
144
+ tslib_1.__param(2, (0, common_1.Inject)(constants_js_1.OPRA_MODULE_OPTIONS)),
145
+ tslib_1.__param(3, (0, common_1.Inject)(constants_js_1.OPRA_INITIALIZER)),
146
+ tslib_1.__metadata("design:paramtypes", [core_1.HttpAdapterHost,
147
+ core_1.ModulesContainer, Object, service_loader_js_1.OpraServiceLoader])
148
+ ], OpraCoreModule);
149
+ exports.OpraCoreModule = OpraCoreModule;
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ var OpraModule_1;
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.OpraModule = void 0;
5
+ const tslib_1 = require("tslib");
6
+ const common_1 = require("@nestjs/common");
7
+ const opra_core_module_js_1 = require("./opra-core.module.js");
8
+ let OpraModule = OpraModule_1 = class OpraModule {
9
+ static forRoot(options) {
10
+ return {
11
+ module: OpraModule_1,
12
+ imports: [opra_core_module_js_1.OpraCoreModule.forRoot(options)]
13
+ };
14
+ }
15
+ static forRootAsync(asyncOptions) {
16
+ return {
17
+ module: OpraModule_1,
18
+ imports: [opra_core_module_js_1.OpraCoreModule.forRootAsync(asyncOptions)]
19
+ };
20
+ }
21
+ };
22
+ OpraModule = OpraModule_1 = tslib_1.__decorate([
23
+ (0, common_1.Module)({})
24
+ ], OpraModule);
25
+ exports.OpraModule = OpraModule;
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "commonjs"
3
+ }
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NestExplorer = void 0;
4
+ const core_1 = require("@opra/core");
5
+ class NestExplorer {
6
+ exploreProviders(rootModule, predicate) {
7
+ const modules = new Set();
8
+ const wrappers = new Set();
9
+ const scanModules = (m) => {
10
+ if (modules.has(m))
11
+ return;
12
+ modules.add(m);
13
+ for (const mm of m.imports.values()) {
14
+ scanModules(mm);
15
+ }
16
+ for (const wrapper of m.providers.values()) {
17
+ if (!wrappers.has(wrapper) && predicate(wrapper))
18
+ wrappers.add(wrapper);
19
+ if (wrapper.host)
20
+ scanModules(wrapper.host);
21
+ }
22
+ };
23
+ scanModules(rootModule);
24
+ return Array.from(wrappers.values());
25
+ }
26
+ exploreResourceWrappers(rootModule) {
27
+ return this.exploreProviders(rootModule, (wrapper) => {
28
+ return !!(wrapper.instance
29
+ && typeof wrapper.instance === 'object'
30
+ && wrapper.instance.constructor
31
+ && Reflect.hasMetadata(core_1.RESOURCE_METADATA, wrapper.instance.constructor));
32
+ });
33
+ }
34
+ }
35
+ exports.NestExplorer = NestExplorer;
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ var _a;
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.OpraServiceLoader = void 0;
5
+ const tslib_1 = require("tslib");
6
+ const common_1 = require("@nestjs/common");
7
+ const core_1 = require("@nestjs/core");
8
+ const core_2 = require("@opra/core");
9
+ const i18n_1 = require("@opra/i18n");
10
+ const url_1 = require("@opra/url");
11
+ const constants_js_1 = require("../constants.js");
12
+ const service_factory_js_1 = require("../factories/service.factory.js");
13
+ class OpraServiceLoader {
14
+ logger = new common_1.Logger(OpraServiceLoader.name, { timestamp: true });
15
+ adapter;
16
+ httpAdapterHost;
17
+ applicationConfig;
18
+ opraFactory;
19
+ opraModuleOptions;
20
+ i18n;
21
+ async initialize(rootModule) {
22
+ const httpAdapter = this.httpAdapterHost?.httpAdapter;
23
+ const globalPrefix = this.applicationConfig.getGlobalPrefix();
24
+ const platformName = httpAdapter.getType();
25
+ const moduleOptions = this.opraModuleOptions;
26
+ const prefix = '/' + (0, url_1.normalizePath)((0, url_1.joinPath)((moduleOptions.useGlobalPrefix !== false ? globalPrefix : ''), moduleOptions.prefix || ''), true);
27
+ const name = moduleOptions.info?.title || 'untitled service';
28
+ const options = {
29
+ ...moduleOptions,
30
+ prefix
31
+ };
32
+ try {
33
+ const serviceHost = await this.opraFactory.generateService(rootModule, options, 'http');
34
+ if (!Object.keys(serviceHost.resources).length) {
35
+ this.logger.warn(`No resources found (${name})`);
36
+ return;
37
+ }
38
+ // serviceConfiguration.i18n = this.i18n;
39
+ if (platformName === 'express') {
40
+ this.adapter = await this.registerExpress(serviceHost, options);
41
+ // else if (platformName === 'fastify')
42
+ // await this.registerFastify();
43
+ }
44
+ else { // noinspection ExceptionCaughtLocallyJS
45
+ throw new Error(`No support for current HttpAdapter: ${platformName}`);
46
+ }
47
+ this.logger.log(`Mapped {${prefix}} to "${name}" service`);
48
+ }
49
+ catch (e) {
50
+ this.logger.error(e);
51
+ throw e;
52
+ }
53
+ }
54
+ async stop() {
55
+ //
56
+ }
57
+ async registerExpress(service, moduleOptions) {
58
+ const httpAdapter = this.httpAdapterHost.httpAdapter;
59
+ if (!httpAdapter)
60
+ return;
61
+ const app = httpAdapter.getInstance();
62
+ return core_2.OpraExpressAdapter.init(app, service, {
63
+ i18n: this.i18n,
64
+ prefix: moduleOptions.prefix
65
+ });
66
+ }
67
+ }
68
+ tslib_1.__decorate([
69
+ (0, common_1.Inject)(),
70
+ tslib_1.__metadata("design:type", core_1.HttpAdapterHost)
71
+ ], OpraServiceLoader.prototype, "httpAdapterHost", void 0);
72
+ tslib_1.__decorate([
73
+ (0, common_1.Inject)(),
74
+ tslib_1.__metadata("design:type", core_1.ApplicationConfig)
75
+ ], OpraServiceLoader.prototype, "applicationConfig", void 0);
76
+ tslib_1.__decorate([
77
+ (0, common_1.Inject)(),
78
+ tslib_1.__metadata("design:type", service_factory_js_1.ServiceFactory)
79
+ ], OpraServiceLoader.prototype, "opraFactory", void 0);
80
+ tslib_1.__decorate([
81
+ (0, common_1.Inject)(constants_js_1.OPRA_MODULE_OPTIONS),
82
+ tslib_1.__metadata("design:type", Object)
83
+ ], OpraServiceLoader.prototype, "opraModuleOptions", void 0);
84
+ tslib_1.__decorate([
85
+ (0, common_1.Inject)(),
86
+ tslib_1.__metadata("design:type", typeof (_a = typeof i18n_1.I18n !== "undefined" && i18n_1.I18n) === "function" ? _a : Object)
87
+ ], OpraServiceLoader.prototype, "i18n", void 0);
88
+ exports.OpraServiceLoader = OpraServiceLoader;
package/cjs/types.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getClassName = exports.getClassOrUndefined = exports.isConstructor = void 0;
4
+ const shared_utils_1 = require("@nestjs/common/utils/shared.utils");
5
+ function isConstructor(obj) {
6
+ return typeof obj === 'function' &&
7
+ !!(obj.prototype && obj.prototype.constructor);
8
+ }
9
+ exports.isConstructor = isConstructor;
10
+ function getClassOrUndefined(typeOrFunc) {
11
+ return isConstructor(typeOrFunc)
12
+ ? typeOrFunc
13
+ : (0, shared_utils_1.isFunction)(typeOrFunc)
14
+ ? typeOrFunc()
15
+ : undefined;
16
+ }
17
+ exports.getClassOrUndefined = getClassOrUndefined;
18
+ function getClassName(nameOrType) {
19
+ if ((0, shared_utils_1.isString)(nameOrType)) {
20
+ return nameOrType;
21
+ }
22
+ const classOrUndefined = getClassOrUndefined(nameOrType);
23
+ return classOrUndefined && classOrUndefined.name;
24
+ }
25
+ exports.getClassName = getClassName;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getNumberOfArguments = void 0;
4
+ const fast_tokenizer_1 = require("fast-tokenizer");
5
+ const anythingEnclosedInParenthesesRegex = /\((.+)\)/;
6
+ function getNumberOfArguments(fn) {
7
+ const functionAsString = fn.toString();
8
+ const parametersEnclosedInParentheses = functionAsString.match(anythingEnclosedInParenthesesRegex);
9
+ if (parametersEnclosedInParentheses) {
10
+ const matchString = parametersEnclosedInParentheses[1];
11
+ const argumentsArray = (0, fast_tokenizer_1.splitString)(matchString, {
12
+ brackets: {
13
+ '(': ')',
14
+ '{': '}',
15
+ '[': ']',
16
+ '/*': '*/'
17
+ }, delimiters: ','
18
+ });
19
+ return argumentsArray.length;
20
+ }
21
+ return 0;
22
+ }
23
+ exports.getNumberOfArguments = getNumberOfArguments;