@zerooneit/expressive-tea 1.3.0-beta.6 → 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 (78) hide show
  1. package/.swcrc +61 -0
  2. package/README.md +564 -174
  3. package/classes/Boot.d.ts +89 -2
  4. package/classes/Boot.js +149 -31
  5. package/classes/Engine.d.ts +58 -10
  6. package/classes/Engine.js +69 -9
  7. package/classes/EngineRegistry.d.ts +154 -0
  8. package/classes/EngineRegistry.js +247 -0
  9. package/classes/LoadBalancer.js +2 -5
  10. package/classes/ProxyRoute.js +5 -5
  11. package/classes/Settings.d.ts +31 -2
  12. package/classes/Settings.js +64 -11
  13. package/decorators/annotations.d.ts +1 -1
  14. package/decorators/annotations.js +17 -17
  15. package/decorators/env.d.ts +145 -0
  16. package/decorators/env.js +177 -0
  17. package/decorators/health.d.ts +115 -0
  18. package/decorators/health.js +124 -0
  19. package/decorators/module.d.ts +15 -16
  20. package/decorators/module.js +14 -24
  21. package/decorators/proxy.d.ts +26 -11
  22. package/decorators/proxy.js +35 -49
  23. package/decorators/router.d.ts +17 -16
  24. package/decorators/router.js +31 -53
  25. package/decorators/server.d.ts +7 -7
  26. package/decorators/server.js +48 -50
  27. package/engines/health/index.d.ts +120 -0
  28. package/engines/health/index.js +179 -0
  29. package/engines/http/index.d.ts +6 -10
  30. package/engines/http/index.js +18 -17
  31. package/engines/index.d.ts +32 -0
  32. package/engines/index.js +112 -0
  33. package/engines/socketio/index.d.ts +2 -4
  34. package/engines/socketio/index.js +14 -7
  35. package/engines/teacup/index.d.ts +12 -2
  36. package/engines/teacup/index.js +56 -10
  37. package/engines/teapot/index.d.ts +12 -2
  38. package/engines/teapot/index.js +58 -17
  39. package/engines/websocket/index.d.ts +1 -1
  40. package/engines/websocket/index.js +8 -3
  41. package/eslint.config.mjs +138 -0
  42. package/exceptions/RequestExceptions.d.ts +3 -3
  43. package/helpers/boot-helper.d.ts +4 -4
  44. package/helpers/boot-helper.js +27 -22
  45. package/helpers/decorators.js +7 -6
  46. package/helpers/promise-helper.d.ts +1 -1
  47. package/helpers/promise-helper.js +1 -2
  48. package/helpers/server.d.ts +31 -5
  49. package/helpers/server.js +98 -60
  50. package/helpers/teapot-helper.d.ts +2 -3
  51. package/helpers/teapot-helper.js +34 -8
  52. package/helpers/websocket-helper.d.ts +1 -3
  53. package/helpers/websocket-helper.js +3 -3
  54. package/interfaces/index.d.ts +1 -1
  55. package/inversify.config.d.ts +4 -4
  56. package/inversify.config.js +1 -1
  57. package/libs/utilities.d.ts +21910 -0
  58. package/libs/utilities.js +420 -0
  59. package/mixins/module.d.ts +45 -0
  60. package/mixins/module.js +71 -0
  61. package/mixins/proxy.d.ts +46 -0
  62. package/mixins/proxy.js +86 -0
  63. package/mixins/route.d.ts +48 -0
  64. package/mixins/route.js +96 -0
  65. package/package.json +85 -73
  66. package/services/DependencyInjection.d.ts +94 -8
  67. package/services/DependencyInjection.js +121 -3
  68. package/services/WebsocketService.d.ts +2 -4
  69. package/services/WebsocketService.js +5 -3
  70. package/types/core.d.ts +14 -0
  71. package/types/core.js +2 -0
  72. package/types/injection-types.d.ts +6 -0
  73. package/types/injection-types.js +10 -0
  74. package/types/inversify.d.ts +5 -0
  75. package/types/inversify.js +3 -0
  76. package/.eslintrc.js +0 -44
  77. package/tsconfig.linter.json +0 -24
  78. package/tslint-to-eslint-config.log +0 -12
