@riktajs/core 0.10.2 → 0.10.3
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/dist/index.cjs +3591 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +770 -0
- package/dist/index.d.ts +770 -2
- package/dist/index.js +3415 -2
- package/dist/index.js.map +1 -0
- package/package.json +12 -5
- package/dist/core/application.d.ts +0 -6
- package/dist/core/application.js +0 -248
- package/dist/core/config/abstract-config-provider.d.ts +0 -14
- package/dist/core/config/abstract-config-provider.js +0 -53
- package/dist/core/config/env-loader.d.ts +0 -3
- package/dist/core/config/env-loader.js +0 -26
- package/dist/core/config/index.d.ts +0 -2
- package/dist/core/config/index.js +0 -2
- package/dist/core/constants.d.ts +0 -30
- package/dist/core/constants.js +0 -31
- package/dist/core/container/abstract-class.utils.d.ts +0 -10
- package/dist/core/container/abstract-class.utils.js +0 -44
- package/dist/core/container/container.d.ts +0 -32
- package/dist/core/container/container.js +0 -292
- package/dist/core/container/implements.decorator.d.ts +0 -6
- package/dist/core/container/implements.decorator.js +0 -39
- package/dist/core/container/index.d.ts +0 -5
- package/dist/core/container/index.js +0 -5
- package/dist/core/container/injection-token.d.ts +0 -29
- package/dist/core/container/injection-token.js +0 -11
- package/dist/core/container/request-scope.d.ts +0 -16
- package/dist/core/container/request-scope.js +0 -49
- package/dist/core/decorators/apply-decorators.d.ts +0 -8
- package/dist/core/decorators/apply-decorators.js +0 -36
- package/dist/core/decorators/autowired.decorator.d.ts +0 -11
- package/dist/core/decorators/autowired.decorator.js +0 -78
- package/dist/core/decorators/config-property.decorator.d.ts +0 -9
- package/dist/core/decorators/config-property.decorator.js +0 -59
- package/dist/core/decorators/controller.decorator.d.ts +0 -5
- package/dist/core/decorators/controller.decorator.js +0 -18
- package/dist/core/decorators/create-param-decorator.d.ts +0 -11
- package/dist/core/decorators/create-param-decorator.js +0 -21
- package/dist/core/decorators/index.d.ts +0 -9
- package/dist/core/decorators/index.js +0 -9
- package/dist/core/decorators/injectable.decorator.d.ts +0 -3
- package/dist/core/decorators/injectable.decorator.js +0 -11
- package/dist/core/decorators/param.decorator.d.ts +0 -59
- package/dist/core/decorators/param.decorator.js +0 -38
- package/dist/core/decorators/provider.decorator.d.ts +0 -12
- package/dist/core/decorators/provider.decorator.js +0 -56
- package/dist/core/decorators/route.decorator.d.ts +0 -9
- package/dist/core/decorators/route.decorator.js +0 -30
- package/dist/core/discovery.d.ts +0 -3
- package/dist/core/discovery.js +0 -111
- package/dist/core/exceptions/catch.decorator.d.ts +0 -8
- package/dist/core/exceptions/catch.decorator.js +0 -13
- package/dist/core/exceptions/config.exceptions.d.ts +0 -9
- package/dist/core/exceptions/config.exceptions.js +0 -34
- package/dist/core/exceptions/discovery.exception.d.ts +0 -18
- package/dist/core/exceptions/discovery.exception.js +0 -39
- package/dist/core/exceptions/exception-filter.d.ts +0 -38
- package/dist/core/exceptions/exception-filter.js +0 -103
- package/dist/core/exceptions/exceptions.d.ts +0 -55
- package/dist/core/exceptions/exceptions.js +0 -91
- package/dist/core/exceptions/http-exception.d.ts +0 -24
- package/dist/core/exceptions/http-exception.js +0 -62
- package/dist/core/exceptions/index.d.ts +0 -12
- package/dist/core/exceptions/index.js +0 -7
- package/dist/core/exceptions/validation.exception.d.ts +0 -17
- package/dist/core/exceptions/validation.exception.js +0 -33
- package/dist/core/guards/can-activate.interface.d.ts +0 -4
- package/dist/core/guards/can-activate.interface.js +0 -1
- package/dist/core/guards/execution-context.d.ts +0 -28
- package/dist/core/guards/execution-context.js +0 -35
- package/dist/core/guards/index.d.ts +0 -4
- package/dist/core/guards/index.js +0 -2
- package/dist/core/guards/use-guards.decorator.d.ts +0 -6
- package/dist/core/guards/use-guards.decorator.js +0 -22
- package/dist/core/index.d.ts +0 -19
- package/dist/core/index.js +0 -17
- package/dist/core/interceptors/index.d.ts +0 -3
- package/dist/core/interceptors/index.js +0 -1
- package/dist/core/interceptors/interceptor.interface.d.ts +0 -7
- package/dist/core/interceptors/interceptor.interface.js +0 -1
- package/dist/core/interceptors/use-interceptors.decorator.d.ts +0 -6
- package/dist/core/interceptors/use-interceptors.decorator.js +0 -19
- package/dist/core/lifecycle/event-bus.d.ts +0 -57
- package/dist/core/lifecycle/event-bus.js +0 -108
- package/dist/core/lifecycle/index.d.ts +0 -3
- package/dist/core/lifecycle/index.js +0 -3
- package/dist/core/lifecycle/interfaces.d.ts +0 -15
- package/dist/core/lifecycle/interfaces.js +0 -1
- package/dist/core/lifecycle/on.decorator.d.ts +0 -11
- package/dist/core/lifecycle/on.decorator.js +0 -13
- package/dist/core/metadata.d.ts +0 -20
- package/dist/core/metadata.js +0 -64
- package/dist/core/middleware/index.d.ts +0 -4
- package/dist/core/middleware/index.js +0 -2
- package/dist/core/middleware/middleware.decorator.d.ts +0 -2
- package/dist/core/middleware/middleware.decorator.js +0 -7
- package/dist/core/middleware/rikta-middleware.interface.d.ts +0 -5
- package/dist/core/middleware/rikta-middleware.interface.js +0 -1
- package/dist/core/middleware/use-middleware.decorator.d.ts +0 -6
- package/dist/core/middleware/use-middleware.decorator.js +0 -22
- package/dist/core/profiler/index.d.ts +0 -2
- package/dist/core/profiler/index.js +0 -1
- package/dist/core/profiler/performance-profiler.d.ts +0 -42
- package/dist/core/profiler/performance-profiler.js +0 -95
- package/dist/core/registry.d.ts +0 -41
- package/dist/core/registry.js +0 -109
- package/dist/core/router/router.d.ts +0 -32
- package/dist/core/router/router.js +0 -300
- package/dist/core/types.d.ts +0 -62
- package/dist/core/types.js +0 -1
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,3591 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
9
|
+
var __export = (target, all) => {
|
|
10
|
+
for (var name in all)
|
|
11
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
12
|
+
};
|
|
13
|
+
var __copyProps = (to, from, except, desc) => {
|
|
14
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
15
|
+
for (let key of __getOwnPropNames(from))
|
|
16
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
17
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
18
|
+
}
|
|
19
|
+
return to;
|
|
20
|
+
};
|
|
21
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
22
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
23
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
24
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
25
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
26
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
27
|
+
mod
|
|
28
|
+
));
|
|
29
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
30
|
+
|
|
31
|
+
// src/index.ts
|
|
32
|
+
var index_exports = {};
|
|
33
|
+
__export(index_exports, {
|
|
34
|
+
AUTOWIRED_METADATA: () => AUTOWIRED_METADATA,
|
|
35
|
+
AbstractClass: () => AbstractClass,
|
|
36
|
+
AbstractConfigProvider: () => AbstractConfigProvider,
|
|
37
|
+
Autowired: () => Autowired,
|
|
38
|
+
BadGatewayException: () => BadGatewayException,
|
|
39
|
+
BadRequestException: () => BadRequestException,
|
|
40
|
+
Body: () => Body,
|
|
41
|
+
CATCH_METADATA: () => CATCH_METADATA,
|
|
42
|
+
CONFIG_PROPERTY_METADATA: () => CONFIG_PROPERTY_METADATA,
|
|
43
|
+
CONFIG_PROVIDER_METADATA: () => CONFIG_PROVIDER_METADATA,
|
|
44
|
+
CONTROLLER_METADATA: () => CONTROLLER_METADATA,
|
|
45
|
+
CUSTOM_PARAM_METADATA: () => CUSTOM_PARAM_METADATA,
|
|
46
|
+
Catch: () => Catch,
|
|
47
|
+
ConfigProperty: () => ConfigProperty,
|
|
48
|
+
ConfigProviderAlreadyRegisteredException: () => ConfigProviderAlreadyRegisteredException,
|
|
49
|
+
ConfigProviderInstantiationException: () => ConfigProviderInstantiationException,
|
|
50
|
+
ConfigProviderNotFoundException: () => ConfigProviderNotFoundException,
|
|
51
|
+
ConfigValidationException: () => ConfigValidationException,
|
|
52
|
+
ConflictException: () => ConflictException,
|
|
53
|
+
Container: () => Container,
|
|
54
|
+
Context: () => Context,
|
|
55
|
+
Controller: () => Controller,
|
|
56
|
+
Ctx: () => Ctx,
|
|
57
|
+
DEFAULT_CONFIG: () => DEFAULT_CONFIG,
|
|
58
|
+
Delete: () => Delete,
|
|
59
|
+
DiscoveryException: () => DiscoveryException,
|
|
60
|
+
EventBus: () => EventBus,
|
|
61
|
+
ExecutionContextImpl: () => ExecutionContextImpl,
|
|
62
|
+
ForbiddenException: () => ForbiddenException,
|
|
63
|
+
GUARDS_METADATA: () => GUARDS_METADATA,
|
|
64
|
+
GatewayTimeoutException: () => GatewayTimeoutException,
|
|
65
|
+
Get: () => Get,
|
|
66
|
+
GlobalExceptionFilter: () => GlobalExceptionFilter,
|
|
67
|
+
GoneException: () => GoneException,
|
|
68
|
+
HEADERS_METADATA: () => HEADERS_METADATA,
|
|
69
|
+
HTTP_CODE_METADATA: () => HTTP_CODE_METADATA,
|
|
70
|
+
Head: () => Head,
|
|
71
|
+
Headers: () => Headers,
|
|
72
|
+
HttpCode: () => HttpCode,
|
|
73
|
+
HttpException: () => HttpException,
|
|
74
|
+
IMPLEMENTS_METADATA: () => IMPLEMENTS_METADATA,
|
|
75
|
+
INJECTABLE_METADATA: () => INJECTABLE_METADATA,
|
|
76
|
+
INJECT_METADATA: () => INJECT_METADATA,
|
|
77
|
+
INTERCEPTORS_METADATA: () => INTERCEPTORS_METADATA,
|
|
78
|
+
Implements: () => Implements,
|
|
79
|
+
Injectable: () => Injectable,
|
|
80
|
+
InjectionToken: () => InjectionToken,
|
|
81
|
+
InternalServerErrorException: () => InternalServerErrorException,
|
|
82
|
+
MIDDLEWARE_METADATA: () => MIDDLEWARE_METADATA,
|
|
83
|
+
MethodNotAllowedException: () => MethodNotAllowedException,
|
|
84
|
+
Middleware: () => Middleware,
|
|
85
|
+
Named: () => Named,
|
|
86
|
+
NotAcceptableException: () => NotAcceptableException,
|
|
87
|
+
NotFoundException: () => NotFoundException,
|
|
88
|
+
NotImplementedException: () => NotImplementedException,
|
|
89
|
+
ON_EVENT_METADATA: () => ON_EVENT_METADATA,
|
|
90
|
+
On: () => On,
|
|
91
|
+
Optional: () => Optional,
|
|
92
|
+
Options: () => Options,
|
|
93
|
+
PARAM_METADATA: () => PARAM_METADATA,
|
|
94
|
+
PRIMARY_METADATA: () => PRIMARY_METADATA,
|
|
95
|
+
PROVIDER_METADATA: () => PROVIDER_METADATA,
|
|
96
|
+
Param: () => Param,
|
|
97
|
+
ParamType: () => ParamType,
|
|
98
|
+
Patch: () => Patch,
|
|
99
|
+
PayloadTooLargeException: () => PayloadTooLargeException,
|
|
100
|
+
PerformanceProfiler: () => PerformanceProfiler,
|
|
101
|
+
Post: () => Post,
|
|
102
|
+
Primary: () => Primary,
|
|
103
|
+
Provider: () => Provider,
|
|
104
|
+
Put: () => Put,
|
|
105
|
+
Query: () => Query,
|
|
106
|
+
ROUTES_METADATA: () => ROUTES_METADATA,
|
|
107
|
+
Registry: () => Registry,
|
|
108
|
+
Reply: () => Reply,
|
|
109
|
+
Req: () => Req,
|
|
110
|
+
Request: () => Request,
|
|
111
|
+
RequestScopeStorage: () => RequestScopeStorage,
|
|
112
|
+
RequestTimeoutException: () => RequestTimeoutException,
|
|
113
|
+
Res: () => Res,
|
|
114
|
+
Rikta: () => RiktaFactory,
|
|
115
|
+
RiktaFactory: () => RiktaFactory,
|
|
116
|
+
Router: () => Router,
|
|
117
|
+
ServiceUnavailableException: () => ServiceUnavailableException,
|
|
118
|
+
SetMetadata: () => SetMetadata,
|
|
119
|
+
TooManyRequestsException: () => TooManyRequestsException,
|
|
120
|
+
UnauthorizedException: () => UnauthorizedException,
|
|
121
|
+
UnprocessableEntityException: () => UnprocessableEntityException,
|
|
122
|
+
UnsupportedMediaTypeException: () => UnsupportedMediaTypeException,
|
|
123
|
+
UseGuards: () => UseGuards,
|
|
124
|
+
UseInterceptors: () => UseInterceptors,
|
|
125
|
+
UseMiddleware: () => UseMiddleware,
|
|
126
|
+
ValidationException: () => ValidationException,
|
|
127
|
+
ZOD_SCHEMA_METADATA: () => ZOD_SCHEMA_METADATA,
|
|
128
|
+
applyDecorators: () => applyDecorators,
|
|
129
|
+
clearPropertyNameCache: () => clearPropertyNameCache,
|
|
130
|
+
container: () => container,
|
|
131
|
+
createExceptionHandler: () => createExceptionHandler,
|
|
132
|
+
createParamDecorator: () => createParamDecorator,
|
|
133
|
+
default: () => RiktaFactory,
|
|
134
|
+
discoverModules: () => discoverModules,
|
|
135
|
+
extendsFrom: () => extendsFrom,
|
|
136
|
+
getCallerDirectory: () => getCallerDirectory,
|
|
137
|
+
getCatchMetadata: () => getCatchMetadata,
|
|
138
|
+
getClassMetadata: () => getClassMetadata,
|
|
139
|
+
getConfigPropertyMappings: () => getConfigPropertyMappings,
|
|
140
|
+
getConfigProviderMetadata: () => getConfigProviderMetadata,
|
|
141
|
+
getControllerMetadata: () => getControllerMetadata,
|
|
142
|
+
getControllerPath: () => getControllerPath,
|
|
143
|
+
getCustomParamMetadata: () => getCustomParamMetadata,
|
|
144
|
+
getGlobalProfiler: () => getGlobalProfiler,
|
|
145
|
+
getGuards: () => getGuards,
|
|
146
|
+
getGuardsMetadata: () => getGuardsMetadata,
|
|
147
|
+
getHttpCode: () => getHttpCode,
|
|
148
|
+
getImplementedAbstract: () => getImplementedAbstract,
|
|
149
|
+
getInterceptorsMetadata: () => getInterceptorsMetadata,
|
|
150
|
+
getMethodMetadata: () => getMethodMetadata,
|
|
151
|
+
getMethodsWithMetadata: () => getMethodsWithMetadata,
|
|
152
|
+
getMiddlewareMetadata: () => getMiddlewareMetadata,
|
|
153
|
+
getMiddlewaresMetadata: () => getMiddlewareMetadata,
|
|
154
|
+
getParamMetadata: () => getParamMetadata,
|
|
155
|
+
getParamMetadataByIndex: () => getParamMetadataByIndex,
|
|
156
|
+
getRoutes: () => getRoutes,
|
|
157
|
+
getZodSchema: () => getZodSchema,
|
|
158
|
+
hasClassMetadata: () => hasClassMetadata,
|
|
159
|
+
hasConfigProperties: () => hasConfigProperties,
|
|
160
|
+
hasMethodMetadata: () => hasMethodMetadata,
|
|
161
|
+
hasRoutes: () => hasRoutes,
|
|
162
|
+
isAbstractClass: () => isAbstractClass,
|
|
163
|
+
isConfigProvider: () => isConfigProvider,
|
|
164
|
+
isController: () => isController,
|
|
165
|
+
isEnvLoaded: () => isEnvLoaded,
|
|
166
|
+
isPrimaryImplementation: () => isPrimaryImplementation,
|
|
167
|
+
loadEnvFiles: () => loadEnvFiles,
|
|
168
|
+
markAsAbstract: () => markAsAbstract,
|
|
169
|
+
profiler: () => profiler,
|
|
170
|
+
registry: () => registry,
|
|
171
|
+
requestScopeStorage: () => requestScopeStorage,
|
|
172
|
+
resetEnvLoaded: () => resetEnvLoaded,
|
|
173
|
+
setGlobalProfiler: () => setGlobalProfiler,
|
|
174
|
+
setImplementsMetadata: () => setImplementsMetadata,
|
|
175
|
+
setPrimaryMetadata: () => setPrimaryMetadata,
|
|
176
|
+
z: () => import_zod2.z
|
|
177
|
+
});
|
|
178
|
+
module.exports = __toCommonJS(index_exports);
|
|
179
|
+
|
|
180
|
+
// src/core/constants.ts
|
|
181
|
+
var CONTROLLER_METADATA = /* @__PURE__ */ Symbol.for("rikta:controller:metadata");
|
|
182
|
+
var ROUTES_METADATA = /* @__PURE__ */ Symbol.for("rikta:routes:metadata");
|
|
183
|
+
var INJECTABLE_METADATA = /* @__PURE__ */ Symbol.for("rikta:injectable:metadata");
|
|
184
|
+
var PARAM_METADATA = /* @__PURE__ */ Symbol.for("rikta:param:metadata");
|
|
185
|
+
var GUARDS_METADATA = /* @__PURE__ */ Symbol.for("rikta:guards:metadata");
|
|
186
|
+
var INTERCEPTORS_METADATA = /* @__PURE__ */ Symbol.for("rikta:interceptors:metadata");
|
|
187
|
+
var MIDDLEWARE_METADATA = /* @__PURE__ */ Symbol.for("rikta:middleware:metadata");
|
|
188
|
+
var HTTP_CODE_METADATA = /* @__PURE__ */ Symbol.for("rikta:http:code:metadata");
|
|
189
|
+
var HEADERS_METADATA = /* @__PURE__ */ Symbol.for("rikta:headers:metadata");
|
|
190
|
+
var INJECT_METADATA = /* @__PURE__ */ Symbol.for("rikta:inject:metadata");
|
|
191
|
+
var ZOD_SCHEMA_METADATA = /* @__PURE__ */ Symbol.for("rikta:zod:schema:metadata");
|
|
192
|
+
var AUTOWIRED_METADATA = /* @__PURE__ */ Symbol.for("rikta:autowired:metadata");
|
|
193
|
+
var PROVIDER_METADATA = /* @__PURE__ */ Symbol.for("rikta:provider:metadata");
|
|
194
|
+
var CONFIG_PROVIDER_METADATA = /* @__PURE__ */ Symbol("config:provider:metadata");
|
|
195
|
+
var CONFIG_PROPERTY_METADATA = /* @__PURE__ */ Symbol("config:property:metadata");
|
|
196
|
+
var ParamType = /* @__PURE__ */ (function(ParamType2) {
|
|
197
|
+
ParamType2["BODY"] = "body";
|
|
198
|
+
ParamType2["QUERY"] = "query";
|
|
199
|
+
ParamType2["PARAM"] = "param";
|
|
200
|
+
ParamType2["HEADERS"] = "headers";
|
|
201
|
+
ParamType2["REQUEST"] = "request";
|
|
202
|
+
ParamType2["REPLY"] = "reply";
|
|
203
|
+
ParamType2["CONTEXT"] = "context";
|
|
204
|
+
return ParamType2;
|
|
205
|
+
})({});
|
|
206
|
+
var DEFAULT_CONFIG = {
|
|
207
|
+
port: 3e3,
|
|
208
|
+
host: "0.0.0.0",
|
|
209
|
+
logger: true,
|
|
210
|
+
prefix: ""
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
// src/core/container/container.ts
|
|
214
|
+
var import_reflect_metadata = require("reflect-metadata");
|
|
215
|
+
|
|
216
|
+
// src/core/container/injection-token.ts
|
|
217
|
+
var InjectionToken = class {
|
|
218
|
+
static {
|
|
219
|
+
__name(this, "InjectionToken");
|
|
220
|
+
}
|
|
221
|
+
description;
|
|
222
|
+
options;
|
|
223
|
+
constructor(description, options) {
|
|
224
|
+
this.description = description;
|
|
225
|
+
this.options = options;
|
|
226
|
+
}
|
|
227
|
+
toString() {
|
|
228
|
+
return `InjectionToken(${this.description})`;
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
// src/core/exceptions/config.exceptions.ts
|
|
233
|
+
var ConfigProviderAlreadyRegisteredException = class extends Error {
|
|
234
|
+
static {
|
|
235
|
+
__name(this, "ConfigProviderAlreadyRegisteredException");
|
|
236
|
+
}
|
|
237
|
+
constructor(token, existingClass, newClass) {
|
|
238
|
+
super(`Config provider with token "${token}" is already registered.
|
|
239
|
+
Existing: ${existingClass}
|
|
240
|
+
Attempted: ${newClass}
|
|
241
|
+
Use a different token or remove the duplicate registration.`);
|
|
242
|
+
this.name = "ConfigProviderAlreadyRegisteredException";
|
|
243
|
+
}
|
|
244
|
+
};
|
|
245
|
+
var ConfigProviderNotFoundException = class extends Error {
|
|
246
|
+
static {
|
|
247
|
+
__name(this, "ConfigProviderNotFoundException");
|
|
248
|
+
}
|
|
249
|
+
constructor(token, availableTokens = []) {
|
|
250
|
+
const suggestion = availableTokens.length > 0 ? `
|
|
251
|
+
|
|
252
|
+
Available tokens: ${availableTokens.join(", ")}` : "";
|
|
253
|
+
super(`Config provider with token "${token}" not found.${suggestion}
|
|
254
|
+
Make sure the provider class is:
|
|
255
|
+
1. Decorated with @Provider('${token}')
|
|
256
|
+
2. Located in a file matching the autowired patterns
|
|
257
|
+
3. Properly exported from its module`);
|
|
258
|
+
this.name = "ConfigProviderNotFoundException";
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
var ConfigProviderInstantiationException = class extends Error {
|
|
262
|
+
static {
|
|
263
|
+
__name(this, "ConfigProviderInstantiationException");
|
|
264
|
+
}
|
|
265
|
+
constructor(token, className, cause) {
|
|
266
|
+
super(`Failed to instantiate config provider "${className}" (token: "${token}").
|
|
267
|
+
Cause: ${cause.message}
|
|
268
|
+
|
|
269
|
+
Check that the provider:
|
|
270
|
+
1. Has a valid constructor
|
|
271
|
+
2. All constructor dependencies are registered
|
|
272
|
+
3. The provide() method is correctly implemented`);
|
|
273
|
+
this.name = "ConfigProviderInstantiationException";
|
|
274
|
+
this.cause = cause;
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
// src/core/registry.ts
|
|
279
|
+
var Registry = class Registry2 {
|
|
280
|
+
static {
|
|
281
|
+
__name(this, "Registry");
|
|
282
|
+
}
|
|
283
|
+
static instance;
|
|
284
|
+
/** All registered controllers */
|
|
285
|
+
controllers = /* @__PURE__ */ new Set();
|
|
286
|
+
/** All registered providers (services via @Injectable) */
|
|
287
|
+
providers = /* @__PURE__ */ new Set();
|
|
288
|
+
/** All registered custom providers (via @Provider) */
|
|
289
|
+
customProviders = /* @__PURE__ */ new Set();
|
|
290
|
+
/** Map of config provider tokens to their class constructors */
|
|
291
|
+
configProviderMap = /* @__PURE__ */ new Map();
|
|
292
|
+
/** Map of abstract classes to their implementations */
|
|
293
|
+
abstractImplementations = /* @__PURE__ */ new Map();
|
|
294
|
+
constructor() {
|
|
295
|
+
}
|
|
296
|
+
static getInstance() {
|
|
297
|
+
if (!Registry2.instance) {
|
|
298
|
+
Registry2.instance = new Registry2();
|
|
299
|
+
}
|
|
300
|
+
return Registry2.instance;
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Reset the registry (useful for testing)
|
|
304
|
+
*/
|
|
305
|
+
static reset() {
|
|
306
|
+
const newInstance = new Registry2();
|
|
307
|
+
Registry2.instance = newInstance;
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Register a controller
|
|
311
|
+
*/
|
|
312
|
+
registerController(target) {
|
|
313
|
+
this.controllers.add(target);
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Register a provider
|
|
317
|
+
*/
|
|
318
|
+
registerProvider(target) {
|
|
319
|
+
this.providers.add(target);
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Get all registered controllers
|
|
323
|
+
*/
|
|
324
|
+
getControllers() {
|
|
325
|
+
return [
|
|
326
|
+
...this.controllers
|
|
327
|
+
];
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Get all registered providers
|
|
331
|
+
*/
|
|
332
|
+
getProviders() {
|
|
333
|
+
return [
|
|
334
|
+
...this.providers
|
|
335
|
+
];
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Check if a controller is registered
|
|
339
|
+
*/
|
|
340
|
+
hasController(target) {
|
|
341
|
+
return this.controllers.has(target);
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Check if a provider is registered
|
|
345
|
+
*/
|
|
346
|
+
hasProvider(target) {
|
|
347
|
+
return this.providers.has(target);
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Register a custom provider (@Provider)
|
|
351
|
+
*/
|
|
352
|
+
registerCustomProvider(target) {
|
|
353
|
+
this.customProviders.add(target);
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* Get all registered custom providers
|
|
357
|
+
*/
|
|
358
|
+
getCustomProviders() {
|
|
359
|
+
return [
|
|
360
|
+
...this.customProviders
|
|
361
|
+
];
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Check if a custom provider is registered
|
|
365
|
+
*/
|
|
366
|
+
hasCustomProvider(target) {
|
|
367
|
+
return this.customProviders.has(target);
|
|
368
|
+
}
|
|
369
|
+
// ============================================================================
|
|
370
|
+
// Config Provider Methods
|
|
371
|
+
// ============================================================================
|
|
372
|
+
/**
|
|
373
|
+
* Register a config provider with its injection token
|
|
374
|
+
*
|
|
375
|
+
* @param token - The injection token (e.g., 'APP_CONFIG')
|
|
376
|
+
* @param providerClass - The config provider class constructor
|
|
377
|
+
* @throws {ConfigProviderAlreadyRegisteredException} If the token is already registered
|
|
378
|
+
*
|
|
379
|
+
* @example
|
|
380
|
+
* ```typescript
|
|
381
|
+
* registry.registerConfigProvider('APP_CONFIG', AppConfigProvider);
|
|
382
|
+
* ```
|
|
383
|
+
*/
|
|
384
|
+
registerConfigProvider(token, providerClass) {
|
|
385
|
+
if (this.configProviderMap.has(token)) {
|
|
386
|
+
const existingClass = this.configProviderMap.get(token);
|
|
387
|
+
throw new ConfigProviderAlreadyRegisteredException(token, existingClass.name, providerClass.name);
|
|
388
|
+
}
|
|
389
|
+
this.configProviderMap.set(token, providerClass);
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Get all registered config provider classes with their tokens
|
|
393
|
+
*
|
|
394
|
+
* @returns Array of registration info objects
|
|
395
|
+
*
|
|
396
|
+
* @internal Used by auto-discovery mechanism
|
|
397
|
+
*/
|
|
398
|
+
getConfigProviderRegistrations() {
|
|
399
|
+
return Array.from(this.configProviderMap.entries()).map(([token, providerClass]) => ({
|
|
400
|
+
token,
|
|
401
|
+
providerClass
|
|
402
|
+
}));
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* Clear all config provider registrations (useful for testing)
|
|
406
|
+
*
|
|
407
|
+
* This will remove all registered config providers
|
|
408
|
+
*
|
|
409
|
+
* @internal
|
|
410
|
+
*/
|
|
411
|
+
clearConfigProviders() {
|
|
412
|
+
this.configProviderMap.clear();
|
|
413
|
+
}
|
|
414
|
+
// ============================================================================
|
|
415
|
+
// Abstract Class Implementation Methods
|
|
416
|
+
// ============================================================================
|
|
417
|
+
/**
|
|
418
|
+
* Register an implementation for an abstract class
|
|
419
|
+
*
|
|
420
|
+
* @param abstractClass - The abstract class being implemented
|
|
421
|
+
* @param implementation - The concrete implementation class
|
|
422
|
+
* @param name - Optional name for named implementations
|
|
423
|
+
*
|
|
424
|
+
* @example
|
|
425
|
+
* ```typescript
|
|
426
|
+
* registry.registerAbstractImplementation(Mailer, SmtpMailer);
|
|
427
|
+
* registry.registerAbstractImplementation(Mailer, SendGridMailer, 'sendgrid');
|
|
428
|
+
* ```
|
|
429
|
+
*/
|
|
430
|
+
registerAbstractImplementation(abstractClass, implementation, name) {
|
|
431
|
+
const implementations = this.abstractImplementations.get(abstractClass) ?? [];
|
|
432
|
+
const existing = implementations.find((i) => i.implementation === implementation);
|
|
433
|
+
if (!existing) {
|
|
434
|
+
implementations.push({
|
|
435
|
+
implementation,
|
|
436
|
+
isPrimary: false,
|
|
437
|
+
name
|
|
438
|
+
});
|
|
439
|
+
this.abstractImplementations.set(abstractClass, implementations);
|
|
440
|
+
} else if (name && !existing.name) {
|
|
441
|
+
existing.name = name;
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
/**
|
|
445
|
+
* Set the name for an implementation
|
|
446
|
+
*
|
|
447
|
+
* @param abstractClass - The abstract class
|
|
448
|
+
* @param implementation - The implementation class
|
|
449
|
+
* @param name - The name to assign
|
|
450
|
+
*/
|
|
451
|
+
setImplementationName(abstractClass, implementation, name) {
|
|
452
|
+
const implementations = this.abstractImplementations.get(abstractClass);
|
|
453
|
+
if (!implementations) {
|
|
454
|
+
return;
|
|
455
|
+
}
|
|
456
|
+
const impl = implementations.find((i) => i.implementation === implementation);
|
|
457
|
+
if (impl) {
|
|
458
|
+
impl.name = name;
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
/**
|
|
462
|
+
* Set an implementation as the primary for an abstract class
|
|
463
|
+
*
|
|
464
|
+
* @param abstractClass - The abstract class
|
|
465
|
+
* @param implementation - The implementation to mark as primary
|
|
466
|
+
*/
|
|
467
|
+
setPrimaryImplementation(abstractClass, implementation) {
|
|
468
|
+
const implementations = this.abstractImplementations.get(abstractClass);
|
|
469
|
+
if (!implementations) {
|
|
470
|
+
return;
|
|
471
|
+
}
|
|
472
|
+
for (const impl of implementations) {
|
|
473
|
+
impl.isPrimary = impl.implementation === implementation;
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
/**
|
|
477
|
+
* Get all implementations for an abstract class.
|
|
478
|
+
*
|
|
479
|
+
* This method only returns the raw metadata - resolution logic
|
|
480
|
+
* (deciding which implementation to use) belongs in the Container.
|
|
481
|
+
*
|
|
482
|
+
* @param abstractClass - The abstract class to look up
|
|
483
|
+
* @returns Array of implementation info, or empty array if none
|
|
484
|
+
*/
|
|
485
|
+
getImplementations(abstractClass) {
|
|
486
|
+
return this.abstractImplementations.get(abstractClass) ?? [];
|
|
487
|
+
}
|
|
488
|
+
/**
|
|
489
|
+
* Check if an abstract class has registered implementations
|
|
490
|
+
*
|
|
491
|
+
* @param abstractClass - The abstract class to check
|
|
492
|
+
* @returns true if at least one implementation exists
|
|
493
|
+
*/
|
|
494
|
+
hasImplementation(abstractClass) {
|
|
495
|
+
const implementations = this.abstractImplementations.get(abstractClass);
|
|
496
|
+
return !!implementations && implementations.length > 0;
|
|
497
|
+
}
|
|
498
|
+
/**
|
|
499
|
+
* Clear all abstract implementations (useful for testing)
|
|
500
|
+
*/
|
|
501
|
+
clearAbstractImplementations() {
|
|
502
|
+
this.abstractImplementations.clear();
|
|
503
|
+
}
|
|
504
|
+
};
|
|
505
|
+
var registry = Registry.getInstance();
|
|
506
|
+
|
|
507
|
+
// src/core/container/abstract-class.utils.ts
|
|
508
|
+
var IMPLEMENTS_METADATA = /* @__PURE__ */ Symbol("rikta:implements");
|
|
509
|
+
var PRIMARY_METADATA = /* @__PURE__ */ Symbol("rikta:primary");
|
|
510
|
+
function isAbstractClass(target) {
|
|
511
|
+
if (typeof target !== "function") {
|
|
512
|
+
return false;
|
|
513
|
+
}
|
|
514
|
+
const isMarkedAbstract = Reflect.getMetadata(IMPLEMENTS_METADATA, target) === void 0 && Reflect.hasMetadata("abstract:class", target);
|
|
515
|
+
if (isMarkedAbstract) {
|
|
516
|
+
return true;
|
|
517
|
+
}
|
|
518
|
+
return Reflect.getMetadata("abstract:class", target) === true;
|
|
519
|
+
}
|
|
520
|
+
__name(isAbstractClass, "isAbstractClass");
|
|
521
|
+
function extendsFrom(derived, base) {
|
|
522
|
+
if (!derived || !base) {
|
|
523
|
+
return false;
|
|
524
|
+
}
|
|
525
|
+
if (derived === base) {
|
|
526
|
+
return false;
|
|
527
|
+
}
|
|
528
|
+
let current = Object.getPrototypeOf(derived);
|
|
529
|
+
while (current && current !== Function.prototype) {
|
|
530
|
+
if (current === base) {
|
|
531
|
+
return true;
|
|
532
|
+
}
|
|
533
|
+
current = Object.getPrototypeOf(current);
|
|
534
|
+
}
|
|
535
|
+
return false;
|
|
536
|
+
}
|
|
537
|
+
__name(extendsFrom, "extendsFrom");
|
|
538
|
+
function getImplementedAbstract(target) {
|
|
539
|
+
return Reflect.getMetadata(IMPLEMENTS_METADATA, target);
|
|
540
|
+
}
|
|
541
|
+
__name(getImplementedAbstract, "getImplementedAbstract");
|
|
542
|
+
function isPrimaryImplementation(target) {
|
|
543
|
+
return Reflect.getMetadata(PRIMARY_METADATA, target) === true;
|
|
544
|
+
}
|
|
545
|
+
__name(isPrimaryImplementation, "isPrimaryImplementation");
|
|
546
|
+
function setImplementsMetadata(target, abstractClass) {
|
|
547
|
+
Reflect.defineMetadata(IMPLEMENTS_METADATA, abstractClass, target);
|
|
548
|
+
}
|
|
549
|
+
__name(setImplementsMetadata, "setImplementsMetadata");
|
|
550
|
+
function setPrimaryMetadata(target) {
|
|
551
|
+
Reflect.defineMetadata(PRIMARY_METADATA, true, target);
|
|
552
|
+
}
|
|
553
|
+
__name(setPrimaryMetadata, "setPrimaryMetadata");
|
|
554
|
+
function markAsAbstract(target) {
|
|
555
|
+
Reflect.defineMetadata("abstract:class", true, target);
|
|
556
|
+
}
|
|
557
|
+
__name(markAsAbstract, "markAsAbstract");
|
|
558
|
+
|
|
559
|
+
// src/core/container/request-scope.ts
|
|
560
|
+
var import_node_async_hooks = require("async_hooks");
|
|
561
|
+
var RequestScopeStorage = class _RequestScopeStorage {
|
|
562
|
+
static {
|
|
563
|
+
__name(this, "RequestScopeStorage");
|
|
564
|
+
}
|
|
565
|
+
static instance;
|
|
566
|
+
/** AsyncLocalStorage for request-scoped data */
|
|
567
|
+
asyncLocalStorage = new import_node_async_hooks.AsyncLocalStorage();
|
|
568
|
+
constructor() {
|
|
569
|
+
}
|
|
570
|
+
/**
|
|
571
|
+
* Get the global RequestScopeStorage instance
|
|
572
|
+
*/
|
|
573
|
+
static getInstance() {
|
|
574
|
+
if (!_RequestScopeStorage.instance) {
|
|
575
|
+
_RequestScopeStorage.instance = new _RequestScopeStorage();
|
|
576
|
+
}
|
|
577
|
+
return _RequestScopeStorage.instance;
|
|
578
|
+
}
|
|
579
|
+
/**
|
|
580
|
+
* Reset the storage (useful for testing)
|
|
581
|
+
*/
|
|
582
|
+
static reset() {
|
|
583
|
+
_RequestScopeStorage.instance = new _RequestScopeStorage();
|
|
584
|
+
}
|
|
585
|
+
/**
|
|
586
|
+
* Run a function within a request scope
|
|
587
|
+
* All request-scoped dependencies resolved within this function
|
|
588
|
+
* will be isolated to this request.
|
|
589
|
+
*
|
|
590
|
+
* @param fn - The function to run within the request scope
|
|
591
|
+
* @returns The result of the function
|
|
592
|
+
*/
|
|
593
|
+
run(fn) {
|
|
594
|
+
const store = /* @__PURE__ */ new Map();
|
|
595
|
+
return this.asyncLocalStorage.run(store, fn);
|
|
596
|
+
}
|
|
597
|
+
/**
|
|
598
|
+
* Run an async function within a request scope
|
|
599
|
+
*
|
|
600
|
+
* @param fn - The async function to run within the request scope
|
|
601
|
+
* @returns Promise resolving to the function result
|
|
602
|
+
*/
|
|
603
|
+
async runAsync(fn) {
|
|
604
|
+
const store = /* @__PURE__ */ new Map();
|
|
605
|
+
return this.asyncLocalStorage.run(store, fn);
|
|
606
|
+
}
|
|
607
|
+
/**
|
|
608
|
+
* Check if we're currently inside a request scope
|
|
609
|
+
*/
|
|
610
|
+
isInRequestScope() {
|
|
611
|
+
return this.asyncLocalStorage.getStore() !== void 0;
|
|
612
|
+
}
|
|
613
|
+
/**
|
|
614
|
+
* Get a request-scoped instance by token
|
|
615
|
+
*
|
|
616
|
+
* @param token - The injection token
|
|
617
|
+
* @returns The instance if found, undefined otherwise
|
|
618
|
+
*/
|
|
619
|
+
get(token) {
|
|
620
|
+
const store = this.asyncLocalStorage.getStore();
|
|
621
|
+
if (!store) {
|
|
622
|
+
return void 0;
|
|
623
|
+
}
|
|
624
|
+
return store.get(token);
|
|
625
|
+
}
|
|
626
|
+
/**
|
|
627
|
+
* Set a request-scoped instance
|
|
628
|
+
*
|
|
629
|
+
* @param token - The injection token
|
|
630
|
+
* @param instance - The instance to store
|
|
631
|
+
* @throws Error if not in a request scope
|
|
632
|
+
*/
|
|
633
|
+
set(token, instance) {
|
|
634
|
+
const store = this.asyncLocalStorage.getStore();
|
|
635
|
+
if (!store) {
|
|
636
|
+
throw new Error("Cannot set request-scoped instance outside of a request context. Make sure RequestScopeStorage.run() or runAsync() is being used.");
|
|
637
|
+
}
|
|
638
|
+
store.set(token, instance);
|
|
639
|
+
}
|
|
640
|
+
/**
|
|
641
|
+
* Check if a request-scoped instance exists
|
|
642
|
+
*
|
|
643
|
+
* @param token - The injection token
|
|
644
|
+
* @returns true if the instance exists in current request scope
|
|
645
|
+
*/
|
|
646
|
+
has(token) {
|
|
647
|
+
const store = this.asyncLocalStorage.getStore();
|
|
648
|
+
return store?.has(token) ?? false;
|
|
649
|
+
}
|
|
650
|
+
/**
|
|
651
|
+
* Get the current request store (for debugging/testing)
|
|
652
|
+
* @internal
|
|
653
|
+
*/
|
|
654
|
+
getStore() {
|
|
655
|
+
return this.asyncLocalStorage.getStore();
|
|
656
|
+
}
|
|
657
|
+
};
|
|
658
|
+
var requestScopeStorage = RequestScopeStorage.getInstance();
|
|
659
|
+
|
|
660
|
+
// src/core/container/container.ts
|
|
661
|
+
var Container = class _Container {
|
|
662
|
+
static {
|
|
663
|
+
__name(this, "Container");
|
|
664
|
+
}
|
|
665
|
+
static instance;
|
|
666
|
+
/** Stores singleton instances by token */
|
|
667
|
+
singletons = /* @__PURE__ */ new Map();
|
|
668
|
+
/** Stores provider registrations */
|
|
669
|
+
providers = /* @__PURE__ */ new Map();
|
|
670
|
+
/** Resolution stack for circular dependency detection */
|
|
671
|
+
resolutionStack = /* @__PURE__ */ new Set();
|
|
672
|
+
constructor() {
|
|
673
|
+
}
|
|
674
|
+
/**
|
|
675
|
+
* Get the global container instance
|
|
676
|
+
*/
|
|
677
|
+
static getInstance() {
|
|
678
|
+
if (!_Container.instance) {
|
|
679
|
+
_Container.instance = new _Container();
|
|
680
|
+
}
|
|
681
|
+
return _Container.instance;
|
|
682
|
+
}
|
|
683
|
+
/**
|
|
684
|
+
* Reset the container (useful for testing)
|
|
685
|
+
*/
|
|
686
|
+
static reset() {
|
|
687
|
+
_Container.instance = new _Container();
|
|
688
|
+
}
|
|
689
|
+
/**
|
|
690
|
+
* Register a class provider in the container
|
|
691
|
+
*/
|
|
692
|
+
register(target, options = {}) {
|
|
693
|
+
const scope = options.scope ?? "singleton";
|
|
694
|
+
this.providers.set(target, {
|
|
695
|
+
scope
|
|
696
|
+
});
|
|
697
|
+
}
|
|
698
|
+
/**
|
|
699
|
+
* Register a custom provider (value, factory, class, or existing)
|
|
700
|
+
*/
|
|
701
|
+
registerProvider(provider) {
|
|
702
|
+
if (typeof provider === "function") {
|
|
703
|
+
this.register(provider);
|
|
704
|
+
return;
|
|
705
|
+
}
|
|
706
|
+
const token = provider.provide;
|
|
707
|
+
if ("useValue" in provider) {
|
|
708
|
+
this.providers.set(token, {
|
|
709
|
+
scope: "singleton",
|
|
710
|
+
provider
|
|
711
|
+
});
|
|
712
|
+
this.singletons.set(token, provider.useValue);
|
|
713
|
+
} else if ("useFactory" in provider) {
|
|
714
|
+
this.providers.set(token, {
|
|
715
|
+
scope: "singleton",
|
|
716
|
+
provider
|
|
717
|
+
});
|
|
718
|
+
} else if ("useClass" in provider) {
|
|
719
|
+
this.providers.set(token, {
|
|
720
|
+
scope: "singleton",
|
|
721
|
+
provider
|
|
722
|
+
});
|
|
723
|
+
} else if ("useExisting" in provider) {
|
|
724
|
+
this.providers.set(token, {
|
|
725
|
+
scope: "singleton",
|
|
726
|
+
provider
|
|
727
|
+
});
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
/**
|
|
731
|
+
* Register a value directly
|
|
732
|
+
*/
|
|
733
|
+
registerValue(token, value) {
|
|
734
|
+
this.registerProvider({
|
|
735
|
+
provide: token,
|
|
736
|
+
useValue: value
|
|
737
|
+
});
|
|
738
|
+
}
|
|
739
|
+
/**
|
|
740
|
+
* Register a factory function
|
|
741
|
+
*/
|
|
742
|
+
registerFactory(token, factory, inject) {
|
|
743
|
+
this.registerProvider({
|
|
744
|
+
provide: token,
|
|
745
|
+
useFactory: factory,
|
|
746
|
+
inject
|
|
747
|
+
});
|
|
748
|
+
}
|
|
749
|
+
/**
|
|
750
|
+
* Check if a provider is registered
|
|
751
|
+
*/
|
|
752
|
+
has(token) {
|
|
753
|
+
return this.providers.has(token);
|
|
754
|
+
}
|
|
755
|
+
/**
|
|
756
|
+
* Resolve a dependency by token
|
|
757
|
+
*/
|
|
758
|
+
resolve(token) {
|
|
759
|
+
return this.resolveToken(token, false);
|
|
760
|
+
}
|
|
761
|
+
/**
|
|
762
|
+
* Resolve a dependency, returning undefined if not found (for optional deps)
|
|
763
|
+
*/
|
|
764
|
+
resolveOptional(token) {
|
|
765
|
+
return this.resolveToken(token, true);
|
|
766
|
+
}
|
|
767
|
+
/**
|
|
768
|
+
* Internal resolution logic
|
|
769
|
+
*/
|
|
770
|
+
resolveToken(token, optional) {
|
|
771
|
+
if (this.resolutionStack.has(token)) {
|
|
772
|
+
const chain = [
|
|
773
|
+
...this.resolutionStack
|
|
774
|
+
].map((t) => this.getTokenName(t)).join(" -> ");
|
|
775
|
+
throw new Error(`Circular dependency detected: ${chain} -> ${this.getTokenName(token)}`);
|
|
776
|
+
}
|
|
777
|
+
if (this.singletons.has(token)) {
|
|
778
|
+
return this.singletons.get(token);
|
|
779
|
+
}
|
|
780
|
+
const config = this.providers.get(token);
|
|
781
|
+
if (!config) {
|
|
782
|
+
if (typeof token === "function") {
|
|
783
|
+
const implementation = this.resolveAbstractClass(token);
|
|
784
|
+
if (implementation) {
|
|
785
|
+
const instance = this.resolveClass(implementation);
|
|
786
|
+
this.singletons.set(token, instance);
|
|
787
|
+
return instance;
|
|
788
|
+
}
|
|
789
|
+
if (!isAbstractClass(token)) {
|
|
790
|
+
return this.resolveClass(token);
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
if (optional) {
|
|
794
|
+
return void 0;
|
|
795
|
+
}
|
|
796
|
+
throw new Error(`No provider found for token: ${this.getTokenName(token)}`);
|
|
797
|
+
}
|
|
798
|
+
if (config.provider && typeof config.provider !== "function") {
|
|
799
|
+
return this.resolveProvider(config.provider, config.scope);
|
|
800
|
+
}
|
|
801
|
+
if (typeof token === "function") {
|
|
802
|
+
return this.resolveClass(token);
|
|
803
|
+
}
|
|
804
|
+
throw new Error(`Cannot resolve token: ${this.getTokenName(token)}`);
|
|
805
|
+
}
|
|
806
|
+
/**
|
|
807
|
+
* Try to resolve an abstract class to its concrete implementation.
|
|
808
|
+
*
|
|
809
|
+
* This method contains all the resolution logic for abstract classes:
|
|
810
|
+
* 1. Check for direct provider registration (useClass)
|
|
811
|
+
* 2. If name specified, find the named implementation
|
|
812
|
+
* 3. If only one implementation exists, use it
|
|
813
|
+
* 4. If multiple implementations, use the one marked @Primary
|
|
814
|
+
* 5. If multiple without @Primary, throw an error
|
|
815
|
+
*
|
|
816
|
+
* @param abstractClass - The abstract class to resolve
|
|
817
|
+
* @param name - Optional name for named implementation resolution
|
|
818
|
+
* @returns The concrete implementation class, or undefined if not found
|
|
819
|
+
*/
|
|
820
|
+
resolveAbstractClass(abstractClass, name) {
|
|
821
|
+
const config = this.providers.get(abstractClass);
|
|
822
|
+
if (config?.provider && "useClass" in config.provider) {
|
|
823
|
+
return config.provider.useClass;
|
|
824
|
+
}
|
|
825
|
+
const implementations = registry.getImplementations(abstractClass);
|
|
826
|
+
if (!implementations || implementations.length === 0) {
|
|
827
|
+
return void 0;
|
|
828
|
+
}
|
|
829
|
+
if (name) {
|
|
830
|
+
const named = implementations.find((i) => i.name === name);
|
|
831
|
+
if (named) {
|
|
832
|
+
return named.implementation;
|
|
833
|
+
}
|
|
834
|
+
throw new Error(`No implementation named '${name}' found for abstract class ${abstractClass.name}. Available names: ${implementations.filter((i) => i.name).map((i) => i.name).join(", ") || "none"}`);
|
|
835
|
+
}
|
|
836
|
+
if (implementations.length === 1) {
|
|
837
|
+
return implementations[0].implementation;
|
|
838
|
+
}
|
|
839
|
+
const primary = implementations.find((i) => i.isPrimary);
|
|
840
|
+
if (primary) {
|
|
841
|
+
return primary.implementation;
|
|
842
|
+
}
|
|
843
|
+
const implNames = implementations.map((i) => i.implementation.name).join(", ");
|
|
844
|
+
throw new Error(`Multiple implementations found for abstract class ${abstractClass.name}: ${implNames}. Use @Primary() to mark one as the default, or @Named() for qualified injection.`);
|
|
845
|
+
}
|
|
846
|
+
/**
|
|
847
|
+
* Resolve a custom provider
|
|
848
|
+
*/
|
|
849
|
+
resolveProvider(provider, scope) {
|
|
850
|
+
if (typeof provider === "function") {
|
|
851
|
+
return this.resolveClass(provider);
|
|
852
|
+
}
|
|
853
|
+
const token = provider.provide;
|
|
854
|
+
if ("useValue" in provider) {
|
|
855
|
+
return provider.useValue;
|
|
856
|
+
}
|
|
857
|
+
if ("useFactory" in provider) {
|
|
858
|
+
const factoryProvider = provider;
|
|
859
|
+
const deps = (factoryProvider.inject ?? []).map((dep) => this.resolve(dep));
|
|
860
|
+
const result = factoryProvider.useFactory(...deps);
|
|
861
|
+
if (scope === "singleton") {
|
|
862
|
+
this.singletons.set(token, result);
|
|
863
|
+
}
|
|
864
|
+
return result;
|
|
865
|
+
}
|
|
866
|
+
if ("useClass" in provider) {
|
|
867
|
+
const classProvider = provider;
|
|
868
|
+
const instance = this.resolveClass(classProvider.useClass);
|
|
869
|
+
if (scope === "singleton") {
|
|
870
|
+
this.singletons.set(token, instance);
|
|
871
|
+
}
|
|
872
|
+
return instance;
|
|
873
|
+
}
|
|
874
|
+
if ("useExisting" in provider) {
|
|
875
|
+
return this.resolve(provider.useExisting);
|
|
876
|
+
}
|
|
877
|
+
throw new Error("Invalid provider configuration");
|
|
878
|
+
}
|
|
879
|
+
/**
|
|
880
|
+
* Resolve a class and all its dependencies
|
|
881
|
+
*/
|
|
882
|
+
resolveClass(target) {
|
|
883
|
+
if (this.resolutionStack.has(target)) {
|
|
884
|
+
const chain = [
|
|
885
|
+
...this.resolutionStack,
|
|
886
|
+
target
|
|
887
|
+
].map((t) => this.getTokenName(t)).join(" -> ");
|
|
888
|
+
throw new Error(`Circular dependency detected: ${chain}`);
|
|
889
|
+
}
|
|
890
|
+
const providerConfig = this.providers.get(target);
|
|
891
|
+
const scope = providerConfig?.scope ?? "singleton";
|
|
892
|
+
if (scope === "singleton" && this.singletons.has(target)) {
|
|
893
|
+
return this.singletons.get(target);
|
|
894
|
+
}
|
|
895
|
+
if (scope === "request") {
|
|
896
|
+
if (!requestScopeStorage.isInRequestScope()) {
|
|
897
|
+
throw new Error(`Cannot resolve request-scoped provider '${target.name}' outside of a request context. Request-scoped providers can only be resolved during HTTP request handling.`);
|
|
898
|
+
}
|
|
899
|
+
const existingInstance = requestScopeStorage.get(target);
|
|
900
|
+
if (existingInstance !== void 0) {
|
|
901
|
+
return existingInstance;
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
this.resolutionStack.add(target);
|
|
905
|
+
try {
|
|
906
|
+
const injectMeta = Reflect.getMetadata(INJECT_METADATA, target) ?? [];
|
|
907
|
+
const paramTypes = Reflect.getMetadata("design:paramtypes", target) ?? [];
|
|
908
|
+
const maxIndex = injectMeta.length > 0 ? Math.max(...injectMeta.map((m) => m.index ?? -1)) : -1;
|
|
909
|
+
const paramCount = Math.max(paramTypes.length, maxIndex + 1);
|
|
910
|
+
const dependencies = [];
|
|
911
|
+
for (let index = 0; index < paramCount; index++) {
|
|
912
|
+
const paramType = paramTypes[index];
|
|
913
|
+
const injectOverride = injectMeta.find((m) => m.index === index);
|
|
914
|
+
const token = injectOverride?.token ?? paramType;
|
|
915
|
+
const isOptional = injectOverride?.optional ?? false;
|
|
916
|
+
const name = injectOverride?.name;
|
|
917
|
+
if (!token) {
|
|
918
|
+
if (isOptional) {
|
|
919
|
+
dependencies.push(void 0);
|
|
920
|
+
continue;
|
|
921
|
+
}
|
|
922
|
+
throw new Error(`Cannot resolve constructor parameter ${index} of ${target.name}. Use @Autowired(token) decorator.`);
|
|
923
|
+
}
|
|
924
|
+
if (!injectOverride && this.isPrimitive(paramType)) {
|
|
925
|
+
if (isOptional) {
|
|
926
|
+
dependencies.push(void 0);
|
|
927
|
+
continue;
|
|
928
|
+
}
|
|
929
|
+
throw new Error(`Cannot inject primitive type '${paramType?.name ?? "unknown"}' into ${target.name}. Use @Autowired(token) decorator.`);
|
|
930
|
+
}
|
|
931
|
+
dependencies.push(isOptional ? this.resolveWithNameOptional(token, name) : this.resolveWithName(token, name));
|
|
932
|
+
}
|
|
933
|
+
const instance = new target(...dependencies);
|
|
934
|
+
this.injectProperties(target, instance);
|
|
935
|
+
if (scope === "singleton") {
|
|
936
|
+
this.singletons.set(target, instance);
|
|
937
|
+
} else if (scope === "request") {
|
|
938
|
+
requestScopeStorage.set(target, instance);
|
|
939
|
+
}
|
|
940
|
+
return instance;
|
|
941
|
+
} finally {
|
|
942
|
+
this.resolutionStack.delete(target);
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
/**
|
|
946
|
+
* Inject properties marked with @Autowired()
|
|
947
|
+
*/
|
|
948
|
+
injectProperties(target, instance) {
|
|
949
|
+
const autowireMeta = Reflect.getMetadata(AUTOWIRED_METADATA, target) ?? [];
|
|
950
|
+
for (const meta of autowireMeta) {
|
|
951
|
+
if (!meta.propertyKey) continue;
|
|
952
|
+
const isOptional = meta.optional ?? false;
|
|
953
|
+
try {
|
|
954
|
+
const value = isOptional ? this.resolveWithNameOptional(meta.token, meta.name) : this.resolveWithName(meta.token, meta.name);
|
|
955
|
+
instance[meta.propertyKey] = value;
|
|
956
|
+
} catch (error) {
|
|
957
|
+
if (!isOptional) {
|
|
958
|
+
throw error;
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
/**
|
|
964
|
+
* Resolve a dependency with optional name for qualified injection
|
|
965
|
+
*/
|
|
966
|
+
resolveWithName(token, name) {
|
|
967
|
+
if (name && typeof token === "function") {
|
|
968
|
+
const implementation = this.resolveAbstractClass(token, name);
|
|
969
|
+
if (implementation) {
|
|
970
|
+
return this.resolveClass(implementation);
|
|
971
|
+
}
|
|
972
|
+
throw new Error(`No implementation named '${name}' found for ${this.getTokenName(token)}`);
|
|
973
|
+
}
|
|
974
|
+
return this.resolve(token);
|
|
975
|
+
}
|
|
976
|
+
/**
|
|
977
|
+
* Resolve a dependency with optional name, returning undefined if not found
|
|
978
|
+
*/
|
|
979
|
+
resolveWithNameOptional(token, name) {
|
|
980
|
+
try {
|
|
981
|
+
return this.resolveWithName(token, name);
|
|
982
|
+
} catch {
|
|
983
|
+
return void 0;
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
/**
|
|
987
|
+
* Register an existing instance as a singleton
|
|
988
|
+
*/
|
|
989
|
+
registerInstance(target, instance) {
|
|
990
|
+
this.providers.set(target, {
|
|
991
|
+
scope: "singleton"
|
|
992
|
+
});
|
|
993
|
+
this.singletons.set(target, instance);
|
|
994
|
+
}
|
|
995
|
+
/**
|
|
996
|
+
* Get all registered providers
|
|
997
|
+
*/
|
|
998
|
+
getProviders() {
|
|
999
|
+
return [
|
|
1000
|
+
...this.providers.keys()
|
|
1001
|
+
];
|
|
1002
|
+
}
|
|
1003
|
+
/**
|
|
1004
|
+
* Clear all singletons (useful for testing)
|
|
1005
|
+
*/
|
|
1006
|
+
clearSingletons() {
|
|
1007
|
+
this.singletons.clear();
|
|
1008
|
+
}
|
|
1009
|
+
/**
|
|
1010
|
+
* Check if a type is a primitive (not injectable)
|
|
1011
|
+
*/
|
|
1012
|
+
isPrimitive(type) {
|
|
1013
|
+
if (!type) return true;
|
|
1014
|
+
const primitives = [
|
|
1015
|
+
String,
|
|
1016
|
+
Number,
|
|
1017
|
+
Boolean,
|
|
1018
|
+
Object,
|
|
1019
|
+
Array,
|
|
1020
|
+
Function
|
|
1021
|
+
];
|
|
1022
|
+
return primitives.includes(type);
|
|
1023
|
+
}
|
|
1024
|
+
/**
|
|
1025
|
+
* Get a human-readable name for a token
|
|
1026
|
+
*/
|
|
1027
|
+
getTokenName(token) {
|
|
1028
|
+
if (typeof token === "function") {
|
|
1029
|
+
return token.name;
|
|
1030
|
+
}
|
|
1031
|
+
if (token instanceof InjectionToken) {
|
|
1032
|
+
return token.toString();
|
|
1033
|
+
}
|
|
1034
|
+
if (typeof token === "symbol") {
|
|
1035
|
+
return token.toString();
|
|
1036
|
+
}
|
|
1037
|
+
return String(token);
|
|
1038
|
+
}
|
|
1039
|
+
};
|
|
1040
|
+
var container = Container.getInstance();
|
|
1041
|
+
|
|
1042
|
+
// src/core/container/implements.decorator.ts
|
|
1043
|
+
var import_reflect_metadata2 = require("reflect-metadata");
|
|
1044
|
+
function Implements(abstractClass) {
|
|
1045
|
+
return (target) => {
|
|
1046
|
+
setImplementsMetadata(target, abstractClass);
|
|
1047
|
+
markAsAbstract(abstractClass);
|
|
1048
|
+
const name = Reflect.getMetadata("rikta:named", target);
|
|
1049
|
+
registry.registerAbstractImplementation(abstractClass, target, name);
|
|
1050
|
+
const isPrimary = Reflect.getMetadata("rikta:is-primary", target) === true;
|
|
1051
|
+
if (isPrimary) {
|
|
1052
|
+
registry.setPrimaryImplementation(abstractClass, target);
|
|
1053
|
+
}
|
|
1054
|
+
};
|
|
1055
|
+
}
|
|
1056
|
+
__name(Implements, "Implements");
|
|
1057
|
+
function Primary() {
|
|
1058
|
+
return (target) => {
|
|
1059
|
+
setPrimaryMetadata(target);
|
|
1060
|
+
const abstractClass = Reflect.getMetadata(IMPLEMENTS_METADATA, target);
|
|
1061
|
+
if (abstractClass) {
|
|
1062
|
+
registry.setPrimaryImplementation(abstractClass, target);
|
|
1063
|
+
}
|
|
1064
|
+
Reflect.defineMetadata("rikta:is-primary", true, target);
|
|
1065
|
+
};
|
|
1066
|
+
}
|
|
1067
|
+
__name(Primary, "Primary");
|
|
1068
|
+
function Named(name) {
|
|
1069
|
+
return (target) => {
|
|
1070
|
+
Reflect.defineMetadata("rikta:named", name, target);
|
|
1071
|
+
const abstractClass = Reflect.getMetadata(IMPLEMENTS_METADATA, target);
|
|
1072
|
+
if (abstractClass) {
|
|
1073
|
+
registry.setImplementationName(abstractClass, target, name);
|
|
1074
|
+
}
|
|
1075
|
+
};
|
|
1076
|
+
}
|
|
1077
|
+
__name(Named, "Named");
|
|
1078
|
+
function AbstractClass() {
|
|
1079
|
+
return (target) => {
|
|
1080
|
+
markAsAbstract(target);
|
|
1081
|
+
};
|
|
1082
|
+
}
|
|
1083
|
+
__name(AbstractClass, "AbstractClass");
|
|
1084
|
+
|
|
1085
|
+
// src/core/discovery.ts
|
|
1086
|
+
var import_fast_glob = __toESM(require("fast-glob"), 1);
|
|
1087
|
+
var import_promises = __toESM(require("fs/promises"), 1);
|
|
1088
|
+
var import_path = __toESM(require("path"), 1);
|
|
1089
|
+
|
|
1090
|
+
// src/core/exceptions/discovery.exception.ts
|
|
1091
|
+
var DiscoveryException = class extends Error {
|
|
1092
|
+
static {
|
|
1093
|
+
__name(this, "DiscoveryException");
|
|
1094
|
+
}
|
|
1095
|
+
/**
|
|
1096
|
+
* The file path that failed to import
|
|
1097
|
+
*/
|
|
1098
|
+
filePath;
|
|
1099
|
+
/**
|
|
1100
|
+
* The original error that caused the failure
|
|
1101
|
+
*/
|
|
1102
|
+
originalError;
|
|
1103
|
+
/**
|
|
1104
|
+
* List of all failed imports (for batch reporting)
|
|
1105
|
+
*/
|
|
1106
|
+
failedImports;
|
|
1107
|
+
constructor(filePathOrFailures, originalError) {
|
|
1108
|
+
if (typeof filePathOrFailures === "string") {
|
|
1109
|
+
const filePath = filePathOrFailures;
|
|
1110
|
+
const error = originalError;
|
|
1111
|
+
super(`[Rikta Discovery] Failed to import module: ${filePath}
|
|
1112
|
+
Reason: ${error.message}`);
|
|
1113
|
+
this.filePath = filePath;
|
|
1114
|
+
this.originalError = error;
|
|
1115
|
+
this.failedImports = [
|
|
1116
|
+
{
|
|
1117
|
+
filePath,
|
|
1118
|
+
error
|
|
1119
|
+
}
|
|
1120
|
+
];
|
|
1121
|
+
} else {
|
|
1122
|
+
const failures = filePathOrFailures;
|
|
1123
|
+
const fileList = failures.map((f) => ` - ${f.filePath}: ${f.error.message}`).join("\n");
|
|
1124
|
+
super(`[Rikta Discovery] Failed to import ${failures.length} module(s):
|
|
1125
|
+
${fileList}`);
|
|
1126
|
+
this.filePath = failures[0]?.filePath ?? "";
|
|
1127
|
+
this.originalError = failures[0]?.error ?? new Error("Unknown error");
|
|
1128
|
+
this.failedImports = failures;
|
|
1129
|
+
}
|
|
1130
|
+
this.name = "DiscoveryException";
|
|
1131
|
+
Error.captureStackTrace(this, this.constructor);
|
|
1132
|
+
}
|
|
1133
|
+
/**
|
|
1134
|
+
* Get a formatted report of all failed imports
|
|
1135
|
+
*/
|
|
1136
|
+
getReport() {
|
|
1137
|
+
const lines = [
|
|
1138
|
+
"Discovery Failures:",
|
|
1139
|
+
""
|
|
1140
|
+
];
|
|
1141
|
+
for (const { filePath, error } of this.failedImports) {
|
|
1142
|
+
lines.push(`\u{1F4C1} ${filePath}`);
|
|
1143
|
+
lines.push(` Error: ${error.message}`);
|
|
1144
|
+
if (error.stack) {
|
|
1145
|
+
const stackLines = error.stack.split("\n").slice(1, 4);
|
|
1146
|
+
lines.push(` Stack: ${stackLines.join("\n ")}`);
|
|
1147
|
+
}
|
|
1148
|
+
lines.push("");
|
|
1149
|
+
}
|
|
1150
|
+
return lines.join("\n");
|
|
1151
|
+
}
|
|
1152
|
+
};
|
|
1153
|
+
|
|
1154
|
+
// src/core/discovery.ts
|
|
1155
|
+
var DEFAULT_IGNORE_PATTERNS = [
|
|
1156
|
+
"**/node_modules/**",
|
|
1157
|
+
"**/dist/**",
|
|
1158
|
+
"**/build/**",
|
|
1159
|
+
"**/benchmarks/**",
|
|
1160
|
+
"**/*.test.ts",
|
|
1161
|
+
"**/*.spec.ts",
|
|
1162
|
+
"**/*.d.ts"
|
|
1163
|
+
];
|
|
1164
|
+
function getEntryPointDirectory() {
|
|
1165
|
+
const mainScript = process.argv[1];
|
|
1166
|
+
if (mainScript) {
|
|
1167
|
+
const filePath = mainScript.startsWith("file://") ? new URL(mainScript).pathname : mainScript;
|
|
1168
|
+
return import_path.default.dirname(filePath);
|
|
1169
|
+
}
|
|
1170
|
+
return process.cwd();
|
|
1171
|
+
}
|
|
1172
|
+
__name(getEntryPointDirectory, "getEntryPointDirectory");
|
|
1173
|
+
var DECORATOR_PATTERNS = [
|
|
1174
|
+
// TypeScript source patterns
|
|
1175
|
+
/@Controller\s*\(/,
|
|
1176
|
+
/@Injectable\s*\(/,
|
|
1177
|
+
/@Provider\s*\(/,
|
|
1178
|
+
// Compiled JavaScript CommonJS patterns (e.g., (0, core_1.Controller)('/path'))
|
|
1179
|
+
/\.\s*Controller\s*\)\s*\(/,
|
|
1180
|
+
/\.\s*Injectable\s*\)\s*\(/,
|
|
1181
|
+
/\.\s*Provider\s*\)\s*\(/,
|
|
1182
|
+
/\.\s*ProviderConfig\s*\)\s*\(/,
|
|
1183
|
+
// ESM compiled patterns - import statements with decorators
|
|
1184
|
+
/import\s*{\s*[^}]*\bController\b[^}]*}\s*from\s*['"]@riktajs\/core['"]/,
|
|
1185
|
+
/import\s*{\s*[^}]*\bInjectable\b[^}]*}\s*from\s*['"]@riktajs\/core['"]/,
|
|
1186
|
+
/import\s*{\s*[^}]*\bProvider\b[^}]*}\s*from\s*['"]@riktajs\/core['"]/
|
|
1187
|
+
];
|
|
1188
|
+
async function containsRiktaDecorators(filePath) {
|
|
1189
|
+
try {
|
|
1190
|
+
const content = await import_promises.default.readFile(filePath, "utf-8");
|
|
1191
|
+
return DECORATOR_PATTERNS.some((pattern) => pattern.test(content));
|
|
1192
|
+
} catch {
|
|
1193
|
+
return false;
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
__name(containsRiktaDecorators, "containsRiktaDecorators");
|
|
1197
|
+
async function discoverModules(optionsOrPatterns = [
|
|
1198
|
+
"./**/*.{ts,js}"
|
|
1199
|
+
], cwd) {
|
|
1200
|
+
const options = Array.isArray(optionsOrPatterns) ? {
|
|
1201
|
+
patterns: optionsOrPatterns,
|
|
1202
|
+
cwd
|
|
1203
|
+
} : optionsOrPatterns;
|
|
1204
|
+
const patterns = options.patterns ?? [
|
|
1205
|
+
"./**/*.{ts,js}"
|
|
1206
|
+
];
|
|
1207
|
+
const strict = options.strict ?? false;
|
|
1208
|
+
const onImportError = options.onImportError;
|
|
1209
|
+
const baseDir = options.cwd ?? cwd ?? getEntryPointDirectory();
|
|
1210
|
+
const absoluteBaseDir = import_path.default.isAbsolute(baseDir) ? baseDir : import_path.default.resolve(process.cwd(), baseDir);
|
|
1211
|
+
const normalizedPatterns = patterns.map((pattern) => {
|
|
1212
|
+
let normalizedPattern = pattern;
|
|
1213
|
+
if (import_path.default.isAbsolute(pattern)) {
|
|
1214
|
+
normalizedPattern = import_path.default.relative(absoluteBaseDir, pattern);
|
|
1215
|
+
if (!normalizedPattern.startsWith(".")) {
|
|
1216
|
+
normalizedPattern = "./" + normalizedPattern;
|
|
1217
|
+
}
|
|
1218
|
+
}
|
|
1219
|
+
if (/\.\w+$/.test(normalizedPattern) || normalizedPattern.endsWith("*")) {
|
|
1220
|
+
return normalizedPattern;
|
|
1221
|
+
}
|
|
1222
|
+
return normalizedPattern.endsWith("/") ? `${normalizedPattern}**/*.{ts,js}` : `${normalizedPattern}/**/*.{ts,js}`;
|
|
1223
|
+
});
|
|
1224
|
+
const files = await (0, import_fast_glob.default)(normalizedPatterns, {
|
|
1225
|
+
cwd: absoluteBaseDir,
|
|
1226
|
+
absolute: true,
|
|
1227
|
+
ignore: DEFAULT_IGNORE_PATTERNS,
|
|
1228
|
+
onlyFiles: true
|
|
1229
|
+
});
|
|
1230
|
+
const decoratorChecks = await Promise.all(files.map(async (file) => ({
|
|
1231
|
+
file,
|
|
1232
|
+
hasDecorators: await containsRiktaDecorators(file)
|
|
1233
|
+
})));
|
|
1234
|
+
const riktaFiles = decoratorChecks.filter(({ hasDecorators }) => hasDecorators).map(({ file }) => file);
|
|
1235
|
+
const importedFiles = [];
|
|
1236
|
+
const failedImports = [];
|
|
1237
|
+
for (const file of riktaFiles) {
|
|
1238
|
+
try {
|
|
1239
|
+
let importPath;
|
|
1240
|
+
if (file.endsWith(".js")) {
|
|
1241
|
+
importPath = `file://${file}`;
|
|
1242
|
+
} else {
|
|
1243
|
+
importPath = file.replace(/\.ts$/, "");
|
|
1244
|
+
}
|
|
1245
|
+
await import(importPath);
|
|
1246
|
+
importedFiles.push(file);
|
|
1247
|
+
} catch (err) {
|
|
1248
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
1249
|
+
onImportError?.(file, error);
|
|
1250
|
+
if (process.env.DEBUG) {
|
|
1251
|
+
console.warn(`[Rikta] Failed to import ${file}:`, error.message);
|
|
1252
|
+
}
|
|
1253
|
+
failedImports.push({
|
|
1254
|
+
filePath: file,
|
|
1255
|
+
error
|
|
1256
|
+
});
|
|
1257
|
+
}
|
|
1258
|
+
}
|
|
1259
|
+
if (strict && failedImports.length > 0) {
|
|
1260
|
+
throw new DiscoveryException(failedImports);
|
|
1261
|
+
}
|
|
1262
|
+
return importedFiles;
|
|
1263
|
+
}
|
|
1264
|
+
__name(discoverModules, "discoverModules");
|
|
1265
|
+
function getCallerDirectory() {
|
|
1266
|
+
return getEntryPointDirectory();
|
|
1267
|
+
}
|
|
1268
|
+
__name(getCallerDirectory, "getCallerDirectory");
|
|
1269
|
+
|
|
1270
|
+
// src/core/decorators/injectable.decorator.ts
|
|
1271
|
+
var import_reflect_metadata3 = require("reflect-metadata");
|
|
1272
|
+
function Injectable(options = {}) {
|
|
1273
|
+
return (target) => {
|
|
1274
|
+
Reflect.defineMetadata(INJECTABLE_METADATA, options, target);
|
|
1275
|
+
container.register(target, options);
|
|
1276
|
+
registry.registerProvider(target);
|
|
1277
|
+
};
|
|
1278
|
+
}
|
|
1279
|
+
__name(Injectable, "Injectable");
|
|
1280
|
+
|
|
1281
|
+
// src/core/lifecycle/event-bus.ts
|
|
1282
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
1283
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1284
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1285
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1286
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1287
|
+
}
|
|
1288
|
+
__name(_ts_decorate, "_ts_decorate");
|
|
1289
|
+
var EventBus = class {
|
|
1290
|
+
static {
|
|
1291
|
+
__name(this, "EventBus");
|
|
1292
|
+
}
|
|
1293
|
+
listeners = /* @__PURE__ */ new Map();
|
|
1294
|
+
onceListeners = /* @__PURE__ */ new Map();
|
|
1295
|
+
/** Track unsubscribe functions by owner for cleanup */
|
|
1296
|
+
ownerUnsubscribers = /* @__PURE__ */ new Map();
|
|
1297
|
+
on(event, listener, owner) {
|
|
1298
|
+
if (!this.listeners.has(event)) {
|
|
1299
|
+
this.listeners.set(event, /* @__PURE__ */ new Set());
|
|
1300
|
+
}
|
|
1301
|
+
const tracked = {
|
|
1302
|
+
listener,
|
|
1303
|
+
owner
|
|
1304
|
+
};
|
|
1305
|
+
this.listeners.get(event).add(tracked);
|
|
1306
|
+
const unsubscribe = /* @__PURE__ */ __name(() => {
|
|
1307
|
+
this.listeners.get(event)?.delete(tracked);
|
|
1308
|
+
if (owner) {
|
|
1309
|
+
this.ownerUnsubscribers.get(owner)?.delete(unsubscribe);
|
|
1310
|
+
}
|
|
1311
|
+
}, "unsubscribe");
|
|
1312
|
+
if (owner) {
|
|
1313
|
+
if (!this.ownerUnsubscribers.has(owner)) {
|
|
1314
|
+
this.ownerUnsubscribers.set(owner, /* @__PURE__ */ new Set());
|
|
1315
|
+
}
|
|
1316
|
+
this.ownerUnsubscribers.get(owner).add(unsubscribe);
|
|
1317
|
+
}
|
|
1318
|
+
return unsubscribe;
|
|
1319
|
+
}
|
|
1320
|
+
once(event, listener, owner) {
|
|
1321
|
+
if (!this.onceListeners.has(event)) {
|
|
1322
|
+
this.onceListeners.set(event, /* @__PURE__ */ new Set());
|
|
1323
|
+
}
|
|
1324
|
+
const tracked = {
|
|
1325
|
+
listener,
|
|
1326
|
+
owner
|
|
1327
|
+
};
|
|
1328
|
+
this.onceListeners.get(event).add(tracked);
|
|
1329
|
+
if (owner) {
|
|
1330
|
+
if (!this.ownerUnsubscribers.has(owner)) {
|
|
1331
|
+
this.ownerUnsubscribers.set(owner, /* @__PURE__ */ new Set());
|
|
1332
|
+
}
|
|
1333
|
+
const unsubscribe = /* @__PURE__ */ __name(() => {
|
|
1334
|
+
this.onceListeners.get(event)?.delete(tracked);
|
|
1335
|
+
}, "unsubscribe");
|
|
1336
|
+
this.ownerUnsubscribers.get(owner).add(unsubscribe);
|
|
1337
|
+
}
|
|
1338
|
+
}
|
|
1339
|
+
async emit(event, payload) {
|
|
1340
|
+
const listeners = this.listeners.get(event);
|
|
1341
|
+
if (listeners) {
|
|
1342
|
+
for (const { listener } of listeners) {
|
|
1343
|
+
await listener(payload);
|
|
1344
|
+
}
|
|
1345
|
+
}
|
|
1346
|
+
const onceListeners = this.onceListeners.get(event);
|
|
1347
|
+
if (onceListeners) {
|
|
1348
|
+
for (const { listener } of onceListeners) {
|
|
1349
|
+
await listener(payload);
|
|
1350
|
+
}
|
|
1351
|
+
this.onceListeners.delete(event);
|
|
1352
|
+
}
|
|
1353
|
+
}
|
|
1354
|
+
waitFor(event) {
|
|
1355
|
+
return new Promise((resolve2) => this.once(event, resolve2));
|
|
1356
|
+
}
|
|
1357
|
+
/**
|
|
1358
|
+
* Remove all listeners for an event
|
|
1359
|
+
*/
|
|
1360
|
+
off(event) {
|
|
1361
|
+
this.listeners.delete(event);
|
|
1362
|
+
this.onceListeners.delete(event);
|
|
1363
|
+
}
|
|
1364
|
+
/**
|
|
1365
|
+
* Remove all listeners registered by a specific owner
|
|
1366
|
+
* Useful for cleaning up when a provider is destroyed
|
|
1367
|
+
*
|
|
1368
|
+
* @param owner - The owner identifier (usually class name)
|
|
1369
|
+
*/
|
|
1370
|
+
removeByOwner(owner) {
|
|
1371
|
+
const unsubscribers = this.ownerUnsubscribers.get(owner);
|
|
1372
|
+
if (unsubscribers) {
|
|
1373
|
+
for (const unsubscribe of unsubscribers) {
|
|
1374
|
+
unsubscribe();
|
|
1375
|
+
}
|
|
1376
|
+
this.ownerUnsubscribers.delete(owner);
|
|
1377
|
+
}
|
|
1378
|
+
}
|
|
1379
|
+
/**
|
|
1380
|
+
* Remove all listeners
|
|
1381
|
+
*/
|
|
1382
|
+
clear() {
|
|
1383
|
+
this.listeners.clear();
|
|
1384
|
+
this.onceListeners.clear();
|
|
1385
|
+
this.ownerUnsubscribers.clear();
|
|
1386
|
+
}
|
|
1387
|
+
/**
|
|
1388
|
+
* Get listener count for an event
|
|
1389
|
+
*/
|
|
1390
|
+
listenerCount(event) {
|
|
1391
|
+
return (this.listeners.get(event)?.size ?? 0) + (this.onceListeners.get(event)?.size ?? 0);
|
|
1392
|
+
}
|
|
1393
|
+
/**
|
|
1394
|
+
* Get total listener count across all events
|
|
1395
|
+
* Useful for debugging memory leaks
|
|
1396
|
+
*/
|
|
1397
|
+
totalListenerCount() {
|
|
1398
|
+
let count = 0;
|
|
1399
|
+
for (const listeners of this.listeners.values()) {
|
|
1400
|
+
count += listeners.size;
|
|
1401
|
+
}
|
|
1402
|
+
for (const listeners of this.onceListeners.values()) {
|
|
1403
|
+
count += listeners.size;
|
|
1404
|
+
}
|
|
1405
|
+
return count;
|
|
1406
|
+
}
|
|
1407
|
+
/**
|
|
1408
|
+
* Get listener count by owner
|
|
1409
|
+
* Useful for debugging which providers have the most listeners
|
|
1410
|
+
*/
|
|
1411
|
+
listenerCountByOwner(owner) {
|
|
1412
|
+
return this.ownerUnsubscribers.get(owner)?.size ?? 0;
|
|
1413
|
+
}
|
|
1414
|
+
/**
|
|
1415
|
+
* Get all registered owners
|
|
1416
|
+
*/
|
|
1417
|
+
getOwners() {
|
|
1418
|
+
return [
|
|
1419
|
+
...this.ownerUnsubscribers.keys()
|
|
1420
|
+
];
|
|
1421
|
+
}
|
|
1422
|
+
};
|
|
1423
|
+
EventBus = _ts_decorate([
|
|
1424
|
+
Injectable()
|
|
1425
|
+
], EventBus);
|
|
1426
|
+
|
|
1427
|
+
// src/core/lifecycle/on.decorator.ts
|
|
1428
|
+
var import_reflect_metadata4 = require("reflect-metadata");
|
|
1429
|
+
var ON_EVENT_METADATA = /* @__PURE__ */ Symbol("on:event:metadata");
|
|
1430
|
+
function On(event, options) {
|
|
1431
|
+
return (target, propertyKey) => {
|
|
1432
|
+
const existing = Reflect.getMetadata(ON_EVENT_METADATA, target.constructor) ?? [];
|
|
1433
|
+
existing.push({
|
|
1434
|
+
event,
|
|
1435
|
+
methodName: String(propertyKey),
|
|
1436
|
+
priority: options?.priority ?? 0
|
|
1437
|
+
});
|
|
1438
|
+
Reflect.defineMetadata(ON_EVENT_METADATA, existing, target.constructor);
|
|
1439
|
+
};
|
|
1440
|
+
}
|
|
1441
|
+
__name(On, "On");
|
|
1442
|
+
|
|
1443
|
+
// src/core/router/router.ts
|
|
1444
|
+
var import_reflect_metadata9 = require("reflect-metadata");
|
|
1445
|
+
|
|
1446
|
+
// src/core/decorators/create-param-decorator.ts
|
|
1447
|
+
var import_reflect_metadata5 = require("reflect-metadata");
|
|
1448
|
+
var CUSTOM_PARAM_METADATA = /* @__PURE__ */ Symbol.for("rikta:custom:param:metadata");
|
|
1449
|
+
function createParamDecorator(factory) {
|
|
1450
|
+
return (data) => {
|
|
1451
|
+
return (target, propertyKey, parameterIndex) => {
|
|
1452
|
+
if (propertyKey === void 0) return;
|
|
1453
|
+
const existingParams = Reflect.getMetadata(CUSTOM_PARAM_METADATA, target.constructor, propertyKey) ?? [];
|
|
1454
|
+
const metadata = {
|
|
1455
|
+
index: parameterIndex,
|
|
1456
|
+
factory,
|
|
1457
|
+
data
|
|
1458
|
+
};
|
|
1459
|
+
existingParams.push(metadata);
|
|
1460
|
+
Reflect.defineMetadata(CUSTOM_PARAM_METADATA, existingParams, target.constructor, propertyKey);
|
|
1461
|
+
};
|
|
1462
|
+
};
|
|
1463
|
+
}
|
|
1464
|
+
__name(createParamDecorator, "createParamDecorator");
|
|
1465
|
+
function getCustomParamMetadata(target, propertyKey) {
|
|
1466
|
+
return Reflect.getMetadata(CUSTOM_PARAM_METADATA, target, propertyKey) ?? [];
|
|
1467
|
+
}
|
|
1468
|
+
__name(getCustomParamMetadata, "getCustomParamMetadata");
|
|
1469
|
+
|
|
1470
|
+
// src/core/exceptions/http-exception.ts
|
|
1471
|
+
var HttpException = class extends Error {
|
|
1472
|
+
static {
|
|
1473
|
+
__name(this, "HttpException");
|
|
1474
|
+
}
|
|
1475
|
+
/**
|
|
1476
|
+
* HTTP status code
|
|
1477
|
+
*/
|
|
1478
|
+
statusCode;
|
|
1479
|
+
/**
|
|
1480
|
+
* Error response object
|
|
1481
|
+
*/
|
|
1482
|
+
response;
|
|
1483
|
+
/**
|
|
1484
|
+
* Timestamp when the exception was created
|
|
1485
|
+
*/
|
|
1486
|
+
timestamp;
|
|
1487
|
+
constructor(response, statusCode = 500) {
|
|
1488
|
+
const message = typeof response === "string" ? response : response.message;
|
|
1489
|
+
super(message);
|
|
1490
|
+
this.name = this.constructor.name;
|
|
1491
|
+
this.statusCode = statusCode;
|
|
1492
|
+
this.timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
1493
|
+
if (typeof response === "string") {
|
|
1494
|
+
this.response = {
|
|
1495
|
+
statusCode,
|
|
1496
|
+
message,
|
|
1497
|
+
error: this.getDefaultError(statusCode),
|
|
1498
|
+
timestamp: this.timestamp
|
|
1499
|
+
};
|
|
1500
|
+
} else {
|
|
1501
|
+
this.response = {
|
|
1502
|
+
statusCode,
|
|
1503
|
+
message: response.message,
|
|
1504
|
+
error: response.error ?? this.getDefaultError(statusCode),
|
|
1505
|
+
timestamp: this.timestamp,
|
|
1506
|
+
...response.details ? {
|
|
1507
|
+
details: response.details
|
|
1508
|
+
} : {},
|
|
1509
|
+
...response.code ? {
|
|
1510
|
+
code: response.code
|
|
1511
|
+
} : {}
|
|
1512
|
+
};
|
|
1513
|
+
}
|
|
1514
|
+
Error.captureStackTrace(this, this.constructor);
|
|
1515
|
+
}
|
|
1516
|
+
/**
|
|
1517
|
+
* Get the response object for JSON serialization
|
|
1518
|
+
*/
|
|
1519
|
+
getResponse() {
|
|
1520
|
+
return this.response;
|
|
1521
|
+
}
|
|
1522
|
+
/**
|
|
1523
|
+
* Get the HTTP status code
|
|
1524
|
+
*/
|
|
1525
|
+
getStatus() {
|
|
1526
|
+
return this.statusCode;
|
|
1527
|
+
}
|
|
1528
|
+
/**
|
|
1529
|
+
* Get default error name for status code
|
|
1530
|
+
*/
|
|
1531
|
+
getDefaultError(statusCode) {
|
|
1532
|
+
const errors = {
|
|
1533
|
+
400: "Bad Request",
|
|
1534
|
+
401: "Unauthorized",
|
|
1535
|
+
403: "Forbidden",
|
|
1536
|
+
404: "Not Found",
|
|
1537
|
+
405: "Method Not Allowed",
|
|
1538
|
+
406: "Not Acceptable",
|
|
1539
|
+
408: "Request Timeout",
|
|
1540
|
+
409: "Conflict",
|
|
1541
|
+
410: "Gone",
|
|
1542
|
+
413: "Payload Too Large",
|
|
1543
|
+
415: "Unsupported Media Type",
|
|
1544
|
+
422: "Unprocessable Entity",
|
|
1545
|
+
429: "Too Many Requests",
|
|
1546
|
+
500: "Internal Server Error",
|
|
1547
|
+
501: "Not Implemented",
|
|
1548
|
+
502: "Bad Gateway",
|
|
1549
|
+
503: "Service Unavailable",
|
|
1550
|
+
504: "Gateway Timeout"
|
|
1551
|
+
};
|
|
1552
|
+
return errors[statusCode] ?? "Error";
|
|
1553
|
+
}
|
|
1554
|
+
};
|
|
1555
|
+
|
|
1556
|
+
// src/core/exceptions/validation.exception.ts
|
|
1557
|
+
var ValidationException = class extends HttpException {
|
|
1558
|
+
static {
|
|
1559
|
+
__name(this, "ValidationException");
|
|
1560
|
+
}
|
|
1561
|
+
/**
|
|
1562
|
+
* The original Zod error object
|
|
1563
|
+
*/
|
|
1564
|
+
zodError;
|
|
1565
|
+
/**
|
|
1566
|
+
* Structured validation error details
|
|
1567
|
+
*/
|
|
1568
|
+
errors;
|
|
1569
|
+
constructor(zodError, message = "Validation failed") {
|
|
1570
|
+
const errors = zodError.issues.map((issue) => ({
|
|
1571
|
+
path: issue.path,
|
|
1572
|
+
message: issue.message,
|
|
1573
|
+
code: issue.code,
|
|
1574
|
+
..."expected" in issue ? {
|
|
1575
|
+
expected: String(issue.expected)
|
|
1576
|
+
} : {},
|
|
1577
|
+
..."received" in issue ? {
|
|
1578
|
+
received: String(issue.received)
|
|
1579
|
+
} : {}
|
|
1580
|
+
}));
|
|
1581
|
+
super({
|
|
1582
|
+
message,
|
|
1583
|
+
error: "Validation Error",
|
|
1584
|
+
details: {
|
|
1585
|
+
errors,
|
|
1586
|
+
errorCount: errors.length
|
|
1587
|
+
}
|
|
1588
|
+
}, 400);
|
|
1589
|
+
this.zodError = zodError;
|
|
1590
|
+
this.errors = errors;
|
|
1591
|
+
}
|
|
1592
|
+
/**
|
|
1593
|
+
* Get formatted errors for client response
|
|
1594
|
+
*/
|
|
1595
|
+
getValidationErrors() {
|
|
1596
|
+
return this.errors;
|
|
1597
|
+
}
|
|
1598
|
+
/**
|
|
1599
|
+
* Get the flattened Zod error format
|
|
1600
|
+
*/
|
|
1601
|
+
getFlattenedErrors() {
|
|
1602
|
+
return this.zodError.flatten();
|
|
1603
|
+
}
|
|
1604
|
+
/**
|
|
1605
|
+
* Get the formatted Zod error
|
|
1606
|
+
*/
|
|
1607
|
+
getFormattedErrors() {
|
|
1608
|
+
return this.zodError.format();
|
|
1609
|
+
}
|
|
1610
|
+
};
|
|
1611
|
+
|
|
1612
|
+
// src/core/exceptions/exceptions.ts
|
|
1613
|
+
var BadRequestException = class extends HttpException {
|
|
1614
|
+
static {
|
|
1615
|
+
__name(this, "BadRequestException");
|
|
1616
|
+
}
|
|
1617
|
+
constructor(response = "Bad Request") {
|
|
1618
|
+
super(response, 400);
|
|
1619
|
+
}
|
|
1620
|
+
};
|
|
1621
|
+
var UnauthorizedException = class extends HttpException {
|
|
1622
|
+
static {
|
|
1623
|
+
__name(this, "UnauthorizedException");
|
|
1624
|
+
}
|
|
1625
|
+
constructor(response = "Unauthorized") {
|
|
1626
|
+
super(response, 401);
|
|
1627
|
+
}
|
|
1628
|
+
};
|
|
1629
|
+
var ForbiddenException = class extends HttpException {
|
|
1630
|
+
static {
|
|
1631
|
+
__name(this, "ForbiddenException");
|
|
1632
|
+
}
|
|
1633
|
+
constructor(response = "Forbidden") {
|
|
1634
|
+
super(response, 403);
|
|
1635
|
+
}
|
|
1636
|
+
};
|
|
1637
|
+
var NotFoundException = class extends HttpException {
|
|
1638
|
+
static {
|
|
1639
|
+
__name(this, "NotFoundException");
|
|
1640
|
+
}
|
|
1641
|
+
constructor(response = "Not Found") {
|
|
1642
|
+
super(response, 404);
|
|
1643
|
+
}
|
|
1644
|
+
};
|
|
1645
|
+
var MethodNotAllowedException = class extends HttpException {
|
|
1646
|
+
static {
|
|
1647
|
+
__name(this, "MethodNotAllowedException");
|
|
1648
|
+
}
|
|
1649
|
+
constructor(response = "Method Not Allowed") {
|
|
1650
|
+
super(response, 405);
|
|
1651
|
+
}
|
|
1652
|
+
};
|
|
1653
|
+
var NotAcceptableException = class extends HttpException {
|
|
1654
|
+
static {
|
|
1655
|
+
__name(this, "NotAcceptableException");
|
|
1656
|
+
}
|
|
1657
|
+
constructor(response = "Not Acceptable") {
|
|
1658
|
+
super(response, 406);
|
|
1659
|
+
}
|
|
1660
|
+
};
|
|
1661
|
+
var RequestTimeoutException = class extends HttpException {
|
|
1662
|
+
static {
|
|
1663
|
+
__name(this, "RequestTimeoutException");
|
|
1664
|
+
}
|
|
1665
|
+
constructor(response = "Request Timeout") {
|
|
1666
|
+
super(response, 408);
|
|
1667
|
+
}
|
|
1668
|
+
};
|
|
1669
|
+
var ConflictException = class extends HttpException {
|
|
1670
|
+
static {
|
|
1671
|
+
__name(this, "ConflictException");
|
|
1672
|
+
}
|
|
1673
|
+
constructor(response = "Conflict") {
|
|
1674
|
+
super(response, 409);
|
|
1675
|
+
}
|
|
1676
|
+
};
|
|
1677
|
+
var GoneException = class extends HttpException {
|
|
1678
|
+
static {
|
|
1679
|
+
__name(this, "GoneException");
|
|
1680
|
+
}
|
|
1681
|
+
constructor(response = "Gone") {
|
|
1682
|
+
super(response, 410);
|
|
1683
|
+
}
|
|
1684
|
+
};
|
|
1685
|
+
var PayloadTooLargeException = class extends HttpException {
|
|
1686
|
+
static {
|
|
1687
|
+
__name(this, "PayloadTooLargeException");
|
|
1688
|
+
}
|
|
1689
|
+
constructor(response = "Payload Too Large") {
|
|
1690
|
+
super(response, 413);
|
|
1691
|
+
}
|
|
1692
|
+
};
|
|
1693
|
+
var UnsupportedMediaTypeException = class extends HttpException {
|
|
1694
|
+
static {
|
|
1695
|
+
__name(this, "UnsupportedMediaTypeException");
|
|
1696
|
+
}
|
|
1697
|
+
constructor(response = "Unsupported Media Type") {
|
|
1698
|
+
super(response, 415);
|
|
1699
|
+
}
|
|
1700
|
+
};
|
|
1701
|
+
var UnprocessableEntityException = class extends HttpException {
|
|
1702
|
+
static {
|
|
1703
|
+
__name(this, "UnprocessableEntityException");
|
|
1704
|
+
}
|
|
1705
|
+
constructor(response = "Unprocessable Entity") {
|
|
1706
|
+
super(response, 422);
|
|
1707
|
+
}
|
|
1708
|
+
};
|
|
1709
|
+
var TooManyRequestsException = class extends HttpException {
|
|
1710
|
+
static {
|
|
1711
|
+
__name(this, "TooManyRequestsException");
|
|
1712
|
+
}
|
|
1713
|
+
constructor(response = "Too Many Requests") {
|
|
1714
|
+
super(response, 429);
|
|
1715
|
+
}
|
|
1716
|
+
};
|
|
1717
|
+
var InternalServerErrorException = class extends HttpException {
|
|
1718
|
+
static {
|
|
1719
|
+
__name(this, "InternalServerErrorException");
|
|
1720
|
+
}
|
|
1721
|
+
constructor(response = "Internal Server Error") {
|
|
1722
|
+
super(response, 500);
|
|
1723
|
+
}
|
|
1724
|
+
};
|
|
1725
|
+
var NotImplementedException = class extends HttpException {
|
|
1726
|
+
static {
|
|
1727
|
+
__name(this, "NotImplementedException");
|
|
1728
|
+
}
|
|
1729
|
+
constructor(response = "Not Implemented") {
|
|
1730
|
+
super(response, 501);
|
|
1731
|
+
}
|
|
1732
|
+
};
|
|
1733
|
+
var BadGatewayException = class extends HttpException {
|
|
1734
|
+
static {
|
|
1735
|
+
__name(this, "BadGatewayException");
|
|
1736
|
+
}
|
|
1737
|
+
constructor(response = "Bad Gateway") {
|
|
1738
|
+
super(response, 502);
|
|
1739
|
+
}
|
|
1740
|
+
};
|
|
1741
|
+
var ServiceUnavailableException = class extends HttpException {
|
|
1742
|
+
static {
|
|
1743
|
+
__name(this, "ServiceUnavailableException");
|
|
1744
|
+
}
|
|
1745
|
+
constructor(response = "Service Unavailable") {
|
|
1746
|
+
super(response, 503);
|
|
1747
|
+
}
|
|
1748
|
+
};
|
|
1749
|
+
var GatewayTimeoutException = class extends HttpException {
|
|
1750
|
+
static {
|
|
1751
|
+
__name(this, "GatewayTimeoutException");
|
|
1752
|
+
}
|
|
1753
|
+
constructor(response = "Gateway Timeout") {
|
|
1754
|
+
super(response, 504);
|
|
1755
|
+
}
|
|
1756
|
+
};
|
|
1757
|
+
|
|
1758
|
+
// src/core/guards/execution-context.ts
|
|
1759
|
+
var ExecutionContextImpl = class {
|
|
1760
|
+
static {
|
|
1761
|
+
__name(this, "ExecutionContextImpl");
|
|
1762
|
+
}
|
|
1763
|
+
request;
|
|
1764
|
+
reply;
|
|
1765
|
+
controllerClass;
|
|
1766
|
+
handlerName;
|
|
1767
|
+
httpHost;
|
|
1768
|
+
constructor(request, reply, controllerClass, handlerName) {
|
|
1769
|
+
this.request = request;
|
|
1770
|
+
this.reply = reply;
|
|
1771
|
+
this.controllerClass = controllerClass;
|
|
1772
|
+
this.handlerName = handlerName;
|
|
1773
|
+
this.httpHost = {
|
|
1774
|
+
getRequest: /* @__PURE__ */ __name(() => this.request, "getRequest"),
|
|
1775
|
+
getResponse: /* @__PURE__ */ __name(() => this.reply, "getResponse")
|
|
1776
|
+
};
|
|
1777
|
+
}
|
|
1778
|
+
switchToHttp() {
|
|
1779
|
+
return this.httpHost;
|
|
1780
|
+
}
|
|
1781
|
+
getRequest() {
|
|
1782
|
+
return this.request;
|
|
1783
|
+
}
|
|
1784
|
+
getReply() {
|
|
1785
|
+
return this.reply;
|
|
1786
|
+
}
|
|
1787
|
+
getClass() {
|
|
1788
|
+
return this.controllerClass;
|
|
1789
|
+
}
|
|
1790
|
+
getHandler() {
|
|
1791
|
+
return this.handlerName;
|
|
1792
|
+
}
|
|
1793
|
+
getMetadata(key) {
|
|
1794
|
+
return Reflect.getMetadata(key, this.controllerClass, this.handlerName);
|
|
1795
|
+
}
|
|
1796
|
+
};
|
|
1797
|
+
|
|
1798
|
+
// src/core/guards/use-guards.decorator.ts
|
|
1799
|
+
var import_reflect_metadata6 = require("reflect-metadata");
|
|
1800
|
+
function UseGuards(...guards) {
|
|
1801
|
+
return (target, propertyKey) => {
|
|
1802
|
+
if (propertyKey !== void 0) {
|
|
1803
|
+
const existingGuards = Reflect.getMetadata(GUARDS_METADATA, target.constructor, propertyKey) ?? [];
|
|
1804
|
+
Reflect.defineMetadata(GUARDS_METADATA, [
|
|
1805
|
+
...existingGuards,
|
|
1806
|
+
...guards
|
|
1807
|
+
], target.constructor, propertyKey);
|
|
1808
|
+
} else {
|
|
1809
|
+
const existingGuards = Reflect.getMetadata(GUARDS_METADATA, target) ?? [];
|
|
1810
|
+
Reflect.defineMetadata(GUARDS_METADATA, [
|
|
1811
|
+
...existingGuards,
|
|
1812
|
+
...guards
|
|
1813
|
+
], target);
|
|
1814
|
+
}
|
|
1815
|
+
};
|
|
1816
|
+
}
|
|
1817
|
+
__name(UseGuards, "UseGuards");
|
|
1818
|
+
function getGuardsMetadata(target, propertyKey) {
|
|
1819
|
+
const classGuards = Reflect.getMetadata(GUARDS_METADATA, target) ?? [];
|
|
1820
|
+
if (!propertyKey) {
|
|
1821
|
+
return classGuards;
|
|
1822
|
+
}
|
|
1823
|
+
const methodGuards = Reflect.getMetadata(GUARDS_METADATA, target, propertyKey) ?? [];
|
|
1824
|
+
return [
|
|
1825
|
+
...classGuards,
|
|
1826
|
+
...methodGuards
|
|
1827
|
+
];
|
|
1828
|
+
}
|
|
1829
|
+
__name(getGuardsMetadata, "getGuardsMetadata");
|
|
1830
|
+
|
|
1831
|
+
// src/core/middleware/use-middleware.decorator.ts
|
|
1832
|
+
var import_reflect_metadata7 = require("reflect-metadata");
|
|
1833
|
+
function UseMiddleware(...middleware) {
|
|
1834
|
+
return (target, propertyKey) => {
|
|
1835
|
+
if (propertyKey !== void 0) {
|
|
1836
|
+
const existingMiddleware = Reflect.getMetadata(MIDDLEWARE_METADATA, target.constructor, propertyKey) ?? [];
|
|
1837
|
+
Reflect.defineMetadata(MIDDLEWARE_METADATA, [
|
|
1838
|
+
...existingMiddleware,
|
|
1839
|
+
...middleware
|
|
1840
|
+
], target.constructor, propertyKey);
|
|
1841
|
+
} else {
|
|
1842
|
+
const existingMiddleware = Reflect.getMetadata(MIDDLEWARE_METADATA, target) ?? [];
|
|
1843
|
+
Reflect.defineMetadata(MIDDLEWARE_METADATA, [
|
|
1844
|
+
...existingMiddleware,
|
|
1845
|
+
...middleware
|
|
1846
|
+
], target);
|
|
1847
|
+
}
|
|
1848
|
+
};
|
|
1849
|
+
}
|
|
1850
|
+
__name(UseMiddleware, "UseMiddleware");
|
|
1851
|
+
function getMiddlewareMetadata(target, propertyKey) {
|
|
1852
|
+
const controllerMiddleware = Reflect.getMetadata(MIDDLEWARE_METADATA, target) ?? [];
|
|
1853
|
+
if (!propertyKey) {
|
|
1854
|
+
return controllerMiddleware;
|
|
1855
|
+
}
|
|
1856
|
+
const methodMiddleware = Reflect.getMetadata(MIDDLEWARE_METADATA, target, propertyKey) ?? [];
|
|
1857
|
+
return [
|
|
1858
|
+
...controllerMiddleware,
|
|
1859
|
+
...methodMiddleware
|
|
1860
|
+
];
|
|
1861
|
+
}
|
|
1862
|
+
__name(getMiddlewareMetadata, "getMiddlewareMetadata");
|
|
1863
|
+
|
|
1864
|
+
// src/core/interceptors/use-interceptors.decorator.ts
|
|
1865
|
+
var import_reflect_metadata8 = require("reflect-metadata");
|
|
1866
|
+
function UseInterceptors(...interceptors) {
|
|
1867
|
+
return (target, propertyKey, descriptor) => {
|
|
1868
|
+
if (propertyKey && descriptor) {
|
|
1869
|
+
const existingInterceptors = Reflect.getMetadata(INTERCEPTORS_METADATA, target.constructor, propertyKey) ?? [];
|
|
1870
|
+
Reflect.defineMetadata(INTERCEPTORS_METADATA, [
|
|
1871
|
+
...existingInterceptors,
|
|
1872
|
+
...interceptors
|
|
1873
|
+
], target.constructor, propertyKey);
|
|
1874
|
+
} else {
|
|
1875
|
+
const existingInterceptors = Reflect.getMetadata(INTERCEPTORS_METADATA, target) ?? [];
|
|
1876
|
+
Reflect.defineMetadata(INTERCEPTORS_METADATA, [
|
|
1877
|
+
...existingInterceptors,
|
|
1878
|
+
...interceptors
|
|
1879
|
+
], target);
|
|
1880
|
+
}
|
|
1881
|
+
};
|
|
1882
|
+
}
|
|
1883
|
+
__name(UseInterceptors, "UseInterceptors");
|
|
1884
|
+
function getInterceptorsMetadata(controllerClass, methodName) {
|
|
1885
|
+
const controllerInterceptors = Reflect.getMetadata(INTERCEPTORS_METADATA, controllerClass) ?? [];
|
|
1886
|
+
const methodInterceptors = Reflect.getMetadata(INTERCEPTORS_METADATA, controllerClass, methodName) ?? [];
|
|
1887
|
+
return [
|
|
1888
|
+
...controllerInterceptors,
|
|
1889
|
+
...methodInterceptors
|
|
1890
|
+
];
|
|
1891
|
+
}
|
|
1892
|
+
__name(getInterceptorsMetadata, "getInterceptorsMetadata");
|
|
1893
|
+
|
|
1894
|
+
// src/core/router/router.ts
|
|
1895
|
+
var Router = class {
|
|
1896
|
+
static {
|
|
1897
|
+
__name(this, "Router");
|
|
1898
|
+
}
|
|
1899
|
+
server;
|
|
1900
|
+
container;
|
|
1901
|
+
globalPrefix;
|
|
1902
|
+
/** Cache for guard instances (singleton per guard class) */
|
|
1903
|
+
guardCache = /* @__PURE__ */ new Map();
|
|
1904
|
+
/** Cache for middleware instances (singleton per middleware class) */
|
|
1905
|
+
middlewareCache = /* @__PURE__ */ new Map();
|
|
1906
|
+
/** Cache for interceptor instances (singleton per interceptor class) */
|
|
1907
|
+
interceptorCache = /* @__PURE__ */ new Map();
|
|
1908
|
+
constructor(server, container2, globalPrefix = "") {
|
|
1909
|
+
this.server = server;
|
|
1910
|
+
this.container = container2;
|
|
1911
|
+
this.globalPrefix = globalPrefix;
|
|
1912
|
+
}
|
|
1913
|
+
/**
|
|
1914
|
+
* Clear the guard instance cache
|
|
1915
|
+
* Useful for testing when you need fresh guard instances
|
|
1916
|
+
*/
|
|
1917
|
+
clearGuardCache() {
|
|
1918
|
+
this.guardCache.clear();
|
|
1919
|
+
}
|
|
1920
|
+
/**
|
|
1921
|
+
* Clear the middleware instance cache
|
|
1922
|
+
* Useful for testing when you need fresh middleware instances
|
|
1923
|
+
*/
|
|
1924
|
+
clearMiddlewareCache() {
|
|
1925
|
+
this.middlewareCache.clear();
|
|
1926
|
+
}
|
|
1927
|
+
/**
|
|
1928
|
+
* Clear the interceptor instance cache
|
|
1929
|
+
* Useful for testing when you need fresh interceptor instances
|
|
1930
|
+
*/
|
|
1931
|
+
clearInterceptorCache() {
|
|
1932
|
+
this.interceptorCache.clear();
|
|
1933
|
+
}
|
|
1934
|
+
/**
|
|
1935
|
+
* Clear all caches (guards, middleware, and interceptors)
|
|
1936
|
+
* Useful for testing or hot-reload scenarios
|
|
1937
|
+
*/
|
|
1938
|
+
clearAllCaches() {
|
|
1939
|
+
this.guardCache.clear();
|
|
1940
|
+
this.middlewareCache.clear();
|
|
1941
|
+
this.interceptorCache.clear();
|
|
1942
|
+
}
|
|
1943
|
+
/**
|
|
1944
|
+
* Get the number of cached guard instances
|
|
1945
|
+
*/
|
|
1946
|
+
getGuardCacheSize() {
|
|
1947
|
+
return this.guardCache.size;
|
|
1948
|
+
}
|
|
1949
|
+
/**
|
|
1950
|
+
* Get the number of cached middleware instances
|
|
1951
|
+
*/
|
|
1952
|
+
getMiddlewareCacheSize() {
|
|
1953
|
+
return this.middlewareCache.size;
|
|
1954
|
+
}
|
|
1955
|
+
/**
|
|
1956
|
+
* Get the number of cached interceptor instances
|
|
1957
|
+
*/
|
|
1958
|
+
getInterceptorCacheSize() {
|
|
1959
|
+
return this.interceptorCache.size;
|
|
1960
|
+
}
|
|
1961
|
+
/**
|
|
1962
|
+
* Register all routes from a controller
|
|
1963
|
+
*/
|
|
1964
|
+
registerController(controllerClass, silent = false) {
|
|
1965
|
+
const controllerMeta = Reflect.getMetadata(CONTROLLER_METADATA, controllerClass);
|
|
1966
|
+
if (!controllerMeta) {
|
|
1967
|
+
throw new Error(`${controllerClass.name} is not decorated with @Controller(). Make sure to add the decorator.`);
|
|
1968
|
+
}
|
|
1969
|
+
const controllerInstance = this.container.resolve(controllerClass);
|
|
1970
|
+
const routes = Reflect.getMetadata(ROUTES_METADATA, controllerClass) ?? [];
|
|
1971
|
+
for (const route of routes) {
|
|
1972
|
+
this.registerRoute(controllerClass, controllerInstance, controllerMeta.prefix, route, silent);
|
|
1973
|
+
}
|
|
1974
|
+
}
|
|
1975
|
+
/**
|
|
1976
|
+
* Register a single route
|
|
1977
|
+
*/
|
|
1978
|
+
registerRoute(controllerClass, controllerInstance, controllerPrefix, route, silent = false) {
|
|
1979
|
+
const fullPath = this.buildPath(controllerPrefix, route.path);
|
|
1980
|
+
const handler = controllerInstance[route.handlerName];
|
|
1981
|
+
if (typeof handler !== "function") {
|
|
1982
|
+
throw new Error(`Handler ${String(route.handlerName)} not found on ${controllerClass.name}`);
|
|
1983
|
+
}
|
|
1984
|
+
const paramsMeta = Reflect.getMetadata(PARAM_METADATA, controllerClass, route.handlerName) ?? [];
|
|
1985
|
+
const customParamsMeta = getCustomParamMetadata(controllerClass, route.handlerName);
|
|
1986
|
+
const statusCode = Reflect.getMetadata(HTTP_CODE_METADATA, controllerClass, route.handlerName);
|
|
1987
|
+
const guards = getGuardsMetadata(controllerClass, route.handlerName);
|
|
1988
|
+
const middleware = getMiddlewareMetadata(controllerClass, route.handlerName);
|
|
1989
|
+
const interceptors = getInterceptorsMetadata(controllerClass, route.handlerName);
|
|
1990
|
+
const compiledResolvers = this.compileParamResolvers(paramsMeta);
|
|
1991
|
+
const hasBuiltinParams = compiledResolvers.length > 0;
|
|
1992
|
+
const hasCustomParams = customParamsMeta.length > 0;
|
|
1993
|
+
const hasParams = hasBuiltinParams || hasCustomParams;
|
|
1994
|
+
const allParamIndexes = [
|
|
1995
|
+
...compiledResolvers.map((r) => r.index),
|
|
1996
|
+
...customParamsMeta.map((r) => r.index)
|
|
1997
|
+
];
|
|
1998
|
+
const maxParamIndex = hasParams ? Math.max(...allParamIndexes) : -1;
|
|
1999
|
+
const guardInstances = this.resolveGuardInstances(guards);
|
|
2000
|
+
const hasGuards = guardInstances.length > 0;
|
|
2001
|
+
const middlewareInstances = this.resolveMiddlewareInstances(middleware);
|
|
2002
|
+
const hasMiddleware = middlewareInstances.length > 0;
|
|
2003
|
+
const interceptorInstances = this.resolveInterceptorInstances(interceptors);
|
|
2004
|
+
const hasInterceptors = interceptorInstances.length > 0;
|
|
2005
|
+
const needsContext = hasGuards || hasCustomParams || hasInterceptors;
|
|
2006
|
+
const createContext = needsContext ? (req, rep) => new ExecutionContextImpl(req, rep, controllerClass, route.handlerName) : null;
|
|
2007
|
+
const executeHandler = /* @__PURE__ */ __name(async (request, reply) => {
|
|
2008
|
+
const executionContext = createContext ? createContext(request, reply) : null;
|
|
2009
|
+
if (hasGuards && executionContext) {
|
|
2010
|
+
await this.executeGuardsOptimized(guardInstances, executionContext);
|
|
2011
|
+
}
|
|
2012
|
+
if (hasMiddleware) {
|
|
2013
|
+
await this.executeMiddlewareChain(middlewareInstances, request, reply);
|
|
2014
|
+
}
|
|
2015
|
+
const coreHandler = /* @__PURE__ */ __name(async () => {
|
|
2016
|
+
let args;
|
|
2017
|
+
if (hasParams) {
|
|
2018
|
+
args = await this.resolveAllParams(compiledResolvers, customParamsMeta, maxParamIndex, request, reply, executionContext);
|
|
2019
|
+
}
|
|
2020
|
+
const result2 = args ? await handler.apply(controllerInstance, args) : await handler.call(controllerInstance);
|
|
2021
|
+
return result2;
|
|
2022
|
+
}, "coreHandler");
|
|
2023
|
+
let result;
|
|
2024
|
+
if (hasInterceptors && executionContext) {
|
|
2025
|
+
result = await this.executeInterceptorChain(interceptorInstances, executionContext, coreHandler);
|
|
2026
|
+
} else {
|
|
2027
|
+
result = await coreHandler();
|
|
2028
|
+
}
|
|
2029
|
+
if (statusCode) reply.status(statusCode);
|
|
2030
|
+
return result;
|
|
2031
|
+
}, "executeHandler");
|
|
2032
|
+
const routeHandler = /* @__PURE__ */ __name(async (request, reply) => {
|
|
2033
|
+
return requestScopeStorage.runAsync(() => executeHandler(request, reply));
|
|
2034
|
+
}, "routeHandler");
|
|
2035
|
+
const method = route.method.toLowerCase();
|
|
2036
|
+
this.server[method](fullPath, routeHandler);
|
|
2037
|
+
if (!silent) console.log(` \u2192 ${route.method.padEnd(7)} ${fullPath}`);
|
|
2038
|
+
}
|
|
2039
|
+
/**
|
|
2040
|
+
* OPTIMIZATION: Compile parameter resolvers at route registration time
|
|
2041
|
+
* Each resolver is a pre-built extractor function
|
|
2042
|
+
*/
|
|
2043
|
+
compileParamResolvers(paramsMeta) {
|
|
2044
|
+
if (paramsMeta.length === 0) return [];
|
|
2045
|
+
return paramsMeta.map((param) => {
|
|
2046
|
+
const extractor = this.createParamExtractor(param);
|
|
2047
|
+
return {
|
|
2048
|
+
index: param.index,
|
|
2049
|
+
extract: extractor,
|
|
2050
|
+
zodSchema: param.zodSchema,
|
|
2051
|
+
validationLabel: `${param.type}${param.key ? ` (${param.key})` : ""}`
|
|
2052
|
+
};
|
|
2053
|
+
});
|
|
2054
|
+
}
|
|
2055
|
+
/**
|
|
2056
|
+
* OPTIMIZATION: Create a specialized extractor function for each param type
|
|
2057
|
+
* This avoids switch statements at runtime
|
|
2058
|
+
*/
|
|
2059
|
+
createParamExtractor(param) {
|
|
2060
|
+
const key = param.key;
|
|
2061
|
+
switch (param.type) {
|
|
2062
|
+
case ParamType.BODY:
|
|
2063
|
+
return key ? (ctx) => ctx.body?.[key] : (ctx) => ctx.body;
|
|
2064
|
+
case ParamType.QUERY:
|
|
2065
|
+
return key ? (ctx) => ctx.query[key] : (ctx) => ctx.query;
|
|
2066
|
+
case ParamType.PARAM:
|
|
2067
|
+
return key ? (ctx) => ctx.params[key] : (ctx) => ctx.params;
|
|
2068
|
+
case ParamType.HEADERS:
|
|
2069
|
+
const headerKey = key?.toLowerCase();
|
|
2070
|
+
return headerKey ? (ctx) => ctx.request.headers[headerKey] : (ctx) => ctx.request.headers;
|
|
2071
|
+
case ParamType.REQUEST:
|
|
2072
|
+
return (ctx) => ctx.request;
|
|
2073
|
+
case ParamType.REPLY:
|
|
2074
|
+
return (ctx) => ctx.reply;
|
|
2075
|
+
case ParamType.CONTEXT:
|
|
2076
|
+
return (ctx) => ctx;
|
|
2077
|
+
default:
|
|
2078
|
+
return () => void 0;
|
|
2079
|
+
}
|
|
2080
|
+
}
|
|
2081
|
+
/**
|
|
2082
|
+
* Resolve all parameters including both built-in and custom param decorators
|
|
2083
|
+
*/
|
|
2084
|
+
async resolveAllParams(compiledResolvers, customParams, maxIndex, request, reply, executionContext) {
|
|
2085
|
+
const routeContext = {
|
|
2086
|
+
request,
|
|
2087
|
+
reply,
|
|
2088
|
+
params: request.params,
|
|
2089
|
+
query: request.query,
|
|
2090
|
+
body: request.body
|
|
2091
|
+
};
|
|
2092
|
+
const args = new Array(maxIndex + 1);
|
|
2093
|
+
for (let i = 0; i < compiledResolvers.length; i++) {
|
|
2094
|
+
const resolver = compiledResolvers[i];
|
|
2095
|
+
let value = resolver.extract(routeContext);
|
|
2096
|
+
if (resolver.zodSchema) {
|
|
2097
|
+
const result = resolver.zodSchema.safeParse(value);
|
|
2098
|
+
if (!result.success) {
|
|
2099
|
+
throw new ValidationException(result.error, `Validation failed for ${resolver.validationLabel}`);
|
|
2100
|
+
}
|
|
2101
|
+
value = result.data;
|
|
2102
|
+
}
|
|
2103
|
+
args[resolver.index] = value;
|
|
2104
|
+
}
|
|
2105
|
+
if (customParams.length > 0) {
|
|
2106
|
+
const ctx = executionContext ?? new ExecutionContextImpl(request, reply, {}, "");
|
|
2107
|
+
for (const customParam of customParams) {
|
|
2108
|
+
const value = await customParam.factory(customParam.data, ctx);
|
|
2109
|
+
args[customParam.index] = value;
|
|
2110
|
+
}
|
|
2111
|
+
}
|
|
2112
|
+
return args;
|
|
2113
|
+
}
|
|
2114
|
+
/**
|
|
2115
|
+
* OPTIMIZATION: Pre-resolve guard instances at route registration
|
|
2116
|
+
*/
|
|
2117
|
+
resolveGuardInstances(guards) {
|
|
2118
|
+
return guards.map((GuardClass) => {
|
|
2119
|
+
let instance = this.guardCache.get(GuardClass);
|
|
2120
|
+
if (instance) return instance;
|
|
2121
|
+
try {
|
|
2122
|
+
instance = this.container.resolve(GuardClass);
|
|
2123
|
+
} catch (error) {
|
|
2124
|
+
throw new Error(`Failed to resolve guard ${GuardClass.name}. Make sure it is decorated with @Injectable(). Original error: ${error instanceof Error ? error.message : String(error)}`);
|
|
2125
|
+
}
|
|
2126
|
+
if (typeof instance.canActivate !== "function") {
|
|
2127
|
+
throw new Error(`${GuardClass.name} does not implement CanActivate interface. The guard must have a canActivate(context: ExecutionContext) method.`);
|
|
2128
|
+
}
|
|
2129
|
+
this.guardCache.set(GuardClass, instance);
|
|
2130
|
+
return instance;
|
|
2131
|
+
});
|
|
2132
|
+
}
|
|
2133
|
+
/**
|
|
2134
|
+
* OPTIMIZATION: Execute guards using pre-resolved instances
|
|
2135
|
+
*/
|
|
2136
|
+
async executeGuardsOptimized(guardInstances, context) {
|
|
2137
|
+
for (let i = 0; i < guardInstances.length; i++) {
|
|
2138
|
+
const result = await guardInstances[i].canActivate(context);
|
|
2139
|
+
if (result !== true) {
|
|
2140
|
+
throw new ForbiddenException(`Access denied by guard`);
|
|
2141
|
+
}
|
|
2142
|
+
}
|
|
2143
|
+
}
|
|
2144
|
+
/**
|
|
2145
|
+
* OPTIMIZATION: Pre-resolve middleware instances at route registration
|
|
2146
|
+
*/
|
|
2147
|
+
resolveMiddlewareInstances(middleware) {
|
|
2148
|
+
return middleware.map((MiddlewareClass) => {
|
|
2149
|
+
let instance = this.middlewareCache.get(MiddlewareClass);
|
|
2150
|
+
if (instance) return instance;
|
|
2151
|
+
try {
|
|
2152
|
+
instance = this.container.resolve(MiddlewareClass);
|
|
2153
|
+
} catch (error) {
|
|
2154
|
+
throw new Error(`Failed to resolve middleware ${MiddlewareClass.name}. Make sure it is decorated with @Injectable(). Original error: ${error instanceof Error ? error.message : String(error)}`);
|
|
2155
|
+
}
|
|
2156
|
+
if (typeof instance.use !== "function") {
|
|
2157
|
+
throw new Error(`${MiddlewareClass.name} does not implement RiktaMiddleware interface. The middleware must have a use(req, res, next) method.`);
|
|
2158
|
+
}
|
|
2159
|
+
this.middlewareCache.set(MiddlewareClass, instance);
|
|
2160
|
+
return instance;
|
|
2161
|
+
});
|
|
2162
|
+
}
|
|
2163
|
+
/**
|
|
2164
|
+
* Execute middleware chain in order
|
|
2165
|
+
* Each middleware must call next() to continue
|
|
2166
|
+
*/
|
|
2167
|
+
async executeMiddlewareChain(middlewareInstances, request, reply) {
|
|
2168
|
+
let index = 0;
|
|
2169
|
+
const next = /* @__PURE__ */ __name(async () => {
|
|
2170
|
+
if (index < middlewareInstances.length) {
|
|
2171
|
+
const middleware = middlewareInstances[index++];
|
|
2172
|
+
await middleware.use(request, reply, next);
|
|
2173
|
+
}
|
|
2174
|
+
}, "next");
|
|
2175
|
+
await next();
|
|
2176
|
+
}
|
|
2177
|
+
/**
|
|
2178
|
+
* OPTIMIZATION: Pre-resolve interceptor instances at route registration
|
|
2179
|
+
*/
|
|
2180
|
+
resolveInterceptorInstances(interceptors) {
|
|
2181
|
+
return interceptors.map((InterceptorClass) => {
|
|
2182
|
+
let instance = this.interceptorCache.get(InterceptorClass);
|
|
2183
|
+
if (instance) return instance;
|
|
2184
|
+
try {
|
|
2185
|
+
instance = this.container.resolve(InterceptorClass);
|
|
2186
|
+
} catch (error) {
|
|
2187
|
+
throw new Error(`Failed to resolve interceptor ${InterceptorClass.name}. Make sure it is decorated with @Injectable(). Original error: ${error instanceof Error ? error.message : String(error)}`);
|
|
2188
|
+
}
|
|
2189
|
+
if (typeof instance.intercept !== "function") {
|
|
2190
|
+
throw new Error(`${InterceptorClass.name} does not implement Interceptor interface. The interceptor must have an intercept(context, next) method.`);
|
|
2191
|
+
}
|
|
2192
|
+
this.interceptorCache.set(InterceptorClass, instance);
|
|
2193
|
+
return instance;
|
|
2194
|
+
});
|
|
2195
|
+
}
|
|
2196
|
+
/**
|
|
2197
|
+
* Execute interceptor chain
|
|
2198
|
+
* Each interceptor wraps around the next, creating an onion-like execution
|
|
2199
|
+
*/
|
|
2200
|
+
async executeInterceptorChain(interceptorInstances, context, coreHandler) {
|
|
2201
|
+
let handler = coreHandler;
|
|
2202
|
+
for (let i = interceptorInstances.length - 1; i >= 0; i--) {
|
|
2203
|
+
const interceptor = interceptorInstances[i];
|
|
2204
|
+
const nextHandler = handler;
|
|
2205
|
+
handler = /* @__PURE__ */ __name(() => {
|
|
2206
|
+
const callHandler = {
|
|
2207
|
+
handle: /* @__PURE__ */ __name(() => nextHandler(), "handle")
|
|
2208
|
+
};
|
|
2209
|
+
return interceptor.intercept(context, callHandler);
|
|
2210
|
+
}, "handler");
|
|
2211
|
+
}
|
|
2212
|
+
return handler();
|
|
2213
|
+
}
|
|
2214
|
+
/**
|
|
2215
|
+
* Build the full route path
|
|
2216
|
+
*/
|
|
2217
|
+
buildPath(controllerPrefix, routePath) {
|
|
2218
|
+
const parts = [
|
|
2219
|
+
this.globalPrefix,
|
|
2220
|
+
controllerPrefix,
|
|
2221
|
+
routePath
|
|
2222
|
+
].filter(Boolean).join("");
|
|
2223
|
+
return parts.replace(/\/+/g, "/") || "/";
|
|
2224
|
+
}
|
|
2225
|
+
};
|
|
2226
|
+
|
|
2227
|
+
// src/core/application.ts
|
|
2228
|
+
var import_reflect_metadata11 = require("reflect-metadata");
|
|
2229
|
+
var import_fastify = __toESM(require("fastify"), 1);
|
|
2230
|
+
|
|
2231
|
+
// src/core/exceptions/exception-filter.ts
|
|
2232
|
+
var GlobalExceptionFilter = class {
|
|
2233
|
+
static {
|
|
2234
|
+
__name(this, "GlobalExceptionFilter");
|
|
2235
|
+
}
|
|
2236
|
+
includeStack;
|
|
2237
|
+
logErrors;
|
|
2238
|
+
constructor(options = {}) {
|
|
2239
|
+
this.includeStack = options.includeStack ?? process.env.NODE_ENV !== "production";
|
|
2240
|
+
this.logErrors = options.logErrors ?? true;
|
|
2241
|
+
}
|
|
2242
|
+
/**
|
|
2243
|
+
* Handle any exception and send standardized response
|
|
2244
|
+
*/
|
|
2245
|
+
catch(exception, context) {
|
|
2246
|
+
const { request, reply, path: path2, method } = context;
|
|
2247
|
+
const requestId = request.id ?? void 0;
|
|
2248
|
+
if (this.logErrors) {
|
|
2249
|
+
this.logError(exception, method, path2, requestId);
|
|
2250
|
+
}
|
|
2251
|
+
const response = this.buildResponse(exception, path2, requestId);
|
|
2252
|
+
reply.status(response.statusCode).send(response);
|
|
2253
|
+
}
|
|
2254
|
+
/**
|
|
2255
|
+
* Build standardized error response
|
|
2256
|
+
*/
|
|
2257
|
+
buildResponse(exception, path2, requestId) {
|
|
2258
|
+
if (exception instanceof HttpException) {
|
|
2259
|
+
const httpResponse = exception.getResponse();
|
|
2260
|
+
return {
|
|
2261
|
+
statusCode: httpResponse.statusCode,
|
|
2262
|
+
message: httpResponse.message,
|
|
2263
|
+
error: httpResponse.error,
|
|
2264
|
+
timestamp: httpResponse.timestamp,
|
|
2265
|
+
path: path2,
|
|
2266
|
+
...requestId ? {
|
|
2267
|
+
requestId
|
|
2268
|
+
} : {},
|
|
2269
|
+
...httpResponse.details ? {
|
|
2270
|
+
details: httpResponse.details
|
|
2271
|
+
} : {},
|
|
2272
|
+
...httpResponse.code ? {
|
|
2273
|
+
code: httpResponse.code
|
|
2274
|
+
} : {},
|
|
2275
|
+
...this.includeStack ? {
|
|
2276
|
+
stack: exception.stack
|
|
2277
|
+
} : {}
|
|
2278
|
+
};
|
|
2279
|
+
}
|
|
2280
|
+
if (this.isFastifyValidationError(exception)) {
|
|
2281
|
+
return {
|
|
2282
|
+
statusCode: 400,
|
|
2283
|
+
message: "Validation failed",
|
|
2284
|
+
error: "Bad Request",
|
|
2285
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2286
|
+
path: path2,
|
|
2287
|
+
...requestId && {
|
|
2288
|
+
requestId
|
|
2289
|
+
},
|
|
2290
|
+
details: exception.validation,
|
|
2291
|
+
...this.includeStack && {
|
|
2292
|
+
stack: exception.stack
|
|
2293
|
+
}
|
|
2294
|
+
};
|
|
2295
|
+
}
|
|
2296
|
+
if (this.isFastifyError(exception)) {
|
|
2297
|
+
const fastifyError = exception;
|
|
2298
|
+
return {
|
|
2299
|
+
statusCode: fastifyError.statusCode ?? 500,
|
|
2300
|
+
message: fastifyError.message,
|
|
2301
|
+
error: fastifyError.code ?? "Error",
|
|
2302
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2303
|
+
path: path2,
|
|
2304
|
+
...requestId && {
|
|
2305
|
+
requestId
|
|
2306
|
+
},
|
|
2307
|
+
...this.includeStack && {
|
|
2308
|
+
stack: exception.stack
|
|
2309
|
+
}
|
|
2310
|
+
};
|
|
2311
|
+
}
|
|
2312
|
+
return {
|
|
2313
|
+
statusCode: 500,
|
|
2314
|
+
message: this.includeStack ? exception.message : "Internal Server Error",
|
|
2315
|
+
error: "Internal Server Error",
|
|
2316
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2317
|
+
path: path2,
|
|
2318
|
+
...requestId && {
|
|
2319
|
+
requestId
|
|
2320
|
+
},
|
|
2321
|
+
...this.includeStack && {
|
|
2322
|
+
stack: exception.stack
|
|
2323
|
+
}
|
|
2324
|
+
};
|
|
2325
|
+
}
|
|
2326
|
+
/**
|
|
2327
|
+
* Check if error is a Fastify validation error
|
|
2328
|
+
*/
|
|
2329
|
+
isFastifyValidationError(error) {
|
|
2330
|
+
return "validation" in error && Array.isArray(error.validation);
|
|
2331
|
+
}
|
|
2332
|
+
/**
|
|
2333
|
+
* Check if error is a Fastify error with statusCode
|
|
2334
|
+
*/
|
|
2335
|
+
isFastifyError(error) {
|
|
2336
|
+
return "statusCode" in error;
|
|
2337
|
+
}
|
|
2338
|
+
/**
|
|
2339
|
+
* Log error to console
|
|
2340
|
+
*/
|
|
2341
|
+
logError(exception, method, path2, requestId) {
|
|
2342
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
2343
|
+
const status = exception instanceof HttpException ? exception.getStatus() : 500;
|
|
2344
|
+
const prefix = status >= 500 ? "\u274C" : "\u26A0\uFE0F";
|
|
2345
|
+
const reqIdStr = requestId ? ` [${requestId}]` : "";
|
|
2346
|
+
console.error(`${prefix} [${timestamp}]${reqIdStr} ${method} ${path2} - ${status} ${exception.message}`);
|
|
2347
|
+
if (status >= 500 && this.includeStack && exception.stack) {
|
|
2348
|
+
console.error(exception.stack);
|
|
2349
|
+
}
|
|
2350
|
+
}
|
|
2351
|
+
};
|
|
2352
|
+
function createExceptionHandler(filter, customFilters = /* @__PURE__ */ new Map()) {
|
|
2353
|
+
return async (error, request, reply) => {
|
|
2354
|
+
const context = {
|
|
2355
|
+
exception: error,
|
|
2356
|
+
request,
|
|
2357
|
+
reply,
|
|
2358
|
+
path: request.url,
|
|
2359
|
+
method: request.method,
|
|
2360
|
+
requestId: request.id
|
|
2361
|
+
};
|
|
2362
|
+
for (const [ExceptionType, customFilter] of customFilters) {
|
|
2363
|
+
if (error instanceof ExceptionType) {
|
|
2364
|
+
return customFilter.catch(error, context);
|
|
2365
|
+
}
|
|
2366
|
+
}
|
|
2367
|
+
return filter.catch(error, context);
|
|
2368
|
+
};
|
|
2369
|
+
}
|
|
2370
|
+
__name(createExceptionHandler, "createExceptionHandler");
|
|
2371
|
+
|
|
2372
|
+
// src/core/exceptions/catch.decorator.ts
|
|
2373
|
+
var import_reflect_metadata10 = require("reflect-metadata");
|
|
2374
|
+
var CATCH_METADATA = /* @__PURE__ */ Symbol("catch:metadata");
|
|
2375
|
+
function Catch(...exceptions) {
|
|
2376
|
+
return (target) => {
|
|
2377
|
+
const metadata = {
|
|
2378
|
+
exceptions: exceptions.length > 0 ? exceptions : []
|
|
2379
|
+
};
|
|
2380
|
+
Reflect.defineMetadata(CATCH_METADATA, metadata, target);
|
|
2381
|
+
};
|
|
2382
|
+
}
|
|
2383
|
+
__name(Catch, "Catch");
|
|
2384
|
+
function getCatchMetadata(target) {
|
|
2385
|
+
return Reflect.getMetadata(CATCH_METADATA, target);
|
|
2386
|
+
}
|
|
2387
|
+
__name(getCatchMetadata, "getCatchMetadata");
|
|
2388
|
+
|
|
2389
|
+
// src/core/config/env-loader.ts
|
|
2390
|
+
var import_dotenv = require("dotenv");
|
|
2391
|
+
var import_fs = require("fs");
|
|
2392
|
+
var import_path2 = require("path");
|
|
2393
|
+
var envLoaded = false;
|
|
2394
|
+
function loadEnvFiles() {
|
|
2395
|
+
if (envLoaded) {
|
|
2396
|
+
return;
|
|
2397
|
+
}
|
|
2398
|
+
const env = process.env.NODE_ENV || "development";
|
|
2399
|
+
const cwd = process.cwd();
|
|
2400
|
+
const baseEnvPath = (0, import_path2.resolve)(cwd, ".env");
|
|
2401
|
+
if ((0, import_fs.existsSync)(baseEnvPath)) {
|
|
2402
|
+
(0, import_dotenv.config)({
|
|
2403
|
+
path: baseEnvPath,
|
|
2404
|
+
override: false
|
|
2405
|
+
});
|
|
2406
|
+
}
|
|
2407
|
+
const envSpecificPath = (0, import_path2.resolve)(cwd, `.env.${env}`);
|
|
2408
|
+
if ((0, import_fs.existsSync)(envSpecificPath)) {
|
|
2409
|
+
(0, import_dotenv.config)({
|
|
2410
|
+
path: envSpecificPath,
|
|
2411
|
+
override: true
|
|
2412
|
+
});
|
|
2413
|
+
}
|
|
2414
|
+
envLoaded = true;
|
|
2415
|
+
}
|
|
2416
|
+
__name(loadEnvFiles, "loadEnvFiles");
|
|
2417
|
+
function isEnvLoaded() {
|
|
2418
|
+
return envLoaded;
|
|
2419
|
+
}
|
|
2420
|
+
__name(isEnvLoaded, "isEnvLoaded");
|
|
2421
|
+
function resetEnvLoaded() {
|
|
2422
|
+
envLoaded = false;
|
|
2423
|
+
}
|
|
2424
|
+
__name(resetEnvLoaded, "resetEnvLoaded");
|
|
2425
|
+
|
|
2426
|
+
// src/core/application.ts
|
|
2427
|
+
var RiktaFactory = class {
|
|
2428
|
+
static {
|
|
2429
|
+
__name(this, "RiktaFactory");
|
|
2430
|
+
}
|
|
2431
|
+
/**
|
|
2432
|
+
* Create and bootstrap the application
|
|
2433
|
+
*
|
|
2434
|
+
* .env files are loaded automatically before any initialization,
|
|
2435
|
+
* making environment variables available immediately.
|
|
2436
|
+
*
|
|
2437
|
+
* @example
|
|
2438
|
+
* ```typescript
|
|
2439
|
+
* // Auto-discovery from current directory (default)
|
|
2440
|
+
* // process.env variables are available immediately after this line
|
|
2441
|
+
* const app = await Rikta.create({ port: 3000 });
|
|
2442
|
+
*
|
|
2443
|
+
* // Auto-discovery from specific paths
|
|
2444
|
+
* const app = await Rikta.create({
|
|
2445
|
+
* autowired: ['./src/controllers', './src/services'],
|
|
2446
|
+
* port: 3000
|
|
2447
|
+
* });
|
|
2448
|
+
* ```
|
|
2449
|
+
*/
|
|
2450
|
+
static async create(config = {}) {
|
|
2451
|
+
loadEnvFiles();
|
|
2452
|
+
const silent = config.silent ?? false;
|
|
2453
|
+
if (!silent) console.log("\n\u{1F680} Rikta Framework Starting...\n");
|
|
2454
|
+
const callerDir = getCallerDirectory();
|
|
2455
|
+
let discoveredFiles = [];
|
|
2456
|
+
if (!config.controllers && config.autowired !== false) {
|
|
2457
|
+
const patterns = Array.isArray(config.autowired) && config.autowired.length > 0 ? config.autowired : [
|
|
2458
|
+
"./**"
|
|
2459
|
+
];
|
|
2460
|
+
discoveredFiles = await discoverModules({
|
|
2461
|
+
patterns,
|
|
2462
|
+
cwd: callerDir,
|
|
2463
|
+
strict: config.strictDiscovery ?? false,
|
|
2464
|
+
onImportError: config.onDiscoveryError
|
|
2465
|
+
});
|
|
2466
|
+
}
|
|
2467
|
+
const app = new RiktaApplicationImpl(config);
|
|
2468
|
+
await app.init(discoveredFiles);
|
|
2469
|
+
return app;
|
|
2470
|
+
}
|
|
2471
|
+
};
|
|
2472
|
+
var RiktaApplicationImpl = class RiktaApplicationImpl2 {
|
|
2473
|
+
static {
|
|
2474
|
+
__name(this, "RiktaApplicationImpl");
|
|
2475
|
+
}
|
|
2476
|
+
server;
|
|
2477
|
+
container;
|
|
2478
|
+
config;
|
|
2479
|
+
router;
|
|
2480
|
+
events;
|
|
2481
|
+
initializedProviders = [];
|
|
2482
|
+
customExceptionFilters = /* @__PURE__ */ new Map();
|
|
2483
|
+
startTime = Date.now();
|
|
2484
|
+
isListening = false;
|
|
2485
|
+
address = "";
|
|
2486
|
+
constructor(config) {
|
|
2487
|
+
const silent = config.silent ?? false;
|
|
2488
|
+
this.config = {
|
|
2489
|
+
port: config.port ?? DEFAULT_CONFIG.port,
|
|
2490
|
+
host: config.host ?? DEFAULT_CONFIG.host,
|
|
2491
|
+
// If silent mode, disable logger unless explicitly set
|
|
2492
|
+
logger: config.logger ?? (silent ? false : DEFAULT_CONFIG.logger),
|
|
2493
|
+
prefix: config.prefix ?? DEFAULT_CONFIG.prefix,
|
|
2494
|
+
silent,
|
|
2495
|
+
controllers: config.controllers,
|
|
2496
|
+
providers: config.providers,
|
|
2497
|
+
exceptionFilter: config.exceptionFilter,
|
|
2498
|
+
exceptionFilters: config.exceptionFilters
|
|
2499
|
+
};
|
|
2500
|
+
this.server = (0, import_fastify.default)({
|
|
2501
|
+
logger: this.config.logger
|
|
2502
|
+
});
|
|
2503
|
+
this.container = Container.getInstance();
|
|
2504
|
+
this.router = new Router(this.server, this.container, this.config.prefix);
|
|
2505
|
+
this.events = new EventBus();
|
|
2506
|
+
this.container.registerInstance(EventBus, this.events);
|
|
2507
|
+
this.setupExceptionHandler();
|
|
2508
|
+
}
|
|
2509
|
+
/**
|
|
2510
|
+
* Setup global exception handler
|
|
2511
|
+
*/
|
|
2512
|
+
setupExceptionHandler() {
|
|
2513
|
+
const silent = this.config.silent ?? false;
|
|
2514
|
+
const globalFilter = new GlobalExceptionFilter({
|
|
2515
|
+
includeStack: this.config.exceptionFilter?.includeStack,
|
|
2516
|
+
logErrors: this.config.exceptionFilter?.logErrors ?? (silent ? false : true)
|
|
2517
|
+
});
|
|
2518
|
+
const customFilters = this.config.exceptionFilters ?? [];
|
|
2519
|
+
for (const FilterClass of customFilters) {
|
|
2520
|
+
const metadata = getCatchMetadata(FilterClass);
|
|
2521
|
+
const filterInstance = this.container.resolve(FilterClass);
|
|
2522
|
+
if (metadata && metadata.exceptions.length > 0) {
|
|
2523
|
+
for (const ExceptionType of metadata.exceptions) {
|
|
2524
|
+
this.customExceptionFilters.set(ExceptionType, filterInstance);
|
|
2525
|
+
}
|
|
2526
|
+
} else {
|
|
2527
|
+
this.customExceptionFilters.set(Error, filterInstance);
|
|
2528
|
+
}
|
|
2529
|
+
}
|
|
2530
|
+
this.server.setErrorHandler(createExceptionHandler(globalFilter, this.customExceptionFilters));
|
|
2531
|
+
}
|
|
2532
|
+
/**
|
|
2533
|
+
* Initialize the application
|
|
2534
|
+
*/
|
|
2535
|
+
async init(discoveredFiles = []) {
|
|
2536
|
+
await this.events.emit("app:discovery", {
|
|
2537
|
+
files: discoveredFiles
|
|
2538
|
+
});
|
|
2539
|
+
await this.processConfigProviders();
|
|
2540
|
+
await this.processCustomProviders();
|
|
2541
|
+
await this.events.emit("app:providers", {
|
|
2542
|
+
count: registry.getCustomProviders().length
|
|
2543
|
+
});
|
|
2544
|
+
const providers = this.getSortedProviders();
|
|
2545
|
+
const additionalProviders = this.config.providers ?? [];
|
|
2546
|
+
for (const provider of additionalProviders) {
|
|
2547
|
+
this.registerProvider(provider);
|
|
2548
|
+
}
|
|
2549
|
+
for (const { target, priority } of providers) {
|
|
2550
|
+
await this.initializeProvider(target, priority);
|
|
2551
|
+
}
|
|
2552
|
+
const controllers = this.config.controllers ?? registry.getControllers();
|
|
2553
|
+
if (!this.config.silent) console.log("\u{1F4E1} Registering routes:");
|
|
2554
|
+
for (const controller of controllers) {
|
|
2555
|
+
this.router.registerController(controller, this.config.silent);
|
|
2556
|
+
}
|
|
2557
|
+
await this.events.emit("app:routes", {
|
|
2558
|
+
count: controllers.length
|
|
2559
|
+
});
|
|
2560
|
+
await this.callHook("onApplicationBootstrap");
|
|
2561
|
+
await this.events.emit("app:bootstrap", {
|
|
2562
|
+
providerCount: this.initializedProviders.length
|
|
2563
|
+
});
|
|
2564
|
+
if (!this.config.silent) console.log("\n\u2705 Rikta is ready\n");
|
|
2565
|
+
}
|
|
2566
|
+
/**
|
|
2567
|
+
* Process all config providers and register them in the container
|
|
2568
|
+
*/
|
|
2569
|
+
async processConfigProviders() {
|
|
2570
|
+
const configProviders = registry.getConfigProviderRegistrations();
|
|
2571
|
+
if (configProviders.length === 0) return;
|
|
2572
|
+
for (const { token, providerClass } of configProviders) {
|
|
2573
|
+
this.container.registerProvider({
|
|
2574
|
+
provide: token,
|
|
2575
|
+
useClass: providerClass
|
|
2576
|
+
});
|
|
2577
|
+
}
|
|
2578
|
+
}
|
|
2579
|
+
/**
|
|
2580
|
+
* Process all @Provider decorated classes
|
|
2581
|
+
*/
|
|
2582
|
+
async processCustomProviders() {
|
|
2583
|
+
const customProviders = registry.getCustomProviders();
|
|
2584
|
+
if (customProviders.length === 0) return;
|
|
2585
|
+
for (const ProviderClass of customProviders) {
|
|
2586
|
+
const metadata = Reflect.getMetadata(PROVIDER_METADATA, ProviderClass);
|
|
2587
|
+
if (!metadata) continue;
|
|
2588
|
+
const providerInstance = this.container.resolve(ProviderClass);
|
|
2589
|
+
const value = await providerInstance.provide();
|
|
2590
|
+
this.container.registerValue(metadata.token, value);
|
|
2591
|
+
}
|
|
2592
|
+
}
|
|
2593
|
+
/**
|
|
2594
|
+
* Get providers sorted by priority (higher = first)
|
|
2595
|
+
*/
|
|
2596
|
+
getSortedProviders() {
|
|
2597
|
+
const providers = registry.getProviders();
|
|
2598
|
+
return providers.map((target) => ({
|
|
2599
|
+
target,
|
|
2600
|
+
priority: this.getProviderPriority(target)
|
|
2601
|
+
})).sort((a, b) => b.priority - a.priority);
|
|
2602
|
+
}
|
|
2603
|
+
/**
|
|
2604
|
+
* Get priority from @Injectable() metadata
|
|
2605
|
+
*/
|
|
2606
|
+
getProviderPriority(target) {
|
|
2607
|
+
const options = Reflect.getMetadata(INJECTABLE_METADATA, target);
|
|
2608
|
+
return options?.priority ?? 0;
|
|
2609
|
+
}
|
|
2610
|
+
/**
|
|
2611
|
+
* Initialize a single provider
|
|
2612
|
+
*/
|
|
2613
|
+
async initializeProvider(target, priority) {
|
|
2614
|
+
const instance = this.container.resolve(target);
|
|
2615
|
+
const name = target.name;
|
|
2616
|
+
this.initializedProviders.push({
|
|
2617
|
+
instance,
|
|
2618
|
+
priority,
|
|
2619
|
+
name
|
|
2620
|
+
});
|
|
2621
|
+
if (this.hasHook(instance, "onProviderInit")) {
|
|
2622
|
+
await instance.onProviderInit();
|
|
2623
|
+
}
|
|
2624
|
+
await this.events.emit("provider:init", {
|
|
2625
|
+
provider: target,
|
|
2626
|
+
name,
|
|
2627
|
+
priority
|
|
2628
|
+
});
|
|
2629
|
+
this.registerEventListeners(target, instance);
|
|
2630
|
+
}
|
|
2631
|
+
/**
|
|
2632
|
+
* Register @On() decorated methods as event listeners
|
|
2633
|
+
* Tracks listeners by provider name for cleanup during shutdown
|
|
2634
|
+
*/
|
|
2635
|
+
registerEventListeners(target, instance) {
|
|
2636
|
+
const metadata = Reflect.getMetadata(ON_EVENT_METADATA, target) ?? [];
|
|
2637
|
+
for (const { event, methodName } of metadata) {
|
|
2638
|
+
const method = instance[methodName];
|
|
2639
|
+
if (typeof method === "function") {
|
|
2640
|
+
this.events.on(event, method.bind(instance), target.name);
|
|
2641
|
+
}
|
|
2642
|
+
}
|
|
2643
|
+
}
|
|
2644
|
+
/**
|
|
2645
|
+
* Register a provider in the container
|
|
2646
|
+
*/
|
|
2647
|
+
registerProvider(provider) {
|
|
2648
|
+
const instance = this.container.resolve(provider);
|
|
2649
|
+
const priority = this.getProviderPriority(provider);
|
|
2650
|
+
this.initializedProviders.push({
|
|
2651
|
+
instance,
|
|
2652
|
+
priority,
|
|
2653
|
+
name: provider.name
|
|
2654
|
+
});
|
|
2655
|
+
}
|
|
2656
|
+
/**
|
|
2657
|
+
* Call a lifecycle hook on all initialized providers
|
|
2658
|
+
*/
|
|
2659
|
+
async callHook(hookName) {
|
|
2660
|
+
for (const { instance } of this.initializedProviders) {
|
|
2661
|
+
if (this.hasHook(instance, hookName)) {
|
|
2662
|
+
await instance[hookName]();
|
|
2663
|
+
}
|
|
2664
|
+
}
|
|
2665
|
+
}
|
|
2666
|
+
/**
|
|
2667
|
+
* Check if an instance has a lifecycle hook
|
|
2668
|
+
*/
|
|
2669
|
+
hasHook(instance, hookName) {
|
|
2670
|
+
return instance !== null && typeof instance === "object" && hookName in instance && typeof instance[hookName] === "function";
|
|
2671
|
+
}
|
|
2672
|
+
/**
|
|
2673
|
+
* Start listening for requests
|
|
2674
|
+
*/
|
|
2675
|
+
async listen() {
|
|
2676
|
+
if (this.isListening) {
|
|
2677
|
+
return this.address;
|
|
2678
|
+
}
|
|
2679
|
+
this.address = await this.server.listen({
|
|
2680
|
+
port: this.config.port,
|
|
2681
|
+
host: this.config.host
|
|
2682
|
+
});
|
|
2683
|
+
this.isListening = true;
|
|
2684
|
+
for (const { instance } of this.initializedProviders) {
|
|
2685
|
+
if (this.hasHook(instance, "onApplicationListen")) {
|
|
2686
|
+
await instance.onApplicationListen(this.address);
|
|
2687
|
+
}
|
|
2688
|
+
}
|
|
2689
|
+
await this.events.emit("app:listen", {
|
|
2690
|
+
address: this.address,
|
|
2691
|
+
port: this.config.port
|
|
2692
|
+
});
|
|
2693
|
+
return this.address;
|
|
2694
|
+
}
|
|
2695
|
+
/**
|
|
2696
|
+
* Close the application
|
|
2697
|
+
*/
|
|
2698
|
+
async close(signal) {
|
|
2699
|
+
await this.events.emit("app:shutdown", {
|
|
2700
|
+
signal
|
|
2701
|
+
});
|
|
2702
|
+
const reversed = [
|
|
2703
|
+
...this.initializedProviders
|
|
2704
|
+
].reverse();
|
|
2705
|
+
for (const { instance, name } of reversed) {
|
|
2706
|
+
if (this.hasHook(instance, "onApplicationShutdown")) {
|
|
2707
|
+
await instance.onApplicationShutdown(signal);
|
|
2708
|
+
}
|
|
2709
|
+
if (this.hasHook(instance, "onProviderDestroy")) {
|
|
2710
|
+
await instance.onProviderDestroy();
|
|
2711
|
+
}
|
|
2712
|
+
this.events.removeByOwner(name);
|
|
2713
|
+
}
|
|
2714
|
+
await this.server.close();
|
|
2715
|
+
this.isListening = false;
|
|
2716
|
+
await this.events.emit("app:destroy", {
|
|
2717
|
+
uptime: Date.now() - this.startTime
|
|
2718
|
+
});
|
|
2719
|
+
this.events.clear();
|
|
2720
|
+
if (!this.config.silent) console.log("\n\u{1F44B} Application closed\n");
|
|
2721
|
+
}
|
|
2722
|
+
/**
|
|
2723
|
+
* Get the server URL
|
|
2724
|
+
*/
|
|
2725
|
+
getUrl() {
|
|
2726
|
+
return this.address;
|
|
2727
|
+
}
|
|
2728
|
+
/**
|
|
2729
|
+
* Get the EventBus instance
|
|
2730
|
+
*/
|
|
2731
|
+
getEventBus() {
|
|
2732
|
+
return this.events;
|
|
2733
|
+
}
|
|
2734
|
+
/**
|
|
2735
|
+
* Get the DI Container instance
|
|
2736
|
+
*/
|
|
2737
|
+
getContainer() {
|
|
2738
|
+
return this.container;
|
|
2739
|
+
}
|
|
2740
|
+
/**
|
|
2741
|
+
* Get the Router instance
|
|
2742
|
+
* Useful for accessing router cache management methods
|
|
2743
|
+
*/
|
|
2744
|
+
getRouter() {
|
|
2745
|
+
return this.router;
|
|
2746
|
+
}
|
|
2747
|
+
/**
|
|
2748
|
+
* Clear all router caches (guards and middleware)
|
|
2749
|
+
* Useful for testing or hot-reload scenarios
|
|
2750
|
+
*
|
|
2751
|
+
* @example
|
|
2752
|
+
* ```typescript
|
|
2753
|
+
* // In tests
|
|
2754
|
+
* afterEach(() => {
|
|
2755
|
+
* app.clearRouterCaches();
|
|
2756
|
+
* });
|
|
2757
|
+
* ```
|
|
2758
|
+
*/
|
|
2759
|
+
clearRouterCaches() {
|
|
2760
|
+
this.router.clearAllCaches();
|
|
2761
|
+
}
|
|
2762
|
+
};
|
|
2763
|
+
|
|
2764
|
+
// src/core/decorators/controller.decorator.ts
|
|
2765
|
+
var import_reflect_metadata12 = require("reflect-metadata");
|
|
2766
|
+
function Controller(prefixOrOptions) {
|
|
2767
|
+
return (target) => {
|
|
2768
|
+
const prefix = typeof prefixOrOptions === "string" ? prefixOrOptions : prefixOrOptions?.prefix ?? "";
|
|
2769
|
+
const normalizedPrefix = prefix ? prefix.startsWith("/") ? prefix : `/${prefix}` : "";
|
|
2770
|
+
Reflect.defineMetadata(CONTROLLER_METADATA, {
|
|
2771
|
+
prefix: normalizedPrefix
|
|
2772
|
+
}, target);
|
|
2773
|
+
Reflect.defineMetadata(INJECTABLE_METADATA, {
|
|
2774
|
+
scope: "singleton"
|
|
2775
|
+
}, target);
|
|
2776
|
+
container.register(target, {
|
|
2777
|
+
scope: "singleton"
|
|
2778
|
+
});
|
|
2779
|
+
registry.registerController(target);
|
|
2780
|
+
};
|
|
2781
|
+
}
|
|
2782
|
+
__name(Controller, "Controller");
|
|
2783
|
+
|
|
2784
|
+
// src/core/decorators/route.decorator.ts
|
|
2785
|
+
var import_reflect_metadata13 = require("reflect-metadata");
|
|
2786
|
+
function createRouteDecorator(method) {
|
|
2787
|
+
return (path2 = "") => {
|
|
2788
|
+
return (target, propertyKey, descriptor) => {
|
|
2789
|
+
const normalizedPath = path2.startsWith("/") ? path2 : `/${path2}`;
|
|
2790
|
+
const routes = Reflect.getMetadata(ROUTES_METADATA, target.constructor) ?? [];
|
|
2791
|
+
routes.push({
|
|
2792
|
+
method,
|
|
2793
|
+
path: normalizedPath === "/" ? "" : normalizedPath,
|
|
2794
|
+
handlerName: propertyKey
|
|
2795
|
+
});
|
|
2796
|
+
Reflect.defineMetadata(ROUTES_METADATA, routes, target.constructor);
|
|
2797
|
+
return descriptor;
|
|
2798
|
+
};
|
|
2799
|
+
};
|
|
2800
|
+
}
|
|
2801
|
+
__name(createRouteDecorator, "createRouteDecorator");
|
|
2802
|
+
var Get = createRouteDecorator("GET");
|
|
2803
|
+
var Post = createRouteDecorator("POST");
|
|
2804
|
+
var Put = createRouteDecorator("PUT");
|
|
2805
|
+
var Patch = createRouteDecorator("PATCH");
|
|
2806
|
+
var Delete = createRouteDecorator("DELETE");
|
|
2807
|
+
var Options = createRouteDecorator("OPTIONS");
|
|
2808
|
+
var Head = createRouteDecorator("HEAD");
|
|
2809
|
+
function HttpCode(statusCode) {
|
|
2810
|
+
return (target, propertyKey, descriptor) => {
|
|
2811
|
+
Reflect.defineMetadata(HTTP_CODE_METADATA, statusCode, target.constructor, propertyKey);
|
|
2812
|
+
return descriptor;
|
|
2813
|
+
};
|
|
2814
|
+
}
|
|
2815
|
+
__name(HttpCode, "HttpCode");
|
|
2816
|
+
|
|
2817
|
+
// src/core/decorators/param.decorator.ts
|
|
2818
|
+
var import_reflect_metadata14 = require("reflect-metadata");
|
|
2819
|
+
function isZodType(value) {
|
|
2820
|
+
return value !== null && typeof value === "object" && ("_zod" in value || "_def" in value) && "safeParse" in value && typeof value.safeParse === "function";
|
|
2821
|
+
}
|
|
2822
|
+
__name(isZodType, "isZodType");
|
|
2823
|
+
function createParamDecorator2(type) {
|
|
2824
|
+
function decorator(keyOrSchema) {
|
|
2825
|
+
return (target, propertyKey, parameterIndex) => {
|
|
2826
|
+
if (propertyKey === void 0) return;
|
|
2827
|
+
const existingParams = Reflect.getMetadata(PARAM_METADATA, target.constructor, propertyKey) ?? [];
|
|
2828
|
+
const isSchema = isZodType(keyOrSchema);
|
|
2829
|
+
const metadata = {
|
|
2830
|
+
index: parameterIndex,
|
|
2831
|
+
type,
|
|
2832
|
+
key: isSchema ? void 0 : keyOrSchema,
|
|
2833
|
+
zodSchema: isSchema ? keyOrSchema : void 0
|
|
2834
|
+
};
|
|
2835
|
+
existingParams.push(metadata);
|
|
2836
|
+
Reflect.defineMetadata(PARAM_METADATA, existingParams, target.constructor, propertyKey);
|
|
2837
|
+
};
|
|
2838
|
+
}
|
|
2839
|
+
__name(decorator, "decorator");
|
|
2840
|
+
return decorator;
|
|
2841
|
+
}
|
|
2842
|
+
__name(createParamDecorator2, "createParamDecorator");
|
|
2843
|
+
var Body = createParamDecorator2(ParamType.BODY);
|
|
2844
|
+
var Query = createParamDecorator2(ParamType.QUERY);
|
|
2845
|
+
var Param = createParamDecorator2(ParamType.PARAM);
|
|
2846
|
+
var Headers = createParamDecorator2(ParamType.HEADERS);
|
|
2847
|
+
var Req = createParamDecorator2(ParamType.REQUEST);
|
|
2848
|
+
var Request = Req;
|
|
2849
|
+
var Res = createParamDecorator2(ParamType.REPLY);
|
|
2850
|
+
var Reply = Res;
|
|
2851
|
+
var Ctx = createParamDecorator2(ParamType.CONTEXT);
|
|
2852
|
+
var Context = Ctx;
|
|
2853
|
+
|
|
2854
|
+
// src/core/decorators/autowired.decorator.ts
|
|
2855
|
+
var import_reflect_metadata15 = require("reflect-metadata");
|
|
2856
|
+
function Autowired(token, name) {
|
|
2857
|
+
return (target, propertyKey, parameterIndex) => {
|
|
2858
|
+
if (typeof parameterIndex === "number") {
|
|
2859
|
+
const paramTypes = Reflect.getMetadata("design:paramtypes", target) ?? [];
|
|
2860
|
+
const inferredType = paramTypes[parameterIndex];
|
|
2861
|
+
const resolvedToken = token ?? inferredType;
|
|
2862
|
+
if (!resolvedToken) {
|
|
2863
|
+
throw new Error(`@Autowired() on constructor parameter ${parameterIndex} of ${target.name} could not infer type. Please provide a token explicitly.`);
|
|
2864
|
+
}
|
|
2865
|
+
const existingInjects = Reflect.getMetadata(INJECT_METADATA, target) ?? [];
|
|
2866
|
+
existingInjects.push({
|
|
2867
|
+
token: resolvedToken,
|
|
2868
|
+
index: parameterIndex,
|
|
2869
|
+
name
|
|
2870
|
+
});
|
|
2871
|
+
Reflect.defineMetadata(INJECT_METADATA, existingInjects, target);
|
|
2872
|
+
} else if (propertyKey !== void 0) {
|
|
2873
|
+
const inferredType = Reflect.getMetadata("design:type", target, propertyKey);
|
|
2874
|
+
const resolvedToken = token ?? inferredType;
|
|
2875
|
+
if (!resolvedToken) {
|
|
2876
|
+
throw new Error(`@Autowired() on ${target.constructor.name}.${String(propertyKey)} could not infer type. Please provide a token explicitly.`);
|
|
2877
|
+
}
|
|
2878
|
+
const existingAutowires = Reflect.getMetadata(AUTOWIRED_METADATA, target.constructor) ?? [];
|
|
2879
|
+
existingAutowires.push({
|
|
2880
|
+
token: resolvedToken,
|
|
2881
|
+
propertyKey: String(propertyKey),
|
|
2882
|
+
name
|
|
2883
|
+
});
|
|
2884
|
+
Reflect.defineMetadata(AUTOWIRED_METADATA, existingAutowires, target.constructor);
|
|
2885
|
+
}
|
|
2886
|
+
};
|
|
2887
|
+
}
|
|
2888
|
+
__name(Autowired, "Autowired");
|
|
2889
|
+
function Optional() {
|
|
2890
|
+
return (target, propertyKey, parameterIndex) => {
|
|
2891
|
+
if (typeof parameterIndex === "number") {
|
|
2892
|
+
const existingInjects = Reflect.getMetadata(INJECT_METADATA, target) ?? [];
|
|
2893
|
+
let meta = existingInjects.find((m) => m.index === parameterIndex);
|
|
2894
|
+
if (meta) {
|
|
2895
|
+
meta.optional = true;
|
|
2896
|
+
} else {
|
|
2897
|
+
const paramTypes = Reflect.getMetadata("design:paramtypes", target) ?? [];
|
|
2898
|
+
const paramType = paramTypes[parameterIndex];
|
|
2899
|
+
if (paramType) {
|
|
2900
|
+
existingInjects.push({
|
|
2901
|
+
token: paramType,
|
|
2902
|
+
index: parameterIndex,
|
|
2903
|
+
optional: true
|
|
2904
|
+
});
|
|
2905
|
+
}
|
|
2906
|
+
}
|
|
2907
|
+
Reflect.defineMetadata(INJECT_METADATA, existingInjects, target);
|
|
2908
|
+
} else if (propertyKey !== void 0) {
|
|
2909
|
+
const existingAutowires = Reflect.getMetadata(AUTOWIRED_METADATA, target.constructor) ?? [];
|
|
2910
|
+
let meta = existingAutowires.find((m) => m.propertyKey === String(propertyKey));
|
|
2911
|
+
if (meta) {
|
|
2912
|
+
meta.optional = true;
|
|
2913
|
+
} else {
|
|
2914
|
+
const propType = Reflect.getMetadata("design:type", target, propertyKey);
|
|
2915
|
+
if (propType) {
|
|
2916
|
+
existingAutowires.push({
|
|
2917
|
+
token: propType,
|
|
2918
|
+
propertyKey: String(propertyKey),
|
|
2919
|
+
optional: true
|
|
2920
|
+
});
|
|
2921
|
+
}
|
|
2922
|
+
}
|
|
2923
|
+
Reflect.defineMetadata(AUTOWIRED_METADATA, existingAutowires, target.constructor);
|
|
2924
|
+
}
|
|
2925
|
+
};
|
|
2926
|
+
}
|
|
2927
|
+
__name(Optional, "Optional");
|
|
2928
|
+
|
|
2929
|
+
// src/core/decorators/provider.decorator.ts
|
|
2930
|
+
var import_reflect_metadata16 = require("reflect-metadata");
|
|
2931
|
+
function generateTokenFromClassName(className) {
|
|
2932
|
+
let tokenName = className.replace(/Provider$/, "");
|
|
2933
|
+
tokenName = tokenName.replace(/([A-Z])/g, "_$1").toUpperCase().replace(/^_/, "");
|
|
2934
|
+
if (!tokenName.endsWith("_CONFIG") && tokenName !== "CONFIG") {
|
|
2935
|
+
tokenName = `${tokenName}_CONFIG`;
|
|
2936
|
+
}
|
|
2937
|
+
return tokenName;
|
|
2938
|
+
}
|
|
2939
|
+
__name(generateTokenFromClassName, "generateTokenFromClassName");
|
|
2940
|
+
function Provider(token) {
|
|
2941
|
+
return (target) => {
|
|
2942
|
+
const className = target.name;
|
|
2943
|
+
const isConfigProvider2 = typeof target.prototype.schema === "function";
|
|
2944
|
+
if (isConfigProvider2) {
|
|
2945
|
+
let configToken;
|
|
2946
|
+
if (typeof token === "string") {
|
|
2947
|
+
if (token.trim() === "") {
|
|
2948
|
+
throw new Error(`@Provider: Config provider "${className}" token must be a non-empty string.`);
|
|
2949
|
+
}
|
|
2950
|
+
configToken = token;
|
|
2951
|
+
} else if (token === void 0) {
|
|
2952
|
+
configToken = generateTokenFromClassName(className);
|
|
2953
|
+
} else {
|
|
2954
|
+
throw new Error(`@Provider: Config provider "${className}" requires a string token or no token for auto-generation.`);
|
|
2955
|
+
}
|
|
2956
|
+
if (configToken !== configToken.toUpperCase()) {
|
|
2957
|
+
throw new Error(`@Provider: Token "${configToken}" for config provider "${className}" must be UPPERCASE. Use "${configToken.toUpperCase()}" instead.`);
|
|
2958
|
+
}
|
|
2959
|
+
const configMetadata = {
|
|
2960
|
+
token: configToken
|
|
2961
|
+
};
|
|
2962
|
+
Reflect.defineMetadata(CONFIG_PROVIDER_METADATA, configMetadata, target);
|
|
2963
|
+
registry.registerConfigProvider(configToken, target);
|
|
2964
|
+
} else {
|
|
2965
|
+
if (token === void 0) {
|
|
2966
|
+
throw new Error(`@Provider: Custom provider "${className}" requires a token parameter.`);
|
|
2967
|
+
}
|
|
2968
|
+
const metadata = {
|
|
2969
|
+
token
|
|
2970
|
+
};
|
|
2971
|
+
Reflect.defineMetadata(PROVIDER_METADATA, metadata, target);
|
|
2972
|
+
registry.registerCustomProvider(target);
|
|
2973
|
+
}
|
|
2974
|
+
};
|
|
2975
|
+
}
|
|
2976
|
+
__name(Provider, "Provider");
|
|
2977
|
+
function getConfigProviderMetadata(target) {
|
|
2978
|
+
return Reflect.getMetadata(CONFIG_PROVIDER_METADATA, target);
|
|
2979
|
+
}
|
|
2980
|
+
__name(getConfigProviderMetadata, "getConfigProviderMetadata");
|
|
2981
|
+
function isConfigProvider(target) {
|
|
2982
|
+
return Reflect.hasMetadata(CONFIG_PROVIDER_METADATA, target);
|
|
2983
|
+
}
|
|
2984
|
+
__name(isConfigProvider, "isConfigProvider");
|
|
2985
|
+
|
|
2986
|
+
// src/core/decorators/config-property.decorator.ts
|
|
2987
|
+
var import_reflect_metadata17 = require("reflect-metadata");
|
|
2988
|
+
var propertyNameCache = /* @__PURE__ */ new Map();
|
|
2989
|
+
function toUpperSnakeCase(propertyName) {
|
|
2990
|
+
if (propertyNameCache.has(propertyName)) {
|
|
2991
|
+
return propertyNameCache.get(propertyName);
|
|
2992
|
+
}
|
|
2993
|
+
const envKey = propertyName.replace(/([A-Z])/g, "_$1").toUpperCase().replace(/^_/, "");
|
|
2994
|
+
propertyNameCache.set(propertyName, envKey);
|
|
2995
|
+
return envKey;
|
|
2996
|
+
}
|
|
2997
|
+
__name(toUpperSnakeCase, "toUpperSnakeCase");
|
|
2998
|
+
function ConfigProperty(envKey) {
|
|
2999
|
+
return (target, propertyKey) => {
|
|
3000
|
+
if (typeof propertyKey === "symbol") {
|
|
3001
|
+
throw new Error(`@ConfigProperty: Symbol properties are not supported. Property "${String(propertyKey)}" must be a string.`);
|
|
3002
|
+
}
|
|
3003
|
+
const finalEnvKey = envKey ?? toUpperSnakeCase(propertyKey);
|
|
3004
|
+
if (!finalEnvKey || typeof finalEnvKey !== "string") {
|
|
3005
|
+
throw new Error(`@ConfigProperty: Invalid env key for property "${propertyKey}". Env key must be a non-empty string.`);
|
|
3006
|
+
}
|
|
3007
|
+
if (finalEnvKey !== finalEnvKey.toUpperCase()) {
|
|
3008
|
+
throw new Error(`@ConfigProperty: Env key "${finalEnvKey}" for property "${propertyKey}" must be UPPERCASE. Use "${finalEnvKey.toUpperCase()}" instead.`);
|
|
3009
|
+
}
|
|
3010
|
+
const constructor = target.constructor;
|
|
3011
|
+
const existingMappings = Reflect.getMetadata(CONFIG_PROPERTY_METADATA, constructor) || [];
|
|
3012
|
+
const duplicate = existingMappings.find((m) => m.propertyKey === propertyKey);
|
|
3013
|
+
if (duplicate) {
|
|
3014
|
+
throw new Error(`@ConfigProperty: Property "${propertyKey}" on class "${constructor.name}" is already decorated. Remove the duplicate @ConfigProperty decorator.`);
|
|
3015
|
+
}
|
|
3016
|
+
const duplicateEnvKey = existingMappings.find((m) => m.envKey === finalEnvKey);
|
|
3017
|
+
if (duplicateEnvKey) {
|
|
3018
|
+
throw new Error(`@ConfigProperty: Env key "${finalEnvKey}" is already mapped to property "${duplicateEnvKey.propertyKey}" on class "${constructor.name}". Each env key can only be mapped to one property.`);
|
|
3019
|
+
}
|
|
3020
|
+
const newMapping = {
|
|
3021
|
+
propertyKey,
|
|
3022
|
+
envKey: finalEnvKey
|
|
3023
|
+
};
|
|
3024
|
+
const updatedMappings = [
|
|
3025
|
+
...existingMappings,
|
|
3026
|
+
newMapping
|
|
3027
|
+
];
|
|
3028
|
+
Reflect.defineMetadata(CONFIG_PROPERTY_METADATA, updatedMappings, constructor);
|
|
3029
|
+
};
|
|
3030
|
+
}
|
|
3031
|
+
__name(ConfigProperty, "ConfigProperty");
|
|
3032
|
+
function getConfigPropertyMappings(target) {
|
|
3033
|
+
return Reflect.getMetadata(CONFIG_PROPERTY_METADATA, target) || [];
|
|
3034
|
+
}
|
|
3035
|
+
__name(getConfigPropertyMappings, "getConfigPropertyMappings");
|
|
3036
|
+
function hasConfigProperties(target) {
|
|
3037
|
+
const mappings = getConfigPropertyMappings(target);
|
|
3038
|
+
return mappings.length > 0;
|
|
3039
|
+
}
|
|
3040
|
+
__name(hasConfigProperties, "hasConfigProperties");
|
|
3041
|
+
function clearPropertyNameCache() {
|
|
3042
|
+
propertyNameCache.clear();
|
|
3043
|
+
}
|
|
3044
|
+
__name(clearPropertyNameCache, "clearPropertyNameCache");
|
|
3045
|
+
|
|
3046
|
+
// src/core/decorators/apply-decorators.ts
|
|
3047
|
+
var import_reflect_metadata18 = require("reflect-metadata");
|
|
3048
|
+
function applyDecorators(...decorators) {
|
|
3049
|
+
return (target, propertyKey, descriptor) => {
|
|
3050
|
+
for (const decorator of decorators.reverse()) {
|
|
3051
|
+
if (descriptor) {
|
|
3052
|
+
const result = decorator(target, propertyKey, descriptor);
|
|
3053
|
+
if (result) {
|
|
3054
|
+
descriptor = result;
|
|
3055
|
+
}
|
|
3056
|
+
} else if (propertyKey !== void 0) {
|
|
3057
|
+
decorator(target, propertyKey);
|
|
3058
|
+
} else {
|
|
3059
|
+
const result = decorator(target);
|
|
3060
|
+
if (result) {
|
|
3061
|
+
return result;
|
|
3062
|
+
}
|
|
3063
|
+
}
|
|
3064
|
+
}
|
|
3065
|
+
if (descriptor) {
|
|
3066
|
+
return descriptor;
|
|
3067
|
+
}
|
|
3068
|
+
};
|
|
3069
|
+
}
|
|
3070
|
+
__name(applyDecorators, "applyDecorators");
|
|
3071
|
+
function SetMetadata(key, value) {
|
|
3072
|
+
const decoratorFactory = /* @__PURE__ */ __name((target, propertyKey, descriptor) => {
|
|
3073
|
+
if (descriptor) {
|
|
3074
|
+
Reflect.defineMetadata(key, value, target.constructor, propertyKey);
|
|
3075
|
+
} else {
|
|
3076
|
+
Reflect.defineMetadata(key, value, target);
|
|
3077
|
+
}
|
|
3078
|
+
}, "decoratorFactory");
|
|
3079
|
+
return decoratorFactory;
|
|
3080
|
+
}
|
|
3081
|
+
__name(SetMetadata, "SetMetadata");
|
|
3082
|
+
|
|
3083
|
+
// src/core/middleware/middleware.decorator.ts
|
|
3084
|
+
var import_reflect_metadata19 = require("reflect-metadata");
|
|
3085
|
+
function Middleware() {
|
|
3086
|
+
return (target) => {
|
|
3087
|
+
Reflect.defineMetadata("middleware", true, target);
|
|
3088
|
+
Reflect.defineMetadata("injectable", true, target);
|
|
3089
|
+
};
|
|
3090
|
+
}
|
|
3091
|
+
__name(Middleware, "Middleware");
|
|
3092
|
+
|
|
3093
|
+
// src/core/config/abstract-config-provider.ts
|
|
3094
|
+
var import_zod = require("zod");
|
|
3095
|
+
var ConfigValidationException = class extends Error {
|
|
3096
|
+
static {
|
|
3097
|
+
__name(this, "ConfigValidationException");
|
|
3098
|
+
}
|
|
3099
|
+
errors;
|
|
3100
|
+
constructor(errors, providerName) {
|
|
3101
|
+
const errorMessages = errors.issues.map((err) => ` - ${err.path.join(".")}: ${err.message}`).join("\n");
|
|
3102
|
+
super(`Configuration validation failed for ${providerName}:
|
|
3103
|
+
${errorMessages}
|
|
3104
|
+
|
|
3105
|
+
Please check your .env file and ensure all required variables are set correctly.`), this.errors = errors;
|
|
3106
|
+
this.name = "ConfigValidationException";
|
|
3107
|
+
}
|
|
3108
|
+
};
|
|
3109
|
+
var AbstractConfigProvider = class {
|
|
3110
|
+
static {
|
|
3111
|
+
__name(this, "AbstractConfigProvider");
|
|
3112
|
+
}
|
|
3113
|
+
/**
|
|
3114
|
+
* Cache for validated configuration
|
|
3115
|
+
* Frozen to prevent accidental mutations
|
|
3116
|
+
*/
|
|
3117
|
+
_cache;
|
|
3118
|
+
/**
|
|
3119
|
+
* Constructor ensures .env files are loaded (for standalone usage)
|
|
3120
|
+
*
|
|
3121
|
+
* Note: When using Rikta.create(), .env files are loaded automatically
|
|
3122
|
+
* during bootstrap, so this is a safety measure for standalone usage.
|
|
3123
|
+
*/
|
|
3124
|
+
constructor() {
|
|
3125
|
+
loadEnvFiles();
|
|
3126
|
+
}
|
|
3127
|
+
/**
|
|
3128
|
+
* Validate and cache the configuration
|
|
3129
|
+
*
|
|
3130
|
+
* This method runs the Zod schema validation against process.env
|
|
3131
|
+
* and caches the result. Subsequent calls return the cached value.
|
|
3132
|
+
*
|
|
3133
|
+
* @returns The validated and frozen configuration object
|
|
3134
|
+
* @throws {ConfigValidationException} If validation fails
|
|
3135
|
+
*
|
|
3136
|
+
* @private
|
|
3137
|
+
*/
|
|
3138
|
+
validateAndCache() {
|
|
3139
|
+
if (this._cache) {
|
|
3140
|
+
return this._cache;
|
|
3141
|
+
}
|
|
3142
|
+
try {
|
|
3143
|
+
const schema = this.schema();
|
|
3144
|
+
const validated = schema.parse(process.env);
|
|
3145
|
+
this._cache = Object.freeze(validated);
|
|
3146
|
+
return this._cache;
|
|
3147
|
+
} catch (error) {
|
|
3148
|
+
if (error instanceof import_zod.z.ZodError) {
|
|
3149
|
+
throw new ConfigValidationException(error, this.constructor.name);
|
|
3150
|
+
}
|
|
3151
|
+
throw error;
|
|
3152
|
+
}
|
|
3153
|
+
}
|
|
3154
|
+
/**
|
|
3155
|
+
* Populate decorated properties with validated values
|
|
3156
|
+
*
|
|
3157
|
+
* This method reads the @ConfigProperty metadata and assigns
|
|
3158
|
+
* the corresponding validated environment values to class properties.
|
|
3159
|
+
*
|
|
3160
|
+
* Must be called in the child class constructor after super().
|
|
3161
|
+
*
|
|
3162
|
+
* @throws {ConfigValidationException} If validation fails
|
|
3163
|
+
*
|
|
3164
|
+
* @example
|
|
3165
|
+
* ```typescript
|
|
3166
|
+
* constructor() {
|
|
3167
|
+
* super();
|
|
3168
|
+
* this.populate(); // Must call this!
|
|
3169
|
+
* }
|
|
3170
|
+
* ```
|
|
3171
|
+
*/
|
|
3172
|
+
populate() {
|
|
3173
|
+
const config = this.validateAndCache();
|
|
3174
|
+
const mappings = getConfigPropertyMappings(this.constructor);
|
|
3175
|
+
for (const mapping of mappings) {
|
|
3176
|
+
const value = config[mapping.envKey];
|
|
3177
|
+
this[mapping.propertyKey] = value;
|
|
3178
|
+
}
|
|
3179
|
+
}
|
|
3180
|
+
/**
|
|
3181
|
+
* Get the raw validated configuration object
|
|
3182
|
+
*
|
|
3183
|
+
* This is useful for accessing config values that aren't mapped
|
|
3184
|
+
* to properties, or for passing the entire config to other services.
|
|
3185
|
+
*
|
|
3186
|
+
* @returns The validated and frozen configuration object
|
|
3187
|
+
*
|
|
3188
|
+
* @example
|
|
3189
|
+
* ```typescript
|
|
3190
|
+
* const config = this.getConfig();
|
|
3191
|
+
* console.log('All env vars:', config);
|
|
3192
|
+
* ```
|
|
3193
|
+
*/
|
|
3194
|
+
getConfig() {
|
|
3195
|
+
return this.validateAndCache();
|
|
3196
|
+
}
|
|
3197
|
+
/**
|
|
3198
|
+
* Get a specific configuration value by key
|
|
3199
|
+
*
|
|
3200
|
+
* @param key - The environment variable name
|
|
3201
|
+
* @returns The validated value, or undefined if not found
|
|
3202
|
+
*
|
|
3203
|
+
* @example
|
|
3204
|
+
* ```typescript
|
|
3205
|
+
* const port = this.get<number>('PORT');
|
|
3206
|
+
* const apiKey = this.get<string>('API_KEY');
|
|
3207
|
+
* ```
|
|
3208
|
+
*/
|
|
3209
|
+
get(key) {
|
|
3210
|
+
const config = this.validateAndCache();
|
|
3211
|
+
return config[key];
|
|
3212
|
+
}
|
|
3213
|
+
};
|
|
3214
|
+
|
|
3215
|
+
// src/core/metadata.ts
|
|
3216
|
+
var import_reflect_metadata20 = require("reflect-metadata");
|
|
3217
|
+
function getControllerMetadata(target) {
|
|
3218
|
+
return Reflect.getMetadata(CONTROLLER_METADATA, target);
|
|
3219
|
+
}
|
|
3220
|
+
__name(getControllerMetadata, "getControllerMetadata");
|
|
3221
|
+
function isController(target) {
|
|
3222
|
+
return Reflect.hasMetadata(CONTROLLER_METADATA, target);
|
|
3223
|
+
}
|
|
3224
|
+
__name(isController, "isController");
|
|
3225
|
+
function getControllerPath(target) {
|
|
3226
|
+
const meta = getControllerMetadata(target);
|
|
3227
|
+
return meta?.prefix ?? "";
|
|
3228
|
+
}
|
|
3229
|
+
__name(getControllerPath, "getControllerPath");
|
|
3230
|
+
function getRoutes(target) {
|
|
3231
|
+
return Reflect.getMetadata(ROUTES_METADATA, target) || [];
|
|
3232
|
+
}
|
|
3233
|
+
__name(getRoutes, "getRoutes");
|
|
3234
|
+
function hasRoutes(target) {
|
|
3235
|
+
const routes = getRoutes(target);
|
|
3236
|
+
return routes.length > 0;
|
|
3237
|
+
}
|
|
3238
|
+
__name(hasRoutes, "hasRoutes");
|
|
3239
|
+
function getParamMetadata(target, methodName) {
|
|
3240
|
+
return Reflect.getMetadata(PARAM_METADATA, target.prototype, methodName) || [];
|
|
3241
|
+
}
|
|
3242
|
+
__name(getParamMetadata, "getParamMetadata");
|
|
3243
|
+
function getParamMetadataByIndex(target, methodName, paramIndex) {
|
|
3244
|
+
const params = getParamMetadata(target, methodName);
|
|
3245
|
+
return params.find((p) => p.index === paramIndex);
|
|
3246
|
+
}
|
|
3247
|
+
__name(getParamMetadataByIndex, "getParamMetadataByIndex");
|
|
3248
|
+
function getHttpCode(target, methodName) {
|
|
3249
|
+
return Reflect.getMetadata(HTTP_CODE_METADATA, target.prototype, methodName);
|
|
3250
|
+
}
|
|
3251
|
+
__name(getHttpCode, "getHttpCode");
|
|
3252
|
+
function getGuards(target, methodName) {
|
|
3253
|
+
if (methodName) {
|
|
3254
|
+
const methodGuards = Reflect.getMetadata(GUARDS_METADATA, target.prototype, methodName) || [];
|
|
3255
|
+
const controllerGuards = Reflect.getMetadata(GUARDS_METADATA, target) || [];
|
|
3256
|
+
return [
|
|
3257
|
+
...controllerGuards,
|
|
3258
|
+
...methodGuards
|
|
3259
|
+
];
|
|
3260
|
+
}
|
|
3261
|
+
return Reflect.getMetadata(GUARDS_METADATA, target) || [];
|
|
3262
|
+
}
|
|
3263
|
+
__name(getGuards, "getGuards");
|
|
3264
|
+
function getZodSchema(target, methodName) {
|
|
3265
|
+
return Reflect.getMetadata(ZOD_SCHEMA_METADATA, target.prototype, methodName);
|
|
3266
|
+
}
|
|
3267
|
+
__name(getZodSchema, "getZodSchema");
|
|
3268
|
+
function getClassMetadata(metadataKey, target) {
|
|
3269
|
+
return Reflect.getMetadata(metadataKey, target);
|
|
3270
|
+
}
|
|
3271
|
+
__name(getClassMetadata, "getClassMetadata");
|
|
3272
|
+
function getMethodMetadata(metadataKey, target, methodName) {
|
|
3273
|
+
return Reflect.getMetadata(metadataKey, target.prototype, methodName);
|
|
3274
|
+
}
|
|
3275
|
+
__name(getMethodMetadata, "getMethodMetadata");
|
|
3276
|
+
function hasClassMetadata(metadataKey, target) {
|
|
3277
|
+
return Reflect.hasMetadata(metadataKey, target);
|
|
3278
|
+
}
|
|
3279
|
+
__name(hasClassMetadata, "hasClassMetadata");
|
|
3280
|
+
function hasMethodMetadata(metadataKey, target, methodName) {
|
|
3281
|
+
return Reflect.hasMetadata(metadataKey, target.prototype, methodName);
|
|
3282
|
+
}
|
|
3283
|
+
__name(hasMethodMetadata, "hasMethodMetadata");
|
|
3284
|
+
function getMethodsWithMetadata(metadataKey, target) {
|
|
3285
|
+
const methods = [];
|
|
3286
|
+
const prototype = target.prototype;
|
|
3287
|
+
const propertyNames = Object.getOwnPropertyNames(prototype);
|
|
3288
|
+
const propertySymbols = Object.getOwnPropertySymbols(prototype);
|
|
3289
|
+
for (const name of [
|
|
3290
|
+
...propertyNames,
|
|
3291
|
+
...propertySymbols
|
|
3292
|
+
]) {
|
|
3293
|
+
if (name !== "constructor" && Reflect.hasMetadata(metadataKey, prototype, name)) {
|
|
3294
|
+
methods.push(name);
|
|
3295
|
+
}
|
|
3296
|
+
}
|
|
3297
|
+
return methods;
|
|
3298
|
+
}
|
|
3299
|
+
__name(getMethodsWithMetadata, "getMethodsWithMetadata");
|
|
3300
|
+
|
|
3301
|
+
// src/core/profiler/performance-profiler.ts
|
|
3302
|
+
var PerformanceProfiler = class {
|
|
3303
|
+
static {
|
|
3304
|
+
__name(this, "PerformanceProfiler");
|
|
3305
|
+
}
|
|
3306
|
+
enabled = true;
|
|
3307
|
+
eventBus;
|
|
3308
|
+
listeners = [];
|
|
3309
|
+
bootstrapMetrics = {};
|
|
3310
|
+
constructor(options) {
|
|
3311
|
+
this.enabled = options?.enabled ?? true;
|
|
3312
|
+
this.eventBus = options?.eventBus;
|
|
3313
|
+
}
|
|
3314
|
+
/**
|
|
3315
|
+
* Enable or disable profiling
|
|
3316
|
+
*/
|
|
3317
|
+
setEnabled(enabled) {
|
|
3318
|
+
this.enabled = enabled;
|
|
3319
|
+
}
|
|
3320
|
+
/**
|
|
3321
|
+
* Check if profiling is enabled
|
|
3322
|
+
*/
|
|
3323
|
+
isEnabled() {
|
|
3324
|
+
return this.enabled;
|
|
3325
|
+
}
|
|
3326
|
+
/**
|
|
3327
|
+
* Start a timer for measuring an operation
|
|
3328
|
+
*
|
|
3329
|
+
* @param name - Name of the operation
|
|
3330
|
+
* @returns A function to call when the operation completes
|
|
3331
|
+
*/
|
|
3332
|
+
startTimer(name) {
|
|
3333
|
+
if (!this.enabled) {
|
|
3334
|
+
return () => null;
|
|
3335
|
+
}
|
|
3336
|
+
const startTime = performance.now();
|
|
3337
|
+
const startTimestamp = Date.now();
|
|
3338
|
+
return (metadata) => {
|
|
3339
|
+
const duration = performance.now() - startTime;
|
|
3340
|
+
const metric = {
|
|
3341
|
+
name,
|
|
3342
|
+
duration,
|
|
3343
|
+
startTime: startTimestamp,
|
|
3344
|
+
metadata
|
|
3345
|
+
};
|
|
3346
|
+
this.emitMetric(metric);
|
|
3347
|
+
return metric;
|
|
3348
|
+
};
|
|
3349
|
+
}
|
|
3350
|
+
/**
|
|
3351
|
+
* Measure the execution time of a function
|
|
3352
|
+
*
|
|
3353
|
+
* @param name - Name of the operation
|
|
3354
|
+
* @param fn - Function to measure
|
|
3355
|
+
* @returns The result of the function
|
|
3356
|
+
*/
|
|
3357
|
+
async measure(name, fn) {
|
|
3358
|
+
const end = this.startTimer(name);
|
|
3359
|
+
try {
|
|
3360
|
+
const result = await fn();
|
|
3361
|
+
end();
|
|
3362
|
+
return result;
|
|
3363
|
+
} catch (error) {
|
|
3364
|
+
end({
|
|
3365
|
+
error: true
|
|
3366
|
+
});
|
|
3367
|
+
throw error;
|
|
3368
|
+
}
|
|
3369
|
+
}
|
|
3370
|
+
/**
|
|
3371
|
+
* Record a route request metric
|
|
3372
|
+
*/
|
|
3373
|
+
recordRouteMetric(metric) {
|
|
3374
|
+
if (!this.enabled) return;
|
|
3375
|
+
this.emitMetric(metric);
|
|
3376
|
+
this.eventBus?.emit("profiler:route", metric);
|
|
3377
|
+
}
|
|
3378
|
+
/**
|
|
3379
|
+
* Record bootstrap phase timing
|
|
3380
|
+
*/
|
|
3381
|
+
recordBootstrapPhase(phase, duration) {
|
|
3382
|
+
this.bootstrapMetrics[phase] = duration;
|
|
3383
|
+
}
|
|
3384
|
+
/**
|
|
3385
|
+
* Get bootstrap metrics
|
|
3386
|
+
*/
|
|
3387
|
+
getBootstrapMetrics() {
|
|
3388
|
+
return {
|
|
3389
|
+
...this.bootstrapMetrics
|
|
3390
|
+
};
|
|
3391
|
+
}
|
|
3392
|
+
/**
|
|
3393
|
+
* Subscribe to metric events
|
|
3394
|
+
*
|
|
3395
|
+
* @param listener - Callback for each metric
|
|
3396
|
+
* @returns Unsubscribe function
|
|
3397
|
+
*/
|
|
3398
|
+
onMetric(listener) {
|
|
3399
|
+
this.listeners.push(listener);
|
|
3400
|
+
return () => {
|
|
3401
|
+
const index = this.listeners.indexOf(listener);
|
|
3402
|
+
if (index !== -1) {
|
|
3403
|
+
this.listeners.splice(index, 1);
|
|
3404
|
+
}
|
|
3405
|
+
};
|
|
3406
|
+
}
|
|
3407
|
+
/**
|
|
3408
|
+
* Emit a metric to all listeners
|
|
3409
|
+
*/
|
|
3410
|
+
emitMetric(metric) {
|
|
3411
|
+
for (const listener of this.listeners) {
|
|
3412
|
+
try {
|
|
3413
|
+
listener(metric);
|
|
3414
|
+
} catch {
|
|
3415
|
+
}
|
|
3416
|
+
}
|
|
3417
|
+
this.eventBus?.emit("profiler:metric", metric);
|
|
3418
|
+
}
|
|
3419
|
+
/**
|
|
3420
|
+
* Create a timer that automatically logs to console
|
|
3421
|
+
*/
|
|
3422
|
+
createConsoleTimer(prefix = "[Rikta]") {
|
|
3423
|
+
return (name) => {
|
|
3424
|
+
const end = this.startTimer(name);
|
|
3425
|
+
return (metadata) => {
|
|
3426
|
+
const metric = end(metadata);
|
|
3427
|
+
if (metric) {
|
|
3428
|
+
console.log(`${prefix} ${metric.name}: ${metric.duration.toFixed(2)}ms`);
|
|
3429
|
+
}
|
|
3430
|
+
};
|
|
3431
|
+
};
|
|
3432
|
+
}
|
|
3433
|
+
};
|
|
3434
|
+
var profiler = new PerformanceProfiler();
|
|
3435
|
+
function setGlobalProfiler(newProfiler) {
|
|
3436
|
+
profiler = newProfiler;
|
|
3437
|
+
}
|
|
3438
|
+
__name(setGlobalProfiler, "setGlobalProfiler");
|
|
3439
|
+
function getGlobalProfiler() {
|
|
3440
|
+
return profiler;
|
|
3441
|
+
}
|
|
3442
|
+
__name(getGlobalProfiler, "getGlobalProfiler");
|
|
3443
|
+
|
|
3444
|
+
// src/core/index.ts
|
|
3445
|
+
var import_zod2 = require("zod");
|
|
3446
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
3447
|
+
0 && (module.exports = {
|
|
3448
|
+
AUTOWIRED_METADATA,
|
|
3449
|
+
AbstractClass,
|
|
3450
|
+
AbstractConfigProvider,
|
|
3451
|
+
Autowired,
|
|
3452
|
+
BadGatewayException,
|
|
3453
|
+
BadRequestException,
|
|
3454
|
+
Body,
|
|
3455
|
+
CATCH_METADATA,
|
|
3456
|
+
CONFIG_PROPERTY_METADATA,
|
|
3457
|
+
CONFIG_PROVIDER_METADATA,
|
|
3458
|
+
CONTROLLER_METADATA,
|
|
3459
|
+
CUSTOM_PARAM_METADATA,
|
|
3460
|
+
Catch,
|
|
3461
|
+
ConfigProperty,
|
|
3462
|
+
ConfigProviderAlreadyRegisteredException,
|
|
3463
|
+
ConfigProviderInstantiationException,
|
|
3464
|
+
ConfigProviderNotFoundException,
|
|
3465
|
+
ConfigValidationException,
|
|
3466
|
+
ConflictException,
|
|
3467
|
+
Container,
|
|
3468
|
+
Context,
|
|
3469
|
+
Controller,
|
|
3470
|
+
Ctx,
|
|
3471
|
+
DEFAULT_CONFIG,
|
|
3472
|
+
Delete,
|
|
3473
|
+
DiscoveryException,
|
|
3474
|
+
EventBus,
|
|
3475
|
+
ExecutionContextImpl,
|
|
3476
|
+
ForbiddenException,
|
|
3477
|
+
GUARDS_METADATA,
|
|
3478
|
+
GatewayTimeoutException,
|
|
3479
|
+
Get,
|
|
3480
|
+
GlobalExceptionFilter,
|
|
3481
|
+
GoneException,
|
|
3482
|
+
HEADERS_METADATA,
|
|
3483
|
+
HTTP_CODE_METADATA,
|
|
3484
|
+
Head,
|
|
3485
|
+
Headers,
|
|
3486
|
+
HttpCode,
|
|
3487
|
+
HttpException,
|
|
3488
|
+
IMPLEMENTS_METADATA,
|
|
3489
|
+
INJECTABLE_METADATA,
|
|
3490
|
+
INJECT_METADATA,
|
|
3491
|
+
INTERCEPTORS_METADATA,
|
|
3492
|
+
Implements,
|
|
3493
|
+
Injectable,
|
|
3494
|
+
InjectionToken,
|
|
3495
|
+
InternalServerErrorException,
|
|
3496
|
+
MIDDLEWARE_METADATA,
|
|
3497
|
+
MethodNotAllowedException,
|
|
3498
|
+
Middleware,
|
|
3499
|
+
Named,
|
|
3500
|
+
NotAcceptableException,
|
|
3501
|
+
NotFoundException,
|
|
3502
|
+
NotImplementedException,
|
|
3503
|
+
ON_EVENT_METADATA,
|
|
3504
|
+
On,
|
|
3505
|
+
Optional,
|
|
3506
|
+
Options,
|
|
3507
|
+
PARAM_METADATA,
|
|
3508
|
+
PRIMARY_METADATA,
|
|
3509
|
+
PROVIDER_METADATA,
|
|
3510
|
+
Param,
|
|
3511
|
+
ParamType,
|
|
3512
|
+
Patch,
|
|
3513
|
+
PayloadTooLargeException,
|
|
3514
|
+
PerformanceProfiler,
|
|
3515
|
+
Post,
|
|
3516
|
+
Primary,
|
|
3517
|
+
Provider,
|
|
3518
|
+
Put,
|
|
3519
|
+
Query,
|
|
3520
|
+
ROUTES_METADATA,
|
|
3521
|
+
Registry,
|
|
3522
|
+
Reply,
|
|
3523
|
+
Req,
|
|
3524
|
+
Request,
|
|
3525
|
+
RequestScopeStorage,
|
|
3526
|
+
RequestTimeoutException,
|
|
3527
|
+
Res,
|
|
3528
|
+
Rikta,
|
|
3529
|
+
RiktaFactory,
|
|
3530
|
+
Router,
|
|
3531
|
+
ServiceUnavailableException,
|
|
3532
|
+
SetMetadata,
|
|
3533
|
+
TooManyRequestsException,
|
|
3534
|
+
UnauthorizedException,
|
|
3535
|
+
UnprocessableEntityException,
|
|
3536
|
+
UnsupportedMediaTypeException,
|
|
3537
|
+
UseGuards,
|
|
3538
|
+
UseInterceptors,
|
|
3539
|
+
UseMiddleware,
|
|
3540
|
+
ValidationException,
|
|
3541
|
+
ZOD_SCHEMA_METADATA,
|
|
3542
|
+
applyDecorators,
|
|
3543
|
+
clearPropertyNameCache,
|
|
3544
|
+
container,
|
|
3545
|
+
createExceptionHandler,
|
|
3546
|
+
createParamDecorator,
|
|
3547
|
+
discoverModules,
|
|
3548
|
+
extendsFrom,
|
|
3549
|
+
getCallerDirectory,
|
|
3550
|
+
getCatchMetadata,
|
|
3551
|
+
getClassMetadata,
|
|
3552
|
+
getConfigPropertyMappings,
|
|
3553
|
+
getConfigProviderMetadata,
|
|
3554
|
+
getControllerMetadata,
|
|
3555
|
+
getControllerPath,
|
|
3556
|
+
getCustomParamMetadata,
|
|
3557
|
+
getGlobalProfiler,
|
|
3558
|
+
getGuards,
|
|
3559
|
+
getGuardsMetadata,
|
|
3560
|
+
getHttpCode,
|
|
3561
|
+
getImplementedAbstract,
|
|
3562
|
+
getInterceptorsMetadata,
|
|
3563
|
+
getMethodMetadata,
|
|
3564
|
+
getMethodsWithMetadata,
|
|
3565
|
+
getMiddlewareMetadata,
|
|
3566
|
+
getMiddlewaresMetadata,
|
|
3567
|
+
getParamMetadata,
|
|
3568
|
+
getParamMetadataByIndex,
|
|
3569
|
+
getRoutes,
|
|
3570
|
+
getZodSchema,
|
|
3571
|
+
hasClassMetadata,
|
|
3572
|
+
hasConfigProperties,
|
|
3573
|
+
hasMethodMetadata,
|
|
3574
|
+
hasRoutes,
|
|
3575
|
+
isAbstractClass,
|
|
3576
|
+
isConfigProvider,
|
|
3577
|
+
isController,
|
|
3578
|
+
isEnvLoaded,
|
|
3579
|
+
isPrimaryImplementation,
|
|
3580
|
+
loadEnvFiles,
|
|
3581
|
+
markAsAbstract,
|
|
3582
|
+
profiler,
|
|
3583
|
+
registry,
|
|
3584
|
+
requestScopeStorage,
|
|
3585
|
+
resetEnvLoaded,
|
|
3586
|
+
setGlobalProfiler,
|
|
3587
|
+
setImplementsMetadata,
|
|
3588
|
+
setPrimaryMetadata,
|
|
3589
|
+
z
|
|
3590
|
+
});
|
|
3591
|
+
//# sourceMappingURL=index.cjs.map
|