@zerooneit/expressive-tea 1.3.0-beta.5 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gitattributes +4 -0
- package/.swcrc +61 -0
- package/README.md +564 -174
- package/classes/Boot.d.ts +94 -3
- package/classes/Boot.js +171 -51
- package/classes/Engine.d.ts +59 -10
- package/classes/Engine.js +72 -11
- package/classes/EngineRegistry.d.ts +154 -0
- package/classes/EngineRegistry.js +247 -0
- package/classes/LoadBalancer.js +2 -5
- package/classes/ProxyRoute.d.ts +3 -3
- package/classes/ProxyRoute.js +5 -5
- package/classes/Settings.d.ts +31 -2
- package/classes/Settings.js +64 -11
- package/decorators/annotations.d.ts +1 -1
- package/decorators/annotations.js +17 -17
- package/decorators/env.d.ts +145 -0
- package/decorators/env.js +177 -0
- package/decorators/health.d.ts +115 -0
- package/decorators/health.js +124 -0
- package/decorators/module.d.ts +15 -15
- package/decorators/module.js +14 -23
- package/decorators/proxy.d.ts +26 -11
- package/decorators/proxy.js +35 -45
- package/decorators/router.d.ts +17 -16
- package/decorators/router.js +32 -52
- package/decorators/server.d.ts +8 -8
- package/decorators/server.js +48 -50
- package/engines/health/index.d.ts +120 -0
- package/engines/health/index.js +179 -0
- package/engines/http/index.d.ts +6 -7
- package/engines/http/index.js +22 -17
- package/engines/index.d.ts +32 -0
- package/engines/index.js +112 -0
- package/engines/socketio/index.d.ts +2 -1
- package/engines/socketio/index.js +16 -6
- package/engines/teacup/index.d.ts +13 -0
- package/engines/teacup/index.js +61 -11
- package/engines/teapot/index.d.ts +15 -2
- package/engines/teapot/index.js +61 -13
- package/engines/websocket/index.d.ts +4 -1
- package/engines/websocket/index.js +10 -2
- package/eslint.config.mjs +138 -0
- package/exceptions/RequestExceptions.d.ts +3 -3
- package/helpers/boot-helper.d.ts +6 -6
- package/helpers/boot-helper.js +30 -24
- package/helpers/decorators.js +7 -6
- package/helpers/promise-helper.d.ts +1 -1
- package/helpers/promise-helper.js +1 -2
- package/helpers/server.d.ts +32 -6
- package/helpers/server.js +101 -61
- package/helpers/teapot-helper.d.ts +5 -8
- package/helpers/teapot-helper.js +39 -11
- package/helpers/websocket-helper.d.ts +3 -5
- package/helpers/websocket-helper.js +3 -3
- package/interfaces/index.d.ts +1 -1
- package/inversify.config.d.ts +4 -4
- package/inversify.config.js +1 -1
- package/libs/utilities.d.ts +21910 -0
- package/libs/utilities.js +420 -0
- package/mixins/module.d.ts +45 -0
- package/mixins/module.js +71 -0
- package/mixins/proxy.d.ts +46 -0
- package/mixins/proxy.js +86 -0
- package/mixins/route.d.ts +48 -0
- package/mixins/route.js +96 -0
- package/package.json +91 -69
- package/services/DependencyInjection.d.ts +95 -7
- package/services/DependencyInjection.js +123 -5
- package/services/WebsocketService.d.ts +4 -6
- package/services/WebsocketService.js +5 -3
- package/types/core.d.ts +14 -0
- package/types/core.js +2 -0
- package/types/injection-types.d.ts +6 -0
- package/types/injection-types.js +10 -0
- package/types/inversify.d.ts +5 -0
- package/types/inversify.js +3 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { type Constructor } from '../types/core';
|
|
2
|
+
import type { ExpressiveTeaHandlerOptions } from '@expressive-tea/commons';
|
|
3
|
+
import { Router } from 'express';
|
|
4
|
+
import type { ExpressMiddlewareHandler } from '@expressive-tea/commons';
|
|
5
|
+
/**
|
|
6
|
+
* Type definition for a routerized class
|
|
7
|
+
* Represents a class that has been enhanced with Expressive Tea route capabilities
|
|
8
|
+
* @template TBase - The base constructor type being extended
|
|
9
|
+
* @since 2.0.0
|
|
10
|
+
*/
|
|
11
|
+
export type RouterizedClass<TBase extends Constructor> = TBase & (new (...args: any[]) => {
|
|
12
|
+
/** Express router for this route controller */
|
|
13
|
+
readonly router: Router;
|
|
14
|
+
/** Mountpoint path for this controller */
|
|
15
|
+
readonly mountpoint: string;
|
|
16
|
+
/** Mount this controller's router on a parent router */
|
|
17
|
+
__mount(parent: Router): any;
|
|
18
|
+
/** Register a route handler with proper middleware and argument injection */
|
|
19
|
+
__registerHandler(options: ExpressiveTeaHandlerOptions): ExpressMiddlewareHandler;
|
|
20
|
+
});
|
|
21
|
+
/**
|
|
22
|
+
* Routerize mixin - Adds Expressive Tea route capabilities to a controller class
|
|
23
|
+
*
|
|
24
|
+
* Transforms a regular class into an Expressive Tea route controller with:
|
|
25
|
+
* - Express router management
|
|
26
|
+
* - Route handler registration
|
|
27
|
+
* - Middleware support
|
|
28
|
+
* - Automatic argument injection from decorators
|
|
29
|
+
* - Annotation processing
|
|
30
|
+
*
|
|
31
|
+
* @template TBase - The base constructor type to extend
|
|
32
|
+
* @param {TBase} Route - The base controller class to extend
|
|
33
|
+
* @param {string} mountpoint - The path where this controller should be mounted
|
|
34
|
+
* @returns {RouterizedClass<TBase>} The enhanced class with route capabilities
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```typescript
|
|
38
|
+
* @Route('/users')
|
|
39
|
+
* class UserController {
|
|
40
|
+
* @Get('/')
|
|
41
|
+
* getUsers() {
|
|
42
|
+
* return ['user1', 'user2'];
|
|
43
|
+
* }
|
|
44
|
+
* }
|
|
45
|
+
* ```
|
|
46
|
+
* @since 2.0.0
|
|
47
|
+
*/
|
|
48
|
+
export declare function Routerize<TBase extends Constructor>(Route: TBase, mountpoint: string): RouterizedClass<TBase>;
|
package/mixins/route.js
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call */
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.Routerize = Routerize;
|
|
5
|
+
const tslib_1 = require("tslib");
|
|
6
|
+
const express_1 = require("express");
|
|
7
|
+
const commons_1 = require("@expressive-tea/commons");
|
|
8
|
+
const commons_2 = require("@expressive-tea/commons");
|
|
9
|
+
const server_1 = require("../helpers/server");
|
|
10
|
+
const inversify_1 = require("inversify");
|
|
11
|
+
const DependencyInjection_1 = require("../services/DependencyInjection");
|
|
12
|
+
/**
|
|
13
|
+
* Routerize mixin - Adds Expressive Tea route capabilities to a controller class
|
|
14
|
+
*
|
|
15
|
+
* Transforms a regular class into an Expressive Tea route controller with:
|
|
16
|
+
* - Express router management
|
|
17
|
+
* - Route handler registration
|
|
18
|
+
* - Middleware support
|
|
19
|
+
* - Automatic argument injection from decorators
|
|
20
|
+
* - Annotation processing
|
|
21
|
+
*
|
|
22
|
+
* @template TBase - The base constructor type to extend
|
|
23
|
+
* @param {TBase} Route - The base controller class to extend
|
|
24
|
+
* @param {string} mountpoint - The path where this controller should be mounted
|
|
25
|
+
* @returns {RouterizedClass<TBase>} The enhanced class with route capabilities
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```typescript
|
|
29
|
+
* @Route('/users')
|
|
30
|
+
* class UserController {
|
|
31
|
+
* @Get('/')
|
|
32
|
+
* getUsers() {
|
|
33
|
+
* return ['user1', 'user2'];
|
|
34
|
+
* }
|
|
35
|
+
* }
|
|
36
|
+
* ```
|
|
37
|
+
* @since 2.0.0
|
|
38
|
+
*/
|
|
39
|
+
function Routerize(Route, mountpoint) {
|
|
40
|
+
let ExpressiveTeaRoute = class ExpressiveTeaRoute extends Route {
|
|
41
|
+
constructor(...args) {
|
|
42
|
+
var _a, _b;
|
|
43
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
44
|
+
super(...args);
|
|
45
|
+
// Metadata is stored on the original class prototype by decorators
|
|
46
|
+
// Route is the base class, so Route.prototype is where metadata is stored
|
|
47
|
+
const handlers = (_a = commons_1.Metadata.get(commons_2.ROUTER_HANDLERS_KEY, Route.prototype)) !== null && _a !== void 0 ? _a : [];
|
|
48
|
+
this.router = (0, express_1.Router)();
|
|
49
|
+
this.mountpoint = mountpoint;
|
|
50
|
+
for (const handler of handlers) {
|
|
51
|
+
const middlewares = (_b = handler.handler.$middlewares) !== null && _b !== void 0 ? _b : [];
|
|
52
|
+
const verb = handler.verb;
|
|
53
|
+
const routeMethod = this.router[verb];
|
|
54
|
+
if (typeof routeMethod === 'function') {
|
|
55
|
+
const allHandlers = [...middlewares, this.__registerHandler(handler)];
|
|
56
|
+
routeMethod.apply(this.router, [handler.route, ...allHandlers]);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
__mount(parent) {
|
|
61
|
+
// Metadata is stored on the original class prototype by decorators
|
|
62
|
+
const rootMiddlewares = commons_1.Metadata.get(commons_2.ROUTER_MIDDLEWARES_KEY, Route.prototype) || [];
|
|
63
|
+
parent.use(this.mountpoint, ...rootMiddlewares, this.router);
|
|
64
|
+
return this;
|
|
65
|
+
}
|
|
66
|
+
__registerHandler(options) {
|
|
67
|
+
const decoratedArguments = commons_1.Metadata.get(commons_2.ARGUMENTS_KEY, options.target, options.propertyKey);
|
|
68
|
+
const annotations = commons_1.Metadata.get(commons_2.ROUTER_ANNOTATIONS_KEY, options.target, options.propertyKey);
|
|
69
|
+
const optionsWithArgs = options;
|
|
70
|
+
return server_1.executeRequest.bind({
|
|
71
|
+
options: optionsWithArgs,
|
|
72
|
+
decoratedArguments,
|
|
73
|
+
annotations,
|
|
74
|
+
self: this
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
ExpressiveTeaRoute = tslib_1.__decorate([
|
|
79
|
+
(0, inversify_1.injectable)('Singleton'),
|
|
80
|
+
(0, inversify_1.injectFromBase)({ extendConstructorArguments: true }),
|
|
81
|
+
tslib_1.__metadata("design:paramtypes", [Object])
|
|
82
|
+
], ExpressiveTeaRoute);
|
|
83
|
+
// Bind the original class to the wrapped class in the DI container
|
|
84
|
+
// This ensures that when modules request the original class via getInstanceOf(),
|
|
85
|
+
// they receive an instance of the wrapped ExpressiveTeaRoute class instead
|
|
86
|
+
try {
|
|
87
|
+
if (DependencyInjection_1.default.Container.isBound(Route)) {
|
|
88
|
+
DependencyInjection_1.default.Container.unbind(Route);
|
|
89
|
+
}
|
|
90
|
+
DependencyInjection_1.default.Container.bind(Route).to(ExpressiveTeaRoute);
|
|
91
|
+
}
|
|
92
|
+
catch (_a) {
|
|
93
|
+
// Binding may fail in some contexts, but that's okay - the class is still usable
|
|
94
|
+
}
|
|
95
|
+
return ExpressiveTeaRoute;
|
|
96
|
+
}
|
package/package.json
CHANGED
|
@@ -1,21 +1,25 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zerooneit/expressive-tea",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "A
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "A modern TypeScript-first framework for building scalable Node.js applications with clean architecture, dependency injection, and decorator-driven development",
|
|
5
5
|
"main": "classes/Boot.js",
|
|
6
6
|
"engines": {
|
|
7
|
-
"node": ">=
|
|
7
|
+
"node": ">=20.0.0"
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
|
-
"test": "yarn
|
|
11
|
-
"test:
|
|
12
|
-
"
|
|
10
|
+
"test": "yarn linter && jest --maxWorkers=4 --coverage --detectOpenHandles --forceExit --silent",
|
|
11
|
+
"test:clear": "jest --clearCache",
|
|
12
|
+
"test:ci": "yarn linter:ci && yarn test:clear && jest --coverage --ci --detectOpenHandles --forceExit --silent",
|
|
13
|
+
"test:dev": "yarn linter && yarn test:clear && jest --detectOpenHandles --forceExit",
|
|
14
|
+
"format": "prettier --ignore-path .gitignore --write \"**/*.+(js|ts|json)\"",
|
|
15
|
+
"linter": "eslint . --fix",
|
|
16
|
+
"linter:ci": "eslint .",
|
|
13
17
|
"build:dev": "tsc --project tsconfig.json --watch",
|
|
14
|
-
"build": "tsc --project tsconfig.json",
|
|
18
|
+
"build": "tsc --project tsconfig.json && resolve-tspaths --src . --out .",
|
|
15
19
|
"clean:build": "trash '**/*.js' '**/*.d.ts' '**/*.js.map' '**/*.d.ts.map' '!node_modules/**/*' '!docs/**/*' '!coverage/**/*' '!gulpfile.js' '!tasks/*.js' '!jest.config.js' '!tools/**/*'",
|
|
16
|
-
"publish:prepare": "
|
|
17
|
-
"postpublish": "
|
|
18
|
-
"prepublishOnly": "
|
|
20
|
+
"publish:prepare": "npm run clean:build && npm run build",
|
|
21
|
+
"postpublish": "npm run clean:build",
|
|
22
|
+
"prepublishOnly": "npm run publish:prepare"
|
|
19
23
|
},
|
|
20
24
|
"publishConfig": {
|
|
21
25
|
"access": "public"
|
|
@@ -25,91 +29,109 @@
|
|
|
25
29
|
],
|
|
26
30
|
"license": "Apache-2.0",
|
|
27
31
|
"devDependencies": {
|
|
28
|
-
"@
|
|
29
|
-
"@
|
|
30
|
-
"@
|
|
31
|
-
"@
|
|
32
|
-
"@
|
|
33
|
-
"@
|
|
34
|
-
"@types/
|
|
35
|
-
"@types/
|
|
36
|
-
"@types/
|
|
37
|
-
"@types/
|
|
38
|
-
"@types/
|
|
39
|
-
"@types/
|
|
32
|
+
"@eslint/eslintrc": "3.3.1",
|
|
33
|
+
"@eslint/js": "9.39.1",
|
|
34
|
+
"@expressive-tea/commons": "2026.1.1",
|
|
35
|
+
"@expressive-tea/plugin": "2026.1.1",
|
|
36
|
+
"@swc/core": "^1.15.11",
|
|
37
|
+
"@swc/jest": "^0.2.39",
|
|
38
|
+
"@types/express": "5.0.0",
|
|
39
|
+
"@types/express-http-proxy": "1.6.7",
|
|
40
|
+
"@types/express-serve-static-core": "4.19.7",
|
|
41
|
+
"@types/jest": "29.5.14",
|
|
42
|
+
"@types/js-yaml": "^4.0.9",
|
|
43
|
+
"@types/node": "20.19.24",
|
|
44
|
+
"@types/supertest": "6.0.3",
|
|
45
|
+
"@types/ws": "8.18.1",
|
|
46
|
+
"@typescript-eslint/eslint-plugin": "8.46.4",
|
|
47
|
+
"@typescript-eslint/parser": "8.46.4",
|
|
48
|
+
"eslint": "9.39.1",
|
|
49
|
+
"eslint-config-prettier": "10.1.8",
|
|
50
|
+
"eslint-plugin-import": "2.32.0",
|
|
51
|
+
"eslint-plugin-jsdoc": "61.1.12",
|
|
52
|
+
"eslint-plugin-n": "17.23.1",
|
|
53
|
+
"eslint-plugin-prefer-arrow": "1.2.3",
|
|
54
|
+
"eslint-plugin-promise": "7.2.1",
|
|
55
|
+
"globals": "16.5.0",
|
|
40
56
|
"http-terminator": "3.2.0",
|
|
41
|
-
"jest": "
|
|
57
|
+
"jest": "30.2.0",
|
|
42
58
|
"jest-express": "1.12.0",
|
|
43
59
|
"jest-junit": "16.0.0",
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"
|
|
60
|
+
"prettier": "^3.8.1",
|
|
61
|
+
"reflect-metadata": "0.2.2",
|
|
62
|
+
"resolve-tspaths": "0.8.23",
|
|
63
|
+
"rimraf": "6.1.0",
|
|
64
|
+
"supertest": "7.1.4",
|
|
47
65
|
"toast-jsdoc": "1.0.2",
|
|
48
|
-
"trash-cli": "
|
|
49
|
-
"ts-jest": "29.
|
|
50
|
-
"ts-
|
|
51
|
-
"
|
|
52
|
-
"
|
|
66
|
+
"trash-cli": "7.0.0",
|
|
67
|
+
"ts-jest": "29.4.5",
|
|
68
|
+
"ts-jest-resolver": "2.0.1",
|
|
69
|
+
"ts-node": "10.9.2",
|
|
70
|
+
"tsconfig-paths": "4.2.0",
|
|
71
|
+
"tslib": "2.8.1",
|
|
72
|
+
"typescript": "5.9.3"
|
|
53
73
|
},
|
|
54
74
|
"dependencies": {
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
"
|
|
75
|
+
"chalk": "4.1.2",
|
|
76
|
+
"dotenv": "^16.4.5",
|
|
77
|
+
"express": "5.2.1",
|
|
78
|
+
"express-http-proxy": "2.1.2",
|
|
79
|
+
"inversify": "7.11.0",
|
|
58
80
|
"inversify-inject-decorators": "3.1.0",
|
|
59
|
-
"
|
|
60
|
-
"
|
|
61
|
-
"socket.io
|
|
81
|
+
"js-yaml": "^4.1.0",
|
|
82
|
+
"lodash": "4.17.23",
|
|
83
|
+
"socket.io": "4.8.1",
|
|
84
|
+
"socket.io-client": "4.8.1",
|
|
62
85
|
"url-scheme": "1.0.5",
|
|
63
|
-
"ws": "8.
|
|
86
|
+
"ws": "8.18.3"
|
|
64
87
|
},
|
|
65
88
|
"repository": {
|
|
66
89
|
"type": "git",
|
|
67
|
-
"url": "git+https://github.com/
|
|
90
|
+
"url": "git+https://github.com/Expressive-Tea/expresive-tea.git"
|
|
68
91
|
},
|
|
69
92
|
"keywords": [
|
|
70
|
-
"Typescript",
|
|
71
93
|
"typescript",
|
|
72
|
-
"
|
|
73
|
-
"Decorators",
|
|
74
|
-
"decorators",
|
|
75
|
-
"decorator",
|
|
76
|
-
"controller",
|
|
77
|
-
"inject",
|
|
78
|
-
"ioc",
|
|
79
|
-
"di",
|
|
80
|
-
"mvc",
|
|
81
|
-
"es6",
|
|
82
|
-
"es2015",
|
|
83
|
-
"REST",
|
|
84
|
-
"API",
|
|
94
|
+
"typescript-framework",
|
|
85
95
|
"express",
|
|
86
|
-
"
|
|
87
|
-
"
|
|
88
|
-
"
|
|
89
|
-
"
|
|
90
|
-
"
|
|
91
|
-
"
|
|
96
|
+
"express-typescript",
|
|
97
|
+
"decorators",
|
|
98
|
+
"dependency-injection",
|
|
99
|
+
"inversify",
|
|
100
|
+
"rest-api",
|
|
101
|
+
"api-framework",
|
|
102
|
+
"backend-framework",
|
|
103
|
+
"nodejs-framework",
|
|
104
|
+
"mvc-framework",
|
|
105
|
+
"clean-architecture",
|
|
106
|
+
"type-safe",
|
|
107
|
+
"server-framework",
|
|
108
|
+
"microservices",
|
|
109
|
+
"websocket",
|
|
110
|
+
"socket.io",
|
|
111
|
+
"health-checks",
|
|
92
112
|
"middleware",
|
|
93
113
|
"controllers",
|
|
94
|
-
"
|
|
95
|
-
"
|
|
96
|
-
"backend"
|
|
97
|
-
"services",
|
|
98
|
-
"node",
|
|
99
|
-
"nodejs"
|
|
114
|
+
"routing",
|
|
115
|
+
"ioc-container",
|
|
116
|
+
"modern-backend"
|
|
100
117
|
],
|
|
101
118
|
"bugs": {
|
|
102
119
|
"url": "https://github.com/Expressive-Tea/expresive-tea/issues"
|
|
103
120
|
},
|
|
104
121
|
"homepage": "https://github.com/Expressive-Tea/expresive-tea#readme",
|
|
105
122
|
"optionalDependencies": {
|
|
106
|
-
"bufferutil": "4.0.
|
|
107
|
-
"utf-8-validate": "
|
|
123
|
+
"bufferutil": "4.0.9",
|
|
124
|
+
"utf-8-validate": "6.0.5"
|
|
108
125
|
},
|
|
109
126
|
"resolutions": {
|
|
110
127
|
"set-value": "4.1.0",
|
|
111
128
|
"glob-parent": "6.0.2",
|
|
112
|
-
"engine.io": "6.4.2"
|
|
129
|
+
"engine.io": "6.4.2",
|
|
130
|
+
"@typescript-eslint/eslint-plugin": "8.46.4",
|
|
131
|
+
"@typescript-eslint/parser": "8.46.4",
|
|
132
|
+
"eslint": "9.39.1",
|
|
133
|
+
"eslint-plugin-n": "17.23.1",
|
|
134
|
+
"eslint-plugin-promise": "7.2.1"
|
|
113
135
|
},
|
|
114
|
-
"packageManager": "yarn@
|
|
136
|
+
"packageManager": "yarn@4.11.0"
|
|
115
137
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { Container } from 'inversify';
|
|
1
|
+
import { Container, Newable, ServiceIdentifier } from 'inversify';
|
|
2
|
+
import { LazyInversifyDecorator, LazyInversifyNamedDecorator, LazyInversifyTaggedDecorator } from '../types/inversify';
|
|
2
3
|
/**
|
|
3
4
|
* @module Services
|
|
4
5
|
*/
|
|
@@ -17,16 +18,101 @@ declare class DependencyInjection {
|
|
|
17
18
|
* @summary Inversify Container
|
|
18
19
|
*/
|
|
19
20
|
static readonly Container: Container;
|
|
21
|
+
/**
|
|
22
|
+
* Map of scoped containers for module-level isolation.
|
|
23
|
+
* @type {Map<string, Container>}
|
|
24
|
+
* @private
|
|
25
|
+
* @static
|
|
26
|
+
* @since 2.0.0
|
|
27
|
+
*/
|
|
28
|
+
private static scopedContainers;
|
|
20
29
|
/**
|
|
21
30
|
* This assign to the global inversify container Express Tea can set provider as user required to the global container
|
|
22
31
|
* and shareable to all registered modules. This method is used if required to assign a provider depending on params
|
|
23
32
|
* or data flow.
|
|
24
33
|
*
|
|
25
34
|
* @param {Class} ProviderFactory - Assign the Class to serve as factory.
|
|
26
|
-
* @param {string | symbol
|
|
35
|
+
* @param {string | symbol} [providerName="ClassName"] - Provide the provider identification.
|
|
27
36
|
* @summary Add Provider to Dependency Injection Providers
|
|
28
37
|
*/
|
|
29
|
-
static setProvider(ProviderFactory: any
|
|
38
|
+
static setProvider(ProviderFactory: Newable<any>, providerName?: ServiceIdentifier<string | symbol>): void;
|
|
39
|
+
/**
|
|
40
|
+
* Create a new scoped container for module-level dependency isolation.
|
|
41
|
+
* The scoped container inherits from the root container but maintains its own bindings.
|
|
42
|
+
*
|
|
43
|
+
* @param {string} scopeName - Unique identifier for the scope
|
|
44
|
+
* @returns {Container} The newly created scoped container
|
|
45
|
+
* @throws {Error} If a scope with the same name already exists
|
|
46
|
+
* @static
|
|
47
|
+
* @since 2.0.0
|
|
48
|
+
* @summary Create a scoped DI container
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* const moduleScope = DependencyInjection.createScope('user-module');
|
|
52
|
+
* moduleScope.bind(UserService).toSelf();
|
|
53
|
+
*/
|
|
54
|
+
static createScope(scopeName: string): Container;
|
|
55
|
+
/**
|
|
56
|
+
* Retrieve an existing scoped container by name.
|
|
57
|
+
*
|
|
58
|
+
* @param {string} scopeName - Unique identifier for the scope
|
|
59
|
+
* @returns {Container | undefined} The scoped container, or undefined if not found
|
|
60
|
+
* @static
|
|
61
|
+
* @since 2.0.0
|
|
62
|
+
* @summary Get a scoped DI container
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* const moduleScope = DependencyInjection.getScope('user-module');
|
|
66
|
+
* if (moduleScope) {
|
|
67
|
+
* const service = moduleScope.get(UserService);
|
|
68
|
+
* }
|
|
69
|
+
*/
|
|
70
|
+
static getScope(scopeName: string): Container | undefined;
|
|
71
|
+
/**
|
|
72
|
+
* Destroy a scoped container and remove it from the registry.
|
|
73
|
+
* This unbinds all services within the scope and cleans up resources.
|
|
74
|
+
*
|
|
75
|
+
* @param {string} scopeName - Unique identifier for the scope
|
|
76
|
+
* @returns {boolean} True if the scope was found and destroyed, false otherwise
|
|
77
|
+
* @static
|
|
78
|
+
* @since 2.0.0
|
|
79
|
+
* @summary Destroy a scoped DI container
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* const destroyed = DependencyInjection.destroyScope('user-module');
|
|
83
|
+
* if (destroyed) {
|
|
84
|
+
* console.log('Scope destroyed successfully');
|
|
85
|
+
* }
|
|
86
|
+
*/
|
|
87
|
+
static destroyScope(scopeName: string): boolean;
|
|
88
|
+
/**
|
|
89
|
+
* Get all registered scope names.
|
|
90
|
+
*
|
|
91
|
+
* @returns {string[]} Array of scope names
|
|
92
|
+
* @static
|
|
93
|
+
* @since 2.0.0
|
|
94
|
+
* @summary Get all scope names
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* const scopes = DependencyInjection.getAllScopeNames();
|
|
98
|
+
* console.log('Active scopes:', scopes);
|
|
99
|
+
*/
|
|
100
|
+
static getAllScopeNames(): string[];
|
|
101
|
+
/**
|
|
102
|
+
* Check if a scope exists.
|
|
103
|
+
*
|
|
104
|
+
* @param {string} scopeName - Unique identifier for the scope
|
|
105
|
+
* @returns {boolean} True if the scope exists, false otherwise
|
|
106
|
+
* @static
|
|
107
|
+
* @since 2.0.0
|
|
108
|
+
* @summary Check if scope exists
|
|
109
|
+
*
|
|
110
|
+
* @example
|
|
111
|
+
* if (DependencyInjection.hasScope('user-module')) {
|
|
112
|
+
* console.log('Scope exists');
|
|
113
|
+
* }
|
|
114
|
+
*/
|
|
115
|
+
static hasScope(scopeName: string): boolean;
|
|
30
116
|
}
|
|
31
117
|
/**
|
|
32
118
|
* @module Decorators/DependencyInjection
|
|
@@ -40,7 +126,7 @@ declare class DependencyInjection {
|
|
|
40
126
|
* @summary Inject a instance of provider defined as Dependency Injection.
|
|
41
127
|
* @function
|
|
42
128
|
*/
|
|
43
|
-
export declare const Inject:
|
|
129
|
+
export declare const Inject: LazyInversifyDecorator;
|
|
44
130
|
/**
|
|
45
131
|
* This implement the Tagged Bindings from Inversify to used on the contructors arguments of the injectable classes and
|
|
46
132
|
* allow not create ambiguous match as named annotation, also check out
|
|
@@ -50,7 +136,7 @@ export declare const Inject: (...args: any[]) => any;
|
|
|
50
136
|
* @summary Bind provider as named annotation.
|
|
51
137
|
* @function
|
|
52
138
|
*/
|
|
53
|
-
export declare const InjectNamed:
|
|
139
|
+
export declare const InjectNamed: LazyInversifyNamedDecorator;
|
|
54
140
|
/**
|
|
55
141
|
* This implement the Named Bindings from Inversify to used on the contructors arguments of the injectable classes and
|
|
56
142
|
* allow not create ambiguous match as tagged annotation.
|
|
@@ -59,7 +145,7 @@ export declare const InjectNamed: (...args: any[]) => any;
|
|
|
59
145
|
* @summary Bind provider as tagged annotation.
|
|
60
146
|
* @function
|
|
61
147
|
*/
|
|
62
|
-
export declare const InjectTagged:
|
|
148
|
+
export declare const InjectTagged: LazyInversifyTaggedDecorator;
|
|
63
149
|
/**
|
|
64
150
|
* Bind an array of bind providers with the same name over the constructor parameter.
|
|
65
151
|
* {@link https://github.com/inversify/InversifyJS/blob/master/wiki/multi_injection.md Multiple Injection}
|
|
@@ -67,5 +153,7 @@ export declare const InjectTagged: (...args: any[]) => any;
|
|
|
67
153
|
* @summary Define multiple concretions for defined inject.
|
|
68
154
|
* @function
|
|
69
155
|
*/
|
|
70
|
-
export declare const MultiInject:
|
|
156
|
+
export declare const MultiInject: LazyInversifyDecorator;
|
|
157
|
+
export declare function defineConstant<T>(name: string | symbol, value: T): void;
|
|
158
|
+
export declare function getInstanceOf<T>(Target: Newable<T>): T;
|
|
71
159
|
export default DependencyInjection;
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.MultiInject = exports.InjectTagged = exports.InjectNamed = exports.Inject = void 0;
|
|
4
|
+
exports.defineConstant = defineConstant;
|
|
5
|
+
exports.getInstanceOf = getInstanceOf;
|
|
4
6
|
const inversify_1 = require("inversify");
|
|
7
|
+
const inversify_config_1 = require("../inversify.config");
|
|
5
8
|
const inversify_inject_decorators_1 = require("inversify-inject-decorators");
|
|
6
9
|
const rootContainer = new inversify_1.Container({
|
|
7
|
-
|
|
10
|
+
autobind: true,
|
|
11
|
+
parent: inversify_config_1.default,
|
|
8
12
|
});
|
|
9
13
|
const lazyDecorators = (0, inversify_inject_decorators_1.default)(rootContainer);
|
|
10
14
|
/**
|
|
@@ -23,14 +27,114 @@ class DependencyInjection {
|
|
|
23
27
|
* or data flow.
|
|
24
28
|
*
|
|
25
29
|
* @param {Class} ProviderFactory - Assign the Class to serve as factory.
|
|
26
|
-
* @param {string | symbol
|
|
30
|
+
* @param {string | symbol} [providerName="ClassName"] - Provide the provider identification.
|
|
27
31
|
* @summary Add Provider to Dependency Injection Providers
|
|
28
32
|
*/
|
|
29
|
-
static setProvider(
|
|
30
|
-
|
|
31
|
-
|
|
33
|
+
static setProvider(
|
|
34
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
35
|
+
ProviderFactory, providerName) {
|
|
36
|
+
if (!rootContainer.isBound(providerName !== null && providerName !== void 0 ? providerName : ProviderFactory.name)) {
|
|
37
|
+
rootContainer.bind(providerName !== null && providerName !== void 0 ? providerName : ProviderFactory.name).to(ProviderFactory);
|
|
32
38
|
}
|
|
33
39
|
}
|
|
40
|
+
/**
|
|
41
|
+
* Create a new scoped container for module-level dependency isolation.
|
|
42
|
+
* The scoped container inherits from the root container but maintains its own bindings.
|
|
43
|
+
*
|
|
44
|
+
* @param {string} scopeName - Unique identifier for the scope
|
|
45
|
+
* @returns {Container} The newly created scoped container
|
|
46
|
+
* @throws {Error} If a scope with the same name already exists
|
|
47
|
+
* @static
|
|
48
|
+
* @since 2.0.0
|
|
49
|
+
* @summary Create a scoped DI container
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* const moduleScope = DependencyInjection.createScope('user-module');
|
|
53
|
+
* moduleScope.bind(UserService).toSelf();
|
|
54
|
+
*/
|
|
55
|
+
static createScope(scopeName) {
|
|
56
|
+
if (DependencyInjection.scopedContainers.has(scopeName)) {
|
|
57
|
+
throw new Error(`Scope "${scopeName}" already exists`);
|
|
58
|
+
}
|
|
59
|
+
const scopedContainer = new inversify_1.Container({ parent: rootContainer });
|
|
60
|
+
DependencyInjection.scopedContainers.set(scopeName, scopedContainer);
|
|
61
|
+
return scopedContainer;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Retrieve an existing scoped container by name.
|
|
65
|
+
*
|
|
66
|
+
* @param {string} scopeName - Unique identifier for the scope
|
|
67
|
+
* @returns {Container | undefined} The scoped container, or undefined if not found
|
|
68
|
+
* @static
|
|
69
|
+
* @since 2.0.0
|
|
70
|
+
* @summary Get a scoped DI container
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* const moduleScope = DependencyInjection.getScope('user-module');
|
|
74
|
+
* if (moduleScope) {
|
|
75
|
+
* const service = moduleScope.get(UserService);
|
|
76
|
+
* }
|
|
77
|
+
*/
|
|
78
|
+
static getScope(scopeName) {
|
|
79
|
+
return DependencyInjection.scopedContainers.get(scopeName);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Destroy a scoped container and remove it from the registry.
|
|
83
|
+
* This unbinds all services within the scope and cleans up resources.
|
|
84
|
+
*
|
|
85
|
+
* @param {string} scopeName - Unique identifier for the scope
|
|
86
|
+
* @returns {boolean} True if the scope was found and destroyed, false otherwise
|
|
87
|
+
* @static
|
|
88
|
+
* @since 2.0.0
|
|
89
|
+
* @summary Destroy a scoped DI container
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* const destroyed = DependencyInjection.destroyScope('user-module');
|
|
93
|
+
* if (destroyed) {
|
|
94
|
+
* console.log('Scope destroyed successfully');
|
|
95
|
+
* }
|
|
96
|
+
*/
|
|
97
|
+
static destroyScope(scopeName) {
|
|
98
|
+
const scopedContainer = DependencyInjection.scopedContainers.get(scopeName);
|
|
99
|
+
if (scopedContainer) {
|
|
100
|
+
scopedContainer.unbindAll();
|
|
101
|
+
DependencyInjection.scopedContainers.delete(scopeName);
|
|
102
|
+
return true;
|
|
103
|
+
}
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Get all registered scope names.
|
|
108
|
+
*
|
|
109
|
+
* @returns {string[]} Array of scope names
|
|
110
|
+
* @static
|
|
111
|
+
* @since 2.0.0
|
|
112
|
+
* @summary Get all scope names
|
|
113
|
+
*
|
|
114
|
+
* @example
|
|
115
|
+
* const scopes = DependencyInjection.getAllScopeNames();
|
|
116
|
+
* console.log('Active scopes:', scopes);
|
|
117
|
+
*/
|
|
118
|
+
static getAllScopeNames() {
|
|
119
|
+
return Array.from(DependencyInjection.scopedContainers.keys());
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Check if a scope exists.
|
|
123
|
+
*
|
|
124
|
+
* @param {string} scopeName - Unique identifier for the scope
|
|
125
|
+
* @returns {boolean} True if the scope exists, false otherwise
|
|
126
|
+
* @static
|
|
127
|
+
* @since 2.0.0
|
|
128
|
+
* @summary Check if scope exists
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
* if (DependencyInjection.hasScope('user-module')) {
|
|
132
|
+
* console.log('Scope exists');
|
|
133
|
+
* }
|
|
134
|
+
*/
|
|
135
|
+
static hasScope(scopeName) {
|
|
136
|
+
return DependencyInjection.scopedContainers.has(scopeName);
|
|
137
|
+
}
|
|
34
138
|
}
|
|
35
139
|
/**
|
|
36
140
|
* This is the implementation of a global inversify container that helps to contains every Dependency Injection.
|
|
@@ -40,6 +144,14 @@ class DependencyInjection {
|
|
|
40
144
|
* @summary Inversify Container
|
|
41
145
|
*/
|
|
42
146
|
DependencyInjection.Container = rootContainer;
|
|
147
|
+
/**
|
|
148
|
+
* Map of scoped containers for module-level isolation.
|
|
149
|
+
* @type {Map<string, Container>}
|
|
150
|
+
* @private
|
|
151
|
+
* @static
|
|
152
|
+
* @since 2.0.0
|
|
153
|
+
*/
|
|
154
|
+
DependencyInjection.scopedContainers = new Map();
|
|
43
155
|
/**
|
|
44
156
|
* @module Decorators/DependencyInjection
|
|
45
157
|
*/
|
|
@@ -80,4 +192,10 @@ exports.InjectTagged = lazyDecorators.lazyInjectTagged;
|
|
|
80
192
|
* @function
|
|
81
193
|
*/
|
|
82
194
|
exports.MultiInject = lazyDecorators.lazyMultiInject;
|
|
195
|
+
function defineConstant(name, value) {
|
|
196
|
+
DependencyInjection.Container.bind(name).toConstantValue(value);
|
|
197
|
+
}
|
|
198
|
+
function getInstanceOf(Target) {
|
|
199
|
+
return DependencyInjection.Container.get(Target);
|
|
200
|
+
}
|
|
83
201
|
exports.default = DependencyInjection;
|