@expressive-tea/core 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.
Files changed (94) hide show
  1. package/.gitattributes +4 -0
  2. package/.swcrc +61 -0
  3. package/LICENSE +201 -0
  4. package/README.md +627 -0
  5. package/banner.png +0 -0
  6. package/classes/Boot.d.ts +145 -0
  7. package/classes/Boot.js +223 -0
  8. package/classes/Engine.d.ts +63 -0
  9. package/classes/Engine.js +90 -0
  10. package/classes/EngineRegistry.d.ts +154 -0
  11. package/classes/EngineRegistry.js +247 -0
  12. package/classes/LoadBalancer.d.ts +8 -0
  13. package/classes/LoadBalancer.js +28 -0
  14. package/classes/ProxyRoute.d.ts +14 -0
  15. package/classes/ProxyRoute.js +40 -0
  16. package/classes/Settings.d.ts +128 -0
  17. package/classes/Settings.js +172 -0
  18. package/decorators/annotations.d.ts +91 -0
  19. package/decorators/annotations.js +132 -0
  20. package/decorators/env.d.ts +145 -0
  21. package/decorators/env.js +177 -0
  22. package/decorators/health.d.ts +115 -0
  23. package/decorators/health.js +124 -0
  24. package/decorators/module.d.ts +34 -0
  25. package/decorators/module.js +39 -0
  26. package/decorators/proxy.d.ts +28 -0
  27. package/decorators/proxy.js +60 -0
  28. package/decorators/router.d.ts +199 -0
  29. package/decorators/router.js +252 -0
  30. package/decorators/server.d.ts +92 -0
  31. package/decorators/server.js +247 -0
  32. package/engines/constants/constants.d.ts +2 -0
  33. package/engines/constants/constants.js +5 -0
  34. package/engines/health/index.d.ts +120 -0
  35. package/engines/health/index.js +179 -0
  36. package/engines/http/index.d.ts +12 -0
  37. package/engines/http/index.js +59 -0
  38. package/engines/index.d.ts +32 -0
  39. package/engines/index.js +112 -0
  40. package/engines/socketio/index.d.ts +7 -0
  41. package/engines/socketio/index.js +30 -0
  42. package/engines/teacup/index.d.ts +27 -0
  43. package/engines/teacup/index.js +136 -0
  44. package/engines/teapot/index.d.ts +32 -0
  45. package/engines/teapot/index.js +167 -0
  46. package/engines/websocket/index.d.ts +9 -0
  47. package/engines/websocket/index.js +39 -0
  48. package/eslint.config.mjs +138 -0
  49. package/exceptions/BootLoaderExceptions.d.ts +26 -0
  50. package/exceptions/BootLoaderExceptions.js +31 -0
  51. package/exceptions/RequestExceptions.d.ts +75 -0
  52. package/exceptions/RequestExceptions.js +89 -0
  53. package/helpers/boot-helper.d.ts +7 -0
  54. package/helpers/boot-helper.js +84 -0
  55. package/helpers/decorators.d.ts +1 -0
  56. package/helpers/decorators.js +15 -0
  57. package/helpers/promise-helper.d.ts +1 -0
  58. package/helpers/promise-helper.js +6 -0
  59. package/helpers/server.d.ts +35 -0
  60. package/helpers/server.js +141 -0
  61. package/helpers/teapot-helper.d.ts +18 -0
  62. package/helpers/teapot-helper.js +88 -0
  63. package/helpers/websocket-helper.d.ts +3 -0
  64. package/helpers/websocket-helper.js +20 -0
  65. package/images/announcement-01.png +0 -0
  66. package/images/logo-sticky-01.png +0 -0
  67. package/images/logo-wp-01.png +0 -0
  68. package/images/logo.png +0 -0
  69. package/images/zero-oneit.png +0 -0
  70. package/interfaces/index.d.ts +4 -0
  71. package/interfaces/index.js +2 -0
  72. package/inversify.config.d.ts +9 -0
  73. package/inversify.config.js +8 -0
  74. package/libs/classNames.d.ts +1 -0
  75. package/libs/classNames.js +4 -0
  76. package/libs/utilities.d.ts +21910 -0
  77. package/libs/utilities.js +420 -0
  78. package/mixins/module.d.ts +45 -0
  79. package/mixins/module.js +71 -0
  80. package/mixins/proxy.d.ts +46 -0
  81. package/mixins/proxy.js +86 -0
  82. package/mixins/route.d.ts +48 -0
  83. package/mixins/route.js +96 -0
  84. package/package.json +137 -0
  85. package/services/DependencyInjection.d.ts +159 -0
  86. package/services/DependencyInjection.js +201 -0
  87. package/services/WebsocketService.d.ts +18 -0
  88. package/services/WebsocketService.js +47 -0
  89. package/types/core.d.ts +14 -0
  90. package/types/core.js +2 -0
  91. package/types/injection-types.d.ts +6 -0
  92. package/types/injection-types.js +10 -0
  93. package/types/inversify.d.ts +5 -0
  94. 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>;