@@ -0,0 +1,145 @@
1
+ /**
2
+ * Environment variable loading options with optional transformation
3
+ * @interface EnvOptions
4
+ * @template T - Type of transformed environment variables
5
+ * @since 2.0.0
6
+ */
7
+ export interface EnvOptions<T = Record<string, string>> {
8
+ /**
9
+ * Path to the .env file (relative to project root)
10
+ * @default '.env'
11
+ */
12
+ path?: string;
13
+ /**
14
+ * Whether to override existing environment variables
15
+ * @default false
16
+ */
17
+ override?: boolean;
18
+ /**
19
+ * List of required environment variables (will throw if missing)
20
+ */
21
+ required?: string[];
22
+ /**
23
+ * Whether to ignore missing .env file
24
+ * @default false
25
+ */
26
+ silent?: boolean;
27
+ /**
28
+ * Optional transformation function for type-safe environment variables.
29
+ * Receives parsed env vars and returns transformed result.
30
+ * Use with validation libraries like Zod for runtime type safety.
31
+ *
32
+ * @param env - Parsed environment variables
33
+ * @returns Transformed and validated environment variables
34
+ * @since 2.0.1
35
+ *
36
+ * @example
37
+ * import { z } from 'zod';
38
+ * const EnvSchema = z.object({
39
+ * PORT: z.string().transform(Number),
40
+ * DATABASE_URL: z.string().url()
41
+ * });
42
+ *
43
+ * @Env({
44
+ * transform: (env) => EnvSchema.parse(env),
45
+ * onTransformError: 'throw'
46
+ * })
47
+ */
48
+ transform?: (env: Record<string, string>) => T;
49
+ /**
50
+ * Behavior when transform function throws an error
51
+ * - 'throw': Re-throw error immediately (fail-fast, recommended for production)
52
+ * - 'warn': Log warning and continue with unvalidated env
53
+ * - 'ignore': Silent failure, continue without transform
54
+ *
55
+ * @default 'throw'
56
+ * @since 2.0.1
57
+ */
58
+ onTransformError?: 'throw' | 'warn' | 'ignore';
59
+ }
60
+ /**
61
+ * Retrieve transformed environment variables from global storage.
62
+ * Returns null if no transform was applied.
63
+ *
64
+ * @template T - Type of transformed environment variables
65
+ * @returns Transformed environment variables or null
66
+ * @since 2.0.1
67
+ *
68
+ * @example
69
+ * const env = getTransformedEnv<MyEnvType>();
70
+ * if (env) {
71
+ * console.log(env.PORT); // Type-safe access
72
+ * }
73
+ */
74
+ export declare function getTransformedEnv<T>(): T | null;
75
+ /**
76
+ * Class decorator to load environment variables from .env files before application initialization.
77
+ *
78
+ * This decorator can be stacked to load multiple .env files in order, allowing for
79
+ * environment-specific overrides (e.g., .env → .env.local → .env.production).
80
+ *
81
+ * Environment variables are loaded BEFORE the Settings singleton is initialized,
82
+ * ensuring they're available during the entire application lifecycle.
83
+ *
84
+ * **New in v2.0.1:** Optional type-safe transformation with validation libraries like Zod.
85
+ *
86
+ * @decorator {ClassDecorator} Env - Load environment variables from .env file
87
+ * @template T - Type of transformed environment variables
88
+ * @param options - Environment loading options
89
+ * @returns Class decorator function
90
+ * @since 2.0.0
91
+ * @summary Load environment variables from .env files with optional type-safe transformation
92
+ *
93
+ * @example
94
+ * // Basic usage - load from .env
95
+ * @Env()
96
+ * class MyApp extends Boot {}
97
+ *
98
+ * @example
99
+ * // Load from custom path with required variables
100
+ * @Env({
101
+ * path: '.env.production',
102
+ * required: ['DATABASE_URL', 'API_KEY']
103
+ * })
104
+ * class MyApp extends Boot {}
105
+ *
106
+ * @example
107
+ * // Stack multiple .env files (loaded in order)
108
+ * @Env({ path: '.env' })
109
+ * @Env({ path: '.env.local', override: true, silent: true })
110
+ * class MyApp extends Boot {}
111
+ *
112
+ * @example
113
+ * // Type-safe transformation with Zod
114
+ * import { z } from 'zod';
115
+ *
116
+ * const EnvSchema = z.object({
117
+ * PORT: z.string().transform(Number),
118
+ * DATABASE_URL: z.string().url(),
119
+ * API_KEY: z.string().min(32)
120
+ * });
121
+ *
122
+ * type Env = z.infer<typeof EnvSchema>;
123
+ *
124
+ * @Env<Env>({
125
+ * path: '.env',
126
+ * required: ['DATABASE_URL', 'API_KEY'],
127
+ * transform: (env) => EnvSchema.parse(env),
128
+ * onTransformError: 'throw' // Fail fast on invalid env
129
+ * })
130
+ * class MyApp extends Boot {
131
+ * constructor() {
132
+ * super();
133
+ * // Access type-safe env
134
+ * const env = Settings.getInstance().getEnv<Env>();
135
+ * console.log(env.PORT); // Type: number
136
+ * }
137
+ * }
138
+ *
139
+ * @example
140
+ * // In your .env file:
141
+ * // DATABASE_URL=postgres://localhost:5432/mydb
142
+ * // API_KEY="secret-key-with-special-chars"
143
+ * // PORT=3000
144
+ */
145
+ export declare function Env<T = Record<string, string>>(options?: EnvOptions<T>): ClassDecorator;
@@ -0,0 +1,177 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getTransformedEnv = getTransformedEnv;
4
+ exports.Env = Env;
5
+ const fs_1 = require("fs");
6
+ const path_1 = require("path");
7
+ const dotenv = require("dotenv");
8
+ /**
9
+ * Global storage for transformed environment variables.
10
+ * Set by @Env decorator when transform option is provided.
11
+ * @private
12
+ */
13
+ let transformedEnv = null;
14
+ /**
15
+ * Store transformed environment variables in global storage.
16
+ * Used internally by @Env decorator.
17
+ *
18
+ * @template T - Type of transformed environment variables
19
+ * @param env - Transformed environment variables
20
+ * @private
21
+ * @since 2.0.1
22
+ */
23
+ function storeTransformedEnv(env) {
24
+ transformedEnv = env;
25
+ }
26
+ /**
27
+ * Retrieve transformed environment variables from global storage.
28
+ * Returns null if no transform was applied.
29
+ *
30
+ * @template T - Type of transformed environment variables
31
+ * @returns Transformed environment variables or null
32
+ * @since 2.0.1
33
+ *
34
+ * @example
35
+ * const env = getTransformedEnv<MyEnvType>();
36
+ * if (env) {
37
+ * console.log(env.PORT); // Type-safe access
38
+ * }
39
+ */
40
+ function getTransformedEnv() {
41
+ return transformedEnv;
42
+ }
43
+ /**
44
+ * Load environment variables from a .env file using dotenv.
45
+ * Supports transformation and validation via optional transform function.
46
+ *
47
+ * @template T - Type of transformed environment variables
48
+ * @param options - Environment loading options
49
+ * @throws {Error} If required variables are missing, file is not found (when not silent), or transform fails (when onTransformError='throw')
50
+ * @since 2.0.0
51
+ * @private
52
+ */
53
+ function loadEnvFile(options) {
54
+ const { path: envPath = '.env', override = false, required = [], silent = false, transform, onTransformError = 'throw' } = options;
55
+ const fullPath = (0, path_1.resolve)(process.cwd(), envPath);
56
+ // Check if file exists
57
+ if (!(0, fs_1.existsSync)(fullPath)) {
58
+ if (!silent) {
59
+ throw new Error(`Environment file not found: ${fullPath}`);
60
+ }
61
+ return undefined;
62
+ }
63
+ // Load with dotenv
64
+ const result = dotenv.config({
65
+ path: fullPath,
66
+ override
67
+ });
68
+ if (result.error && !silent) {
69
+ throw new Error(`Failed to load ${fullPath}: ${result.error.message}`);
70
+ }
71
+ // Validate required variables
72
+ const missing = required.filter((key) => process.env[key] === undefined);
73
+ if (missing.length > 0) {
74
+ throw new Error(`Missing required environment variables: ${missing.join(', ')}`);
75
+ }
76
+ // Apply transform if provided
77
+ if (transform) {
78
+ try {
79
+ const envVars = result.parsed || {};
80
+ const transformed = transform(envVars);
81
+ // Store transformed result globally
82
+ storeTransformedEnv(transformed);
83
+ return transformed;
84
+ }
85
+ catch (error) {
86
+ const errorMsg = `Environment transformation failed: ${error.message}`;
87
+ if (onTransformError === 'throw') {
88
+ throw new Error(errorMsg);
89
+ }
90
+ else if (onTransformError === 'warn') {
91
+ console.warn(`[Expressive Tea] ${errorMsg}`);
92
+ if (error.stack) {
93
+ console.warn(error.stack);
94
+ }
95
+ }
96
+ // 'ignore' - do nothing, return undefined
97
+ }
98
+ }
99
+ return undefined;
100
+ }
101
+ /**
102
+ * Class decorator to load environment variables from .env files before application initialization.
103
+ *
104
+ * This decorator can be stacked to load multiple .env files in order, allowing for
105
+ * environment-specific overrides (e.g., .env → .env.local → .env.production).
106
+ *
107
+ * Environment variables are loaded BEFORE the Settings singleton is initialized,
108
+ * ensuring they're available during the entire application lifecycle.
109
+ *
110
+ * **New in v2.0.1:** Optional type-safe transformation with validation libraries like Zod.
111
+ *
112
+ * @decorator {ClassDecorator} Env - Load environment variables from .env file
113
+ * @template T - Type of transformed environment variables
114
+ * @param options - Environment loading options
115
+ * @returns Class decorator function
116
+ * @since 2.0.0
117
+ * @summary Load environment variables from .env files with optional type-safe transformation
118
+ *
119
+ * @example
120
+ * // Basic usage - load from .env
121
+ * @Env()
122
+ * class MyApp extends Boot {}
123
+ *
124
+ * @example
125
+ * // Load from custom path with required variables
126
+ * @Env({
127
+ * path: '.env.production',
128
+ * required: ['DATABASE_URL', 'API_KEY']
129
+ * })
130
+ * class MyApp extends Boot {}
131
+ *
132
+ * @example
133
+ * // Stack multiple .env files (loaded in order)
134
+ * @Env({ path: '.env' })
135
+ * @Env({ path: '.env.local', override: true, silent: true })
136
+ * class MyApp extends Boot {}
137
+ *
138
+ * @example
139
+ * // Type-safe transformation with Zod
140
+ * import { z } from 'zod';
141
+ *
142
+ * const EnvSchema = z.object({
143
+ * PORT: z.string().transform(Number),
144
+ * DATABASE_URL: z.string().url(),
145
+ * API_KEY: z.string().min(32)
146
+ * });
147
+ *
148
+ * type Env = z.infer<typeof EnvSchema>;
149
+ *
150
+ * @Env<Env>({
151
+ * path: '.env',
152
+ * required: ['DATABASE_URL', 'API_KEY'],
153
+ * transform: (env) => EnvSchema.parse(env),
154
+ * onTransformError: 'throw' // Fail fast on invalid env
155
+ * })
156
+ * class MyApp extends Boot {
157
+ * constructor() {
158
+ * super();
159
+ * // Access type-safe env
160
+ * const env = Settings.getInstance().getEnv<Env>();
161
+ * console.log(env.PORT); // Type: number
162
+ * }
163
+ * }
164
+ *
165
+ * @example
166
+ * // In your .env file:
167
+ * // DATABASE_URL=postgres://localhost:5432/mydb
168
+ * // API_KEY="secret-key-with-special-chars"
169
+ * // PORT=3000
170
+ */
171
+ function Env(options = {}) {
172
+ return (target) => {
173
+ // Load env file immediately when decorator is applied
174
+ loadEnvFile(options);
175
+ return target;
176
+ };
177
+ }
@@ -0,0 +1,115 @@
1
+ import type { HealthCheck as HealthCheckConfig } from '../engines/health';
2
+ /**
3
+ * Health check decorator options
4
+ * @since 2.0.0
5
+ */
6
+ export interface HealthCheckOptions {
7
+ /** Array of health checks to register */
8
+ checks: HealthCheckConfig[];
9
+ }
10
+ /**
11
+ * Class decorator to register health checks for monitoring and orchestration.
12
+ *
13
+ * Adds standardized health check endpoints:
14
+ * - `/health` - Detailed health status with all checks
15
+ * - `/health/live` - Liveness probe (Kubernetes compatible)
16
+ * - `/health/ready` - Readiness probe (only passes if all critical checks pass)
17
+ *
18
+ * Health checks are executed asynchronously and can be marked as critical for readiness.
19
+ * Non-critical checks only affect the detailed `/health` endpoint.
20
+ *
21
+ * @decorator {ClassDecorator} HealthCheck - Register health checks
22
+ * @param options - Health check configuration
23
+ * @returns Class decorator function
24
+ * @since 2.0.0
25
+ * @summary Register application health checks for monitoring
26
+ *
27
+ * @example
28
+ * // Basic health check
29
+ * @HealthCheck({
30
+ * checks: [
31
+ * {
32
+ * name: 'database',
33
+ * check: async () => {
34
+ * const isConnected = await db.ping();
35
+ * return { status: isConnected ? 'pass' : 'fail' };
36
+ * },
37
+ * critical: true,
38
+ * timeout: 5000
39
+ * }
40
+ * ]
41
+ * })
42
+ * class MyApp extends Boot {}
43
+ *
44
+ * @example
45
+ * // Multiple health checks with different priorities
46
+ * @HealthCheck({
47
+ * checks: [
48
+ * {
49
+ * name: 'database',
50
+ * check: async () => {
51
+ * const connected = await db.ping();
52
+ * return {
53
+ * status: connected ? 'pass' : 'fail',
54
+ * details: { connections: db.poolSize }
55
+ * };
56
+ * },
57
+ * critical: true // Required for readiness
58
+ * },
59
+ * {
60
+ * name: 'cache',
61
+ * check: async () => {
62
+ * const ready = await redis.ping();
63
+ * return {
64
+ * status: ready ? 'pass' : 'warn', // Warn but don't fail
65
+ * details: { cached_items: await redis.dbsize() }
66
+ * };
67
+ * },
68
+ * critical: false // Optional, won't block readiness
69
+ * },
70
+ * {
71
+ * name: 'external_api',
72
+ * check: async () => {
73
+ * try {
74
+ * const response = await fetch('https://api.example.com/status');
75
+ * return { status: response.ok ? 'pass' : 'warn' };
76
+ * } catch (error) {
77
+ * return {
78
+ * status: 'warn',
79
+ * error: error.message
80
+ * };
81
+ * }
82
+ * },
83
+ * timeout: 3000
84
+ * }
85
+ * ]
86
+ * })
87
+ * class MyApp extends Boot {}
88
+ *
89
+ * @example
90
+ * // Kubernetes deployment.yaml example
91
+ * // spec:
92
+ * // containers:
93
+ * // - name: my-app
94
+ * // livenessProbe:
95
+ * // httpGet:
96
+ * // path: /health/live
97
+ * // port: 3000
98
+ * // initialDelaySeconds: 30
99
+ * // periodSeconds: 10
100
+ * // readinessProbe:
101
+ * // httpGet:
102
+ * // path: /health/ready
103
+ * // port: 3000
104
+ * // initialDelaySeconds: 5
105
+ * // periodSeconds: 5
106
+ */
107
+ export declare function HealthCheck(options: HealthCheckOptions): ClassDecorator;
108
+ /**
109
+ * Get health checks from a class
110
+ * @param target - Target class
111
+ * @returns Array of health checks
112
+ * @since 2.0.0
113
+ * @internal
114
+ */
115
+ export declare function getHealthChecks(target: any): HealthCheckConfig[];
@@ -0,0 +1,124 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HealthCheck = HealthCheck;
4
+ exports.getHealthChecks = getHealthChecks;
5
+ const commons_1 = require("@expressive-tea/commons");
6
+ /**
7
+ * Health check decorator metadata key
8
+ * @private
9
+ */
10
+ const HEALTH_CHECKS_KEY = 'expressive-tea:health-checks';
11
+ /**
12
+ * Class decorator to register health checks for monitoring and orchestration.
13
+ *
14
+ * Adds standardized health check endpoints:
15
+ * - `/health` - Detailed health status with all checks
16
+ * - `/health/live` - Liveness probe (Kubernetes compatible)
17
+ * - `/health/ready` - Readiness probe (only passes if all critical checks pass)
18
+ *
19
+ * Health checks are executed asynchronously and can be marked as critical for readiness.
20
+ * Non-critical checks only affect the detailed `/health` endpoint.
21
+ *
22
+ * @decorator {ClassDecorator} HealthCheck - Register health checks
23
+ * @param options - Health check configuration
24
+ * @returns Class decorator function
25
+ * @since 2.0.0
26
+ * @summary Register application health checks for monitoring
27
+ *
28
+ * @example
29
+ * // Basic health check
30
+ * @HealthCheck({
31
+ * checks: [
32
+ * {
33
+ * name: 'database',
34
+ * check: async () => {
35
+ * const isConnected = await db.ping();
36
+ * return { status: isConnected ? 'pass' : 'fail' };
37
+ * },
38
+ * critical: true,
39
+ * timeout: 5000
40
+ * }
41
+ * ]
42
+ * })
43
+ * class MyApp extends Boot {}
44
+ *
45
+ * @example
46
+ * // Multiple health checks with different priorities
47
+ * @HealthCheck({
48
+ * checks: [
49
+ * {
50
+ * name: 'database',
51
+ * check: async () => {
52
+ * const connected = await db.ping();
53
+ * return {
54
+ * status: connected ? 'pass' : 'fail',
55
+ * details: { connections: db.poolSize }
56
+ * };
57
+ * },
58
+ * critical: true // Required for readiness
59
+ * },
60
+ * {
61
+ * name: 'cache',
62
+ * check: async () => {
63
+ * const ready = await redis.ping();
64
+ * return {
65
+ * status: ready ? 'pass' : 'warn', // Warn but don't fail
66
+ * details: { cached_items: await redis.dbsize() }
67
+ * };
68
+ * },
69
+ * critical: false // Optional, won't block readiness
70
+ * },
71
+ * {
72
+ * name: 'external_api',
73
+ * check: async () => {
74
+ * try {
75
+ * const response = await fetch('https://api.example.com/status');
76
+ * return { status: response.ok ? 'pass' : 'warn' };
77
+ * } catch (error) {
78
+ * return {
79
+ * status: 'warn',
80
+ * error: error.message
81
+ * };
82
+ * }
83
+ * },
84
+ * timeout: 3000
85
+ * }
86
+ * ]
87
+ * })
88
+ * class MyApp extends Boot {}
89
+ *
90
+ * @example
91
+ * // Kubernetes deployment.yaml example
92
+ * // spec:
93
+ * // containers:
94
+ * // - name: my-app
95
+ * // livenessProbe:
96
+ * // httpGet:
97
+ * // path: /health/live
98
+ * // port: 3000
99
+ * // initialDelaySeconds: 30
100
+ * // periodSeconds: 10
101
+ * // readinessProbe:
102
+ * // httpGet:
103
+ * // path: /health/ready
104
+ * // port: 3000
105
+ * // initialDelaySeconds: 5
106
+ * // periodSeconds: 5
107
+ */
108
+ function HealthCheck(options) {
109
+ return (target) => {
110
+ // Store health checks in metadata
111
+ commons_1.Metadata.set(HEALTH_CHECKS_KEY, options.checks, target);
112
+ return target;
113
+ };
114
+ }
115
+ /**
116
+ * Get health checks from a class
117
+ * @param target - Target class
118
+ * @returns Array of health checks
119
+ * @since 2.0.0
120
+ * @internal
121
+ */
122
+ function getHealthChecks(target) {
123
+ return commons_1.Metadata.get(HEALTH_CHECKS_KEY, target) || [];
124
+ }
@@ -1,5 +1,6 @@
1
- import { type Express, Router } from 'express';
2
- import { type ExpressiveTeaModuleProps } from '@expressive-tea/commons/interfaces';
1
+ import { type ExpressiveTeaModuleProps } from '@expressive-tea/commons';
2
+ import { type Constructor } from '../types/core';
3
+ import { type ModulizedClass } from '../mixins/module';
3
4
  /**
4
5
  * @typedef {Object} ExpressiveTeaModuleProps
5
6
  * @property {Object[]} controllers Controllers Assigned to Module
@@ -13,23 +14,21 @@ import { type ExpressiveTeaModuleProps } from '@expressive-tea/commons/interface
13
14
  * Module Decorator is a Class Decorator which is help to register a Module into Expressive Tea. A module is a
14
15
  * placeholder over a mountpoint. We can considerate a module like a container which provide isolation and modularity
15
16
  * for our project. This module can be mounted in different applications and will move all the controller routes too.
17
+ *
16
18
  * @decorator {ClassDecorator} Module - Module Class Register Decorator
17
- * @param {ExpressiveTeaModuleProps} options
19
+ * @template TBase - The base constructor type being decorated
20
+ * @param {ExpressiveTeaModuleProps} options - Module configuration options
21
+ * @returns {(target: TBase) => ModulizedClass<TBase>} Decorator function that returns a modulized class
18
22
  * @summary Module Decorator
23
+ *
19
24
  * @example
20
25
  * {REPLACE-AT}Module({
21
- * controllers: [],
22
- * providers: [],
23
- * mountpoint: '/'
26
+ * controllers: [UserController],
27
+ * providers: [UserService],
28
+ * mountpoint: '/api'
24
29
  * })
25
- * class Example {}
30
+ * class ApiModule {}
31
+ *
32
+ * @since 1.0.0
26
33
  */