@@ -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 ADDED
@@ -0,0 +1,137 @@
1
+ {
2
+ "name": "@expressive-tea/core",
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
+ "main": "classes/Boot.js",
6
+ "engines": {
7
+ "node": ">=20.0.0"
8
+ },
9
+ "scripts": {
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 .",
17
+ "build:dev": "tsc --project tsconfig.json --watch",
18
+ "build": "tsc --project tsconfig.json && resolve-tspaths --src . --out .",
19
+ "clean:build": "trash '**/*.js' '**/*.d.ts' '**/*.js.map' '**/*.d.ts.map' '!node_modules/**/*' '!docs/**/*' '!coverage/**/*' '!gulpfile.js' '!tasks/*.js' '!jest.config.js' '!tools/**/*'",
20
+ "publish:prepare": "npm run clean:build && npm run build",
21
+ "postpublish": "npm run clean:build",
22
+ "prepublishOnly": "npm test && npm run publish:prepare"
23
+ },
24
+ "publishConfig": {
25
+ "access": "public"
26
+ },
27
+ "contributors": [
28
+ "Diego Resendez <diego.resendez@zero-oneit.com>"
29
+ ],
30
+ "license": "Apache-2.0",
31
+ "devDependencies": {
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",
56
+ "http-terminator": "3.2.0",
57
+ "jest": "30.2.0",
58
+ "jest-express": "1.12.0",
59
+ "jest-junit": "16.0.0",
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",
65
+ "toast-jsdoc": "1.0.2",
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"
73
+ },
74
+ "dependencies": {
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",
80
+ "inversify-inject-decorators": "3.1.0",
81
+ "js-yaml": "^4.1.0",
82
+ "lodash": "4.17.23",
83
+ "socket.io": "4.8.1",
84
+ "socket.io-client": "4.8.1",
85
+ "url-scheme": "1.0.5",
86
+ "ws": "8.18.3"
87
+ },
88
+ "repository": {
89
+ "type": "git",
90
+ "url": "git+https://github.com/Expressive-Tea/expresive-tea.git"
91
+ },
92
+ "keywords": [
93
+ "typescript",
94
+ "typescript-framework",
95
+ "express",
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",
112
+ "middleware",
113
+ "controllers",
114
+ "routing",
115
+ "ioc-container",
116
+ "modern-backend"
117
+ ],
118
+ "bugs": {
119
+ "url": "https://github.com/Expressive-Tea/expresive-tea/issues"
120
+ },
121
+ "homepage": "https://github.com/Expressive-Tea/expresive-tea#readme",
122
+ "optionalDependencies": {
123
+ "bufferutil": "4.0.9",
124
+ "utf-8-validate": "6.0.5"
125
+ },
126
+ "resolutions": {
127
+ "set-value": "4.1.0",
128
+ "glob-parent": "6.0.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"
135
+ },
136
+ "packageManager": "yarn@4.11.0"
137
+ }
@@ -0,0 +1,159 @@
1
+ import { Container, Newable, ServiceIdentifier } from 'inversify';
2
+ import { LazyInversifyDecorator, LazyInversifyNamedDecorator, LazyInversifyTaggedDecorator } from '../types/inversify';
3
+ /**
4
+ * @module Services
5
+ */
6
+ /**
7
+ * This Class contain the helpers to add on the dynamically Dependency Injection Providers which will be used globally
8
+ * by all the components.
9
+ * @class DependencyInjection
10
+ * @summary Define a Dependency Injection Provider
11
+ */
12
+ declare class DependencyInjection {
13
+ /**
14
+ * This is the implementation of a global inversify container that helps to contains every Dependency Injection.
15
+ * @type {InversifyContainers}
16
+ * @static
17
+ * @readonly
18
+ * @summary Inversify Container
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;
29
+ /**
30
+ * This assign to the global inversify container Express Tea can set provider as user required to the global container
31
+ * and shareable to all registered modules. This method is used if required to assign a provider depending on params
32
+ * or data flow.
33
+ *
34
+ * @param {Class} ProviderFactory - Assign the Class to serve as factory.
35
+ * @param {string | symbol} [providerName="ClassName"] - Provide the provider identification.
36
+ * @summary Add Provider to Dependency Injection Providers
37
+ */
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;
116
+ }
117
+ /**
118
+ * @module Decorators/DependencyInjection
119
+ */
120
+ /**
121
+ * This annotation allow inject directly into a class property an instance of the provider as is passed on the
122
+ * provider declaration, checkout
123
+ * {@link https://github.com/inversify/InversifyJS/blob/master/wiki/classes_as_id.md Classes as ID}
124
+ * from Inversify Project.
125
+ * @decorator {PropertyDecorator} Inject - Inject a dependency constructor defined as provider.
126
+ * @summary Inject a instance of provider defined as Dependency Injection.
127
+ * @function
128
+ */
129
+ export declare const Inject: LazyInversifyDecorator;
130
+ /**
131
+ * This implement the Tagged Bindings from Inversify to used on the contructors arguments of the injectable classes and
132
+ * allow not create ambiguous match as named annotation, also check out
133
+ * {@link https://github.com/inversify/InversifyJS/blob/master/wiki/named_bindings.md Named Bindings}
134
+ * from Inversify Project.
135
+ * @decorator {ConstructorParameter} InjectNamed - Inject a provider instance on costructor arguments.
136
+ * @summary Bind provider as named annotation.
137
+ * @function
138
+ */
139
+ export declare const InjectNamed: LazyInversifyNamedDecorator;
140
+ /**
141
+ * This implement the Named Bindings from Inversify to used on the contructors arguments of the injectable classes and
142
+ * allow not create ambiguous match as tagged annotation.
143
+ * {@link https://github.com/inversify/InversifyJS/blob/master/wiki/tagged_bindings.md Tagged Bindings}
144
+ * @decorator {ConstructorParameter} InjectTagged - Inject a provider instance on costructor arguments.
145
+ * @summary Bind provider as tagged annotation.
146
+ * @function
147
+ */
148
+ export declare const InjectTagged: LazyInversifyTaggedDecorator;
149
+ /**
150
+ * Bind an array of bind providers with the same name over the constructor parameter.
151
+ * {@link https://github.com/inversify/InversifyJS/blob/master/wiki/multi_injection.md Multiple Injection}
152
+ * @decorator {ConstructorParameter} MultiInject - Inject an array of providers under same name.
153
+ * @summary Define multiple concretions for defined inject.
154
+ * @function
155
+ */
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;
159
+ export default DependencyInjection;
@@ -0,0 +1,201 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MultiInject = exports.InjectTagged = exports.InjectNamed = exports.Inject = void 0;
4
+ exports.defineConstant = defineConstant;
5
+ exports.getInstanceOf = getInstanceOf;
6
+ const inversify_1 = require("inversify");
7
+ const inversify_config_1 = require("../inversify.config");
8
+ const inversify_inject_decorators_1 = require("inversify-inject-decorators");
9
+ const rootContainer = new inversify_1.Container({
10
+ autobind: true,
11
+ parent: inversify_config_1.default,
12
+ });
13
+ const lazyDecorators = (0, inversify_inject_decorators_1.default)(rootContainer);
14
+ /**
15
+ * @module Services
16
+ */
17
+ /**
18
+ * This Class contain the helpers to add on the dynamically Dependency Injection Providers which will be used globally
19
+ * by all the components.
20
+ * @class DependencyInjection
21
+ * @summary Define a Dependency Injection Provider
22
+ */
23
+ class DependencyInjection {
24
+ /**
25
+ * This assign to the global inversify container Express Tea can set provider as user required to the global container
26
+ * and shareable to all registered modules. This method is used if required to assign a provider depending on params
27
+ * or data flow.
28
+ *
29
+ * @param {Class} ProviderFactory - Assign the Class to serve as factory.
30
+ * @param {string | symbol} [providerName="ClassName"] - Provide the provider identification.
31
+ * @summary Add Provider to Dependency Injection Providers
32
+ */
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);
38
+ }
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
+ }
138
+ }
139
+ /**
140
+ * This is the implementation of a global inversify container that helps to contains every Dependency Injection.
141
+ * @type {InversifyContainers}
142
+ * @static
143
+ * @readonly
144
+ * @summary Inversify Container
145
+ */
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();
155
+ /**
156
+ * @module Decorators/DependencyInjection
157
+ */
158
+ /**
159
+ * This annotation allow inject directly into a class property an instance of the provider as is passed on the
160
+ * provider declaration, checkout
161
+ * {@link https://github.com/inversify/InversifyJS/blob/master/wiki/classes_as_id.md Classes as ID}
162
+ * from Inversify Project.
163
+ * @decorator {PropertyDecorator} Inject - Inject a dependency constructor defined as provider.
164
+ * @summary Inject a instance of provider defined as Dependency Injection.
165
+ * @function
166
+ */
167
+ exports.Inject = lazyDecorators.lazyInject;
168
+ /**
169
+ * This implement the Tagged Bindings from Inversify to used on the contructors arguments of the injectable classes and
170
+ * allow not create ambiguous match as named annotation, also check out
171
+ * {@link https://github.com/inversify/InversifyJS/blob/master/wiki/named_bindings.md Named Bindings}
172
+ * from Inversify Project.
173
+ * @decorator {ConstructorParameter} InjectNamed - Inject a provider instance on costructor arguments.
174
+ * @summary Bind provider as named annotation.
175
+ * @function
176
+ */
177
+ exports.InjectNamed = lazyDecorators.lazyInjectNamed;
178
+ /**
179
+ * This implement the Named Bindings from Inversify to used on the contructors arguments of the injectable classes and
180
+ * allow not create ambiguous match as tagged annotation.
181
+ * {@link https://github.com/inversify/InversifyJS/blob/master/wiki/tagged_bindings.md Tagged Bindings}
182
+ * @decorator {ConstructorParameter} InjectTagged - Inject a provider instance on costructor arguments.
183
+ * @summary Bind provider as tagged annotation.
184
+ * @function
185
+ */
186
+ exports.InjectTagged = lazyDecorators.lazyInjectTagged;
187
+ /**
188
+ * Bind an array of bind providers with the same name over the constructor parameter.
189
+ * {@link https://github.com/inversify/InversifyJS/blob/master/wiki/multi_injection.md Multiple Injection}
190
+ * @decorator {ConstructorParameter} MultiInject - Inject an array of providers under same name.
191
+ * @summary Define multiple concretions for defined inject.
192
+ * @function
193
+ */
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
+ }
201
+ exports.default = DependencyInjection;
@@ -0,0 +1,18 @@
1
+ import type WebSocket from 'ws';
2
+ import type * as http from 'http';
3
+ import * as https from 'https';
4
+ export default class WebsocketService {
5
+ static instance: WebsocketService | undefined;
6
+ private ws;
7
+ private wss;
8
+ httpServer: http.Server;
9
+ httpsServer: https.Server;
10
+ constructor(ws?: WebSocket.Server, wss?: WebSocket.Server);
11
+ getWebsocket(httpServer: http.Server | https.Server): WebSocket.Server;
12
+ setHttpServer(httpServer: http.Server | https.Server): void;
13
+ setWebSocket(ws: WebSocket.Server): void;
14
+ setSecureWebsocket(wss: WebSocket.Server): void;
15
+ static getInstance(ws?: WebSocket.Server, wss?: WebSocket.Server): WebsocketService;
16
+ static init(ws?: WebSocket.Server, wss?: WebSocket.Server): void;
17
+ static clear(): void;
18
+ }