27
- export declare function Module(options: ExpressiveTeaModuleProps): <T extends new (...args: any[]) => any>(Module: T) => {
28
- new (...args: any[]): {
29
- [x: string]: any;
30
- readonly settings: ExpressiveTeaModuleProps;
31
- readonly router: Router;
32
- readonly controllers: any[];
33
- __register(server: Express): void;
34
- };
35
- } & T;
34
+ export declare function Module<TBase extends Constructor = Constructor>(options: ExpressiveTeaModuleProps): (target: TBase) => ModulizedClass<TBase>;
@@ -1,9 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Module = void 0;
4
- const express_1 = require("express");
5
- const lodash_1 = require("lodash");
6
- const DependencyInjection_1 = require("../services/DependencyInjection");
3
+ exports.Module = Module;
4
+ const module_1 = require("../mixins/module");
7
5
  /**
8
6
  * @typedef {Object} ExpressiveTeaModuleProps
9
7
  * @property {Object[]} controllers Controllers Assigned to Module
@@ -17,33 +15,25 @@ const DependencyInjection_1 = require("../services/DependencyInjection");
17
15
  * Module Decorator is a Class Decorator which is help to register a Module into Expressive Tea. A module is a
18
16
  * placeholder over a mountpoint. We can considerate a module like a container which provide isolation and modularity
19
17
  * for our project. This module can be mounted in different applications and will move all the controller routes too.
18
+ *
20
19
  * @decorator {ClassDecorator} Module - Module Class Register Decorator
21
- * @param {ExpressiveTeaModuleProps} options
20
+ * @template TBase - The base constructor type being decorated
21
+ * @param {ExpressiveTeaModuleProps} options - Module configuration options
22
+ * @returns {(target: TBase) => ModulizedClass<TBase>} Decorator function that returns a modulized class
22
23
  * @summary Module Decorator
24
+ *
23
25
  * @example
24
26
  * {REPLACE-AT}Module({
25
- * controllers: [],
26
- * providers: [],
27
- * mountpoint: '/'
27
+ * controllers: [UserController],
28
+ * providers: [UserService],
29
+ * mountpoint: '/api'
28
30
  * })
29
- * class Example {}
31
+ * class ApiModule {}
32
+ *
33
+ * @since 1.0.0
30
34
  */
31
35
  function Module(options) {
32
36
  return (Module) => {
33
- return class ExpressiveTeaModule extends Module {
34
- constructor(...args) {
35
- // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
36
- super(...args);
37
- this.router = (0, express_1.Router)();
38
- this.settings = options;
39
- (0, lodash_1.each)(this.settings.providers, (P) => { DependencyInjection_1.default.setProvider(P); });
40
- this.controllers = (0, lodash_1.map)(this.settings.controllers, C => new C());
41
- }
42
- __register(server) {
43
- (0, lodash_1.each)(this.controllers, c => c.__mount(this.router));
44
- server.use(this.settings.mountpoint, this.router);
45
- }
46
- };
37
+ return (0, module_1.Modulize)(Module, options);
47
38
  };
48
39
  }
49
- exports.Module = Module;