@haskou/ddd-kernel 0.1.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -115
- package/dist/DomainEventConsumer-Bg-bOwmh.d.cts +11 -0
- package/dist/DomainEventConsumer-BroJmVty.d.ts +11 -0
- package/dist/DomainMessageBus-3jYk7TPw.d.ts +13 -0
- package/dist/DomainMessageBus-OyliPu3Z.d.cts +13 -0
- package/dist/MessageBus-BtUXnd0Y.d.cts +10 -0
- package/dist/MessageBus-oQ9BnW84.d.ts +10 -0
- package/dist/{NoFailedMessagesError-0YJKRWPF.d.ts → NoFailedMessagesError-BLpGI-G4.d.ts} +6 -1
- package/dist/{NoFailedMessagesError-Kz7CYWpT.d.cts → NoFailedMessagesError-BjxYoKTR.d.cts} +6 -1
- package/dist/PublisherHookErrorPolicy-CjouTcSR.d.cts +8 -0
- package/dist/PublisherHookErrorPolicy-DSsCNE6O.d.ts +8 -0
- package/dist/RetryPredicate-U7dYnQ4N.d.ts +15 -0
- package/dist/RetryPredicate-yT_z9zk1.d.cts +15 -0
- package/dist/{Scheduler-oigqNOUJ.d.ts → Scheduler-BW-U5Ccg.d.cts} +1 -1
- package/dist/{Scheduler-oigqNOUJ.d.cts → Scheduler-BW-U5Ccg.d.ts} +1 -1
- package/dist/ServiceClass-BkEHcXDi.d.cts +72 -0
- package/dist/ServiceClass-Bq_fBC5R.d.ts +72 -0
- package/dist/{Kernel-BWUOUWWI.d.cts → ShutdownHook-BjbnCKzr.d.cts} +49 -7
- package/dist/{Kernel-CUaqHa1s.d.ts → ShutdownHook-CMWLsfu-.d.ts} +49 -7
- package/dist/Subscription-4vuAAxax.d.cts +23 -0
- package/dist/Subscription-vtF0lEHP.d.ts +23 -0
- package/dist/adapters/index.cjs +665 -37
- package/dist/adapters/index.cjs.map +1 -1
- package/dist/adapters/index.d.cts +15 -13
- package/dist/adapters/index.d.ts +15 -13
- package/dist/adapters/index.js +659 -37
- package/dist/adapters/index.js.map +1 -1
- package/dist/adapters/pubsub/amqp/index.cjs +241 -16
- package/dist/adapters/pubsub/amqp/index.cjs.map +1 -1
- package/dist/adapters/pubsub/amqp/index.d.cts +16 -8
- package/dist/adapters/pubsub/amqp/index.d.ts +16 -8
- package/dist/adapters/pubsub/amqp/index.js +241 -16
- package/dist/adapters/pubsub/amqp/index.js.map +1 -1
- package/dist/adapters/pubsub/in-memory/index.cjs +96 -8
- package/dist/adapters/pubsub/in-memory/index.cjs.map +1 -1
- package/dist/adapters/pubsub/in-memory/index.d.cts +9 -3
- package/dist/adapters/pubsub/in-memory/index.d.ts +9 -3
- package/dist/adapters/pubsub/in-memory/index.js +96 -8
- package/dist/adapters/pubsub/in-memory/index.js.map +1 -1
- package/dist/adapters/pubsub/index.cjs +397 -27
- package/dist/adapters/pubsub/index.cjs.map +1 -1
- package/dist/adapters/pubsub/index.d.cts +89 -7
- package/dist/adapters/pubsub/index.d.ts +89 -7
- package/dist/adapters/pubsub/index.js +389 -26
- package/dist/adapters/pubsub/index.js.map +1 -1
- package/dist/adapters/ui/express/index.cjs +279 -11
- package/dist/adapters/ui/express/index.cjs.map +1 -1
- package/dist/adapters/ui/express/index.d.cts +127 -12
- package/dist/adapters/ui/express/index.d.ts +127 -12
- package/dist/adapters/ui/express/index.js +270 -11
- package/dist/adapters/ui/express/index.js.map +1 -1
- package/dist/adapters/ui/index.cjs +412 -27
- package/dist/adapters/ui/index.cjs.map +1 -1
- package/dist/adapters/ui/index.d.cts +7 -8
- package/dist/adapters/ui/index.d.ts +7 -8
- package/dist/adapters/ui/index.js +413 -27
- package/dist/adapters/ui/index.js.map +1 -1
- package/dist/adapters/ui/routes/index.cjs +136 -9
- package/dist/adapters/ui/routes/index.cjs.map +1 -1
- package/dist/adapters/ui/routes/index.js +136 -9
- package/dist/adapters/ui/routes/index.js.map +1 -1
- package/dist/contracts/index.cjs +16 -17
- package/dist/contracts/index.cjs.map +1 -1
- package/dist/contracts/index.d.cts +10 -2
- package/dist/contracts/index.d.ts +10 -2
- package/dist/contracts/index.js +16 -17
- package/dist/contracts/index.js.map +1 -1
- package/dist/contracts/kernel/index.cjs.map +1 -1
- package/dist/contracts/kernel/index.d.cts +7 -1
- package/dist/contracts/kernel/index.d.ts +7 -1
- package/dist/contracts/pubsub/index.cjs.map +1 -1
- package/dist/contracts/pubsub/index.d.cts +5 -1
- package/dist/contracts/pubsub/index.d.ts +5 -1
- package/dist/contracts/ui/index.cjs +16 -17
- package/dist/contracts/ui/index.cjs.map +1 -1
- package/dist/contracts/ui/index.d.cts +16 -16
- package/dist/contracts/ui/index.d.ts +16 -16
- package/dist/contracts/ui/index.js +16 -17
- package/dist/contracts/ui/index.js.map +1 -1
- package/dist/domain/index.cjs.map +1 -1
- package/dist/domain/index.d.cts +6 -2
- package/dist/domain/index.d.ts +6 -2
- package/dist/domain/index.js.map +1 -1
- package/dist/index.cjs +152 -26
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -7
- package/dist/index.d.ts +8 -7
- package/dist/index.js +152 -26
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/dependency-injection/index.cjs +119 -3
- package/dist/infrastructure/dependency-injection/index.cjs.map +1 -1
- package/dist/infrastructure/dependency-injection/index.d.cts +4 -1
- package/dist/infrastructure/dependency-injection/index.d.ts +4 -1
- package/dist/infrastructure/dependency-injection/index.js +119 -3
- package/dist/infrastructure/dependency-injection/index.js.map +1 -1
- package/dist/infrastructure/express/index.cjs +279 -11
- package/dist/infrastructure/express/index.cjs.map +1 -1
- package/dist/infrastructure/express/index.d.cts +7 -8
- package/dist/infrastructure/express/index.d.ts +7 -8
- package/dist/infrastructure/express/index.js +270 -11
- package/dist/infrastructure/express/index.js.map +1 -1
- package/dist/infrastructure/scheduler/index.cjs +136 -9
- package/dist/infrastructure/scheduler/index.cjs.map +1 -1
- package/dist/infrastructure/scheduler/index.d.cts +2 -2
- package/dist/infrastructure/scheduler/index.d.ts +2 -2
- package/dist/infrastructure/scheduler/index.js +136 -9
- package/dist/infrastructure/scheduler/index.js.map +1 -1
- package/package.json +101 -11
- package/dist/Consumer-CC8ZRCsd.d.cts +0 -17
- package/dist/Consumer-CeT0Wbxb.d.ts +0 -17
- package/dist/DomainEventConsumer-3WBMSSr2.d.cts +0 -7
- package/dist/DomainEventConsumer-B4hkIUmP.d.ts +0 -7
- package/dist/DomainEventPublisher-8G0lvmdy.d.cts +0 -7
- package/dist/DomainEventPublisher-DhGgM3f2.d.ts +0 -7
- package/dist/ServiceClass-BmNw8fJj.d.cts +0 -37
- package/dist/ServiceClass-C7NCKdSS.d.ts +0 -37
- package/dist/ShutdownHook-BGskq2-q.d.ts +0 -9
- package/dist/ShutdownHook-Dib5uNKB.d.cts +0 -9
- package/dist/Subscription-Bwkb_did.d.ts +0 -9
- package/dist/Subscription-P9WROD_6.d.cts +0 -9
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { D as DependencyInjection, a as DependencyInjectionOptions, S as ServiceClass } from '../../ServiceClass-
|
|
1
|
+
export { C as ClassDependencyOverride, D as DependencyInjection, a as DependencyInjectionOptions, b as DependencyOverride, c as DependencyOverrideFactory, d as DependencyOverrideToken, F as FactoryDependencyOverride, S as ServiceClass, V as ValueDependencyOverride } from '../../ServiceClass-BkEHcXDi.cjs';
|
|
2
2
|
import '../../ServiceResolver-D2Jz-l_Z.cjs';
|
|
3
3
|
|
|
4
4
|
type ExplicitServiceClass = {
|
|
@@ -11,6 +11,9 @@ type ContainerDefinition = {
|
|
|
11
11
|
|
|
12
12
|
type DefinitionMetadata = {
|
|
13
13
|
readonly _abstract?: boolean;
|
|
14
|
+
readonly _appendArgs?: unknown[];
|
|
15
|
+
readonly _args?: unknown[];
|
|
16
|
+
readonly _overrideArgs?: unknown[];
|
|
14
17
|
readonly _parent?: string | null;
|
|
15
18
|
};
|
|
16
19
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { D as DependencyInjection, a as DependencyInjectionOptions, S as ServiceClass } from '../../ServiceClass-
|
|
1
|
+
export { C as ClassDependencyOverride, D as DependencyInjection, a as DependencyInjectionOptions, b as DependencyOverride, c as DependencyOverrideFactory, d as DependencyOverrideToken, F as FactoryDependencyOverride, S as ServiceClass, V as ValueDependencyOverride } from '../../ServiceClass-Bq_fBC5R.js';
|
|
2
2
|
import '../../ServiceResolver-D2Jz-l_Z.js';
|
|
3
3
|
|
|
4
4
|
type ExplicitServiceClass = {
|
|
@@ -11,6 +11,9 @@ type ContainerDefinition = {
|
|
|
11
11
|
|
|
12
12
|
type DefinitionMetadata = {
|
|
13
13
|
readonly _abstract?: boolean;
|
|
14
|
+
readonly _appendArgs?: unknown[];
|
|
15
|
+
readonly _args?: unknown[];
|
|
16
|
+
readonly _overrideArgs?: unknown[];
|
|
14
17
|
readonly _parent?: string | null;
|
|
15
18
|
};
|
|
16
19
|
|
|
@@ -26,6 +26,7 @@ var DependencyInjection = class _DependencyInjection {
|
|
|
26
26
|
autowire;
|
|
27
27
|
loader;
|
|
28
28
|
container;
|
|
29
|
+
overrideTokenIds = /* @__PURE__ */ new Map();
|
|
29
30
|
static configure(options) {
|
|
30
31
|
_DependencyInjection.configuredInstance = new _DependencyInjection(options);
|
|
31
32
|
return _DependencyInjection.configuredInstance;
|
|
@@ -50,6 +51,16 @@ var DependencyInjection = class _DependencyInjection {
|
|
|
50
51
|
getServiceClassName(serviceName) {
|
|
51
52
|
return typeof serviceName === "function" ? serviceName.name : void 0;
|
|
52
53
|
}
|
|
54
|
+
getOverrideId(prefix, token) {
|
|
55
|
+
const tokenName = this.getServiceClassName(token) ?? String(token);
|
|
56
|
+
return `ddd-kernel.override.${prefix}.${tokenName}`;
|
|
57
|
+
}
|
|
58
|
+
ensureSyntheticService(id, value) {
|
|
59
|
+
const definition = this.container.register(id);
|
|
60
|
+
definition.public = true;
|
|
61
|
+
definition.synthetic = true;
|
|
62
|
+
this.container.set(id, value);
|
|
63
|
+
}
|
|
53
64
|
parentMatchesService(parentId, serviceClassName) {
|
|
54
65
|
if (!parentId) {
|
|
55
66
|
return false;
|
|
@@ -61,6 +72,26 @@ var DependencyInjection = class _DependencyInjection {
|
|
|
61
72
|
const serviceName = Buffer.from(serviceId, "base64").toString("utf8");
|
|
62
73
|
return serviceName.endsWith(`__${serviceClassName}__${serviceClassName}`);
|
|
63
74
|
}
|
|
75
|
+
serviceIdReferencesService(serviceId, serviceClassName) {
|
|
76
|
+
const serviceName = Buffer.from(serviceId, "base64").toString("utf8");
|
|
77
|
+
return serviceName.endsWith(`__${serviceClassName}`);
|
|
78
|
+
}
|
|
79
|
+
getReferenceId(value) {
|
|
80
|
+
if (typeof value === "object" && value !== null && "id" in value && typeof value.id === "string") {
|
|
81
|
+
return value.id;
|
|
82
|
+
}
|
|
83
|
+
return void 0;
|
|
84
|
+
}
|
|
85
|
+
getDefinitionArgumentReferences(definition) {
|
|
86
|
+
return [
|
|
87
|
+
...definition._args ?? [],
|
|
88
|
+
...definition._appendArgs ?? [],
|
|
89
|
+
...definition._overrideArgs ?? []
|
|
90
|
+
].flatMap((argument) => {
|
|
91
|
+
const referenceId = this.getReferenceId(argument);
|
|
92
|
+
return referenceId ? [referenceId] : [];
|
|
93
|
+
});
|
|
94
|
+
}
|
|
64
95
|
findConcreteChildServiceId(serviceName) {
|
|
65
96
|
const serviceClassName = this.getServiceClassName(serviceName);
|
|
66
97
|
if (!serviceClassName) {
|
|
@@ -91,6 +122,86 @@ var DependencyInjection = class _DependencyInjection {
|
|
|
91
122
|
);
|
|
92
123
|
return matches[matches.length - 1];
|
|
93
124
|
}
|
|
125
|
+
findReferencedServiceIds(serviceName) {
|
|
126
|
+
const serviceClassName = this.getServiceClassName(serviceName);
|
|
127
|
+
if (!serviceClassName) {
|
|
128
|
+
return [];
|
|
129
|
+
}
|
|
130
|
+
return [
|
|
131
|
+
...new Set(
|
|
132
|
+
[...this.definitions.values()].flatMap(
|
|
133
|
+
(definition) => this.getDefinitionArgumentReferences(definition)
|
|
134
|
+
).filter(
|
|
135
|
+
(id) => this.serviceIdReferencesService(id, serviceClassName)
|
|
136
|
+
)
|
|
137
|
+
)
|
|
138
|
+
];
|
|
139
|
+
}
|
|
140
|
+
getOverrideTokenIds(token) {
|
|
141
|
+
const tokenIds = [
|
|
142
|
+
this.findRegisteredServiceId(token),
|
|
143
|
+
this.findAliasServiceId(token),
|
|
144
|
+
...this.findReferencedServiceIds(token)
|
|
145
|
+
].filter((id) => id !== void 0);
|
|
146
|
+
const existingTokenIds = [...new Set(tokenIds)];
|
|
147
|
+
if (existingTokenIds.length > 0) {
|
|
148
|
+
return existingTokenIds;
|
|
149
|
+
}
|
|
150
|
+
const overrideTokenId = this.getOverrideId("token", token);
|
|
151
|
+
this.ensureSyntheticService(overrideTokenId, void 0);
|
|
152
|
+
return [overrideTokenId];
|
|
153
|
+
}
|
|
154
|
+
getOverrideClassServiceId(ClassDefinition) {
|
|
155
|
+
const registeredServiceId = this.findRegisteredServiceId(ClassDefinition);
|
|
156
|
+
if (registeredServiceId) {
|
|
157
|
+
return registeredServiceId;
|
|
158
|
+
}
|
|
159
|
+
const overrideClassId = this.getOverrideId("class", ClassDefinition);
|
|
160
|
+
this.container.register(overrideClassId, ClassDefinition);
|
|
161
|
+
return overrideClassId;
|
|
162
|
+
}
|
|
163
|
+
applyClassOverride(override) {
|
|
164
|
+
if (!("useClass" in override)) {
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
const tokenIds = this.getOverrideTokenIds(override.token);
|
|
168
|
+
const classId = this.getOverrideClassServiceId(override.useClass);
|
|
169
|
+
this.overrideTokenIds.set(override.token, tokenIds[0]);
|
|
170
|
+
for (const tokenId of tokenIds) {
|
|
171
|
+
this.container.setAlias(tokenId, classId);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
applyFactoryOverride(override) {
|
|
175
|
+
if (!("useFactory" in override)) {
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
const tokenIds = this.getOverrideTokenIds(override.token);
|
|
179
|
+
const factoryId = this.getOverrideId("factory", override.token);
|
|
180
|
+
this.ensureSyntheticService(factoryId, override.useFactory(this));
|
|
181
|
+
this.overrideTokenIds.set(override.token, tokenIds[0]);
|
|
182
|
+
for (const tokenId of tokenIds) {
|
|
183
|
+
this.container.setAlias(tokenId, factoryId);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
applyValueOverride(override) {
|
|
187
|
+
if (!("useValue" in override)) {
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
const tokenIds = this.getOverrideTokenIds(override.token);
|
|
191
|
+
const valueId = this.getOverrideId("value", override.token);
|
|
192
|
+
this.ensureSyntheticService(valueId, override.useValue);
|
|
193
|
+
this.overrideTokenIds.set(override.token, tokenIds[0]);
|
|
194
|
+
for (const tokenId of tokenIds) {
|
|
195
|
+
this.container.setAlias(tokenId, valueId);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
applyOverrides() {
|
|
199
|
+
for (const override of this.options.overrides ?? []) {
|
|
200
|
+
this.applyClassOverride(override);
|
|
201
|
+
this.applyFactoryOverride(override);
|
|
202
|
+
this.applyValueOverride(override);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
94
205
|
registerParentAliases() {
|
|
95
206
|
for (const [id, definition] of this.definitions.entries()) {
|
|
96
207
|
if (definition._abstract === true || !definition._parent) {
|
|
@@ -113,17 +224,22 @@ var DependencyInjection = class _DependencyInjection {
|
|
|
113
224
|
await this.loader.load(this.options.servicesYamlPath);
|
|
114
225
|
}
|
|
115
226
|
this.registerParentAliases();
|
|
227
|
+
this.applyOverrides();
|
|
116
228
|
await this.container.compile();
|
|
117
229
|
}
|
|
118
230
|
getService(serviceName) {
|
|
119
|
-
const
|
|
120
|
-
if (
|
|
121
|
-
return this.container.get(
|
|
231
|
+
const overrideTokenId = this.overrideTokenIds.get(serviceName);
|
|
232
|
+
if (overrideTokenId) {
|
|
233
|
+
return this.container.get(overrideTokenId);
|
|
122
234
|
}
|
|
123
235
|
const aliasServiceId = this.findAliasServiceId(serviceName);
|
|
124
236
|
if (aliasServiceId) {
|
|
125
237
|
return this.container.get(aliasServiceId);
|
|
126
238
|
}
|
|
239
|
+
const childServiceId = this.findConcreteChildServiceId(serviceName);
|
|
240
|
+
if (childServiceId) {
|
|
241
|
+
return this.container.get(childServiceId);
|
|
242
|
+
}
|
|
127
243
|
const registeredServiceId = this.findRegisteredServiceId(serviceName);
|
|
128
244
|
if (registeredServiceId) {
|
|
129
245
|
return this.container.get(registeredServiceId);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/infrastructure/dependency-injection/DependencyInjection.ts"],"sourcesContent":["import fs from 'fs-extra';\nimport {\n Autowire,\n ContainerBuilder,\n ServiceFile,\n YamlFileLoader,\n} from 'node-dependency-injection';\nimport path from 'node:path';\n\nimport type { ServiceResolver } from '../../contracts/index.js';\nimport type { ContainerInternals } from './ContainerInternals.js';\nimport type { DefinitionMetadata } from './DefinitionMetadata.js';\nimport type { DependencyInjectionOptions } from './DependencyInjectionOptions.js';\n\nexport class DependencyInjection implements ServiceResolver {\n private static configuredInstance: DependencyInjection | undefined;\n private autowire: Autowire | undefined;\n private loader: YamlFileLoader | undefined;\n private readonly container: ContainerBuilder;\n\n public static configure(\n options: DependencyInjectionOptions,\n ): DependencyInjection {\n DependencyInjection.configuredInstance = new DependencyInjection(options);\n\n return DependencyInjection.configuredInstance;\n }\n\n public static get instance(): DependencyInjection {\n if (!DependencyInjection.configuredInstance) {\n throw new Error('DependencyInjection has not been configured.');\n }\n\n return DependencyInjection.configuredInstance;\n }\n\n constructor(\n private readonly options: DependencyInjectionOptions = {\n containerBuild: process.env.CONTAINER_BUILD === 'true',\n servicesYamlPath: path.resolve(\n process.cwd(),\n 'config',\n 'container',\n 'services.yaml',\n ),\n sourceDirectory: path.resolve(process.cwd(), 'src'),\n },\n ) {\n this.container = new ContainerBuilder(false, this.options.sourceDirectory);\n }\n\n private get definitions(): Map<string, DefinitionMetadata> {\n const container = this.container as unknown as ContainerInternals;\n\n return container._definitions || new Map();\n }\n\n private get aliases(): Map<string, string> {\n const container = this.container as unknown as ContainerInternals;\n\n return container._alias || new Map();\n }\n\n private async ensureFolderExists(filePath: string): Promise<void> {\n await fs.mkdir(path.dirname(filePath), { recursive: true });\n }\n\n private getServiceClassName(serviceName: unknown): string | undefined {\n return typeof serviceName === 'function' ? serviceName.name : undefined;\n }\n\n private parentMatchesService(\n parentId: string | null | undefined,\n serviceClassName: string,\n ): boolean {\n if (!parentId) {\n return false;\n }\n\n const parentName = Buffer.from(parentId, 'base64').toString('utf8');\n\n return parentName.endsWith(`__${serviceClassName}__${serviceClassName}`);\n }\n\n private serviceIdMatchesService(\n serviceId: string,\n serviceClassName: string,\n ): boolean {\n const serviceName = Buffer.from(serviceId, 'base64').toString('utf8');\n\n return serviceName.endsWith(`__${serviceClassName}__${serviceClassName}`);\n }\n\n private findConcreteChildServiceId(serviceName: unknown): string | undefined {\n const serviceClassName = this.getServiceClassName(serviceName);\n\n if (!serviceClassName) {\n return undefined;\n }\n\n const matches = [...this.definitions.entries()]\n .filter(([, definition]) => definition._abstract !== true)\n .filter(([, definition]) =>\n this.parentMatchesService(definition._parent, serviceClassName),\n )\n .map(([id]) => id);\n\n return matches[matches.length - 1];\n }\n\n private findRegisteredServiceId(serviceName: unknown): string | undefined {\n const serviceClassName = this.getServiceClassName(serviceName);\n\n if (!serviceClassName) {\n return undefined;\n }\n\n const matches = [...this.definitions.keys()].filter((id) =>\n this.serviceIdMatchesService(id, serviceClassName),\n );\n\n return matches[matches.length - 1];\n }\n\n private findAliasServiceId(serviceName: unknown): string | undefined {\n const serviceClassName = this.getServiceClassName(serviceName);\n\n if (!serviceClassName) {\n return undefined;\n }\n\n const matches = [...this.aliases.keys()].filter((id) =>\n this.serviceIdMatchesService(id, serviceClassName),\n );\n\n return matches[matches.length - 1];\n }\n\n private registerParentAliases(): void {\n for (const [id, definition] of this.definitions.entries()) {\n if (definition._abstract === true || !definition._parent) {\n continue;\n }\n\n this.container.setAlias(definition._parent, id);\n }\n }\n\n public async compile(): Promise<void> {\n if (this.options.containerBuild) {\n await this.ensureFolderExists(this.options.servicesYamlPath);\n this.autowire = new Autowire(this.container);\n this.autowire.serviceFile = new ServiceFile(\n this.options.servicesYamlPath,\n false,\n );\n await this.autowire.process();\n } else {\n this.loader = new YamlFileLoader(this.container);\n await this.loader.load(this.options.servicesYamlPath);\n }\n\n this.registerParentAliases();\n await this.container.compile();\n }\n\n public getService<T>(serviceName: unknown): T {\n const childServiceId = this.findConcreteChildServiceId(serviceName);\n\n if (childServiceId) {\n return this.container.get<T>(childServiceId);\n }\n\n const aliasServiceId = this.findAliasServiceId(serviceName);\n\n if (aliasServiceId) {\n return this.container.get<T>(aliasServiceId);\n }\n\n const registeredServiceId = this.findRegisteredServiceId(serviceName);\n\n if (registeredServiceId) {\n return this.container.get<T>(registeredServiceId);\n }\n\n return this.container.get<T>(serviceName);\n }\n}\n\nexport default DependencyInjection;\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/infrastructure/dependency-injection/DependencyInjection.ts"],"sourcesContent":["import fs from 'fs-extra';\nimport {\n Autowire,\n ContainerBuilder,\n ServiceFile,\n YamlFileLoader,\n} from 'node-dependency-injection';\nimport path from 'node:path';\n\nimport type { ServiceResolver } from '../../contracts/index.js';\nimport type { ContainerInternals } from './ContainerInternals.js';\nimport type { DefinitionMetadata } from './DefinitionMetadata.js';\nimport type { DependencyInjectionOptions } from './DependencyInjectionOptions.js';\nimport type { DependencyOverride } from './DependencyOverride.js';\n\nexport class DependencyInjection implements ServiceResolver {\n private static configuredInstance: DependencyInjection | undefined;\n private autowire: Autowire | undefined;\n private loader: YamlFileLoader | undefined;\n private readonly container: ContainerBuilder;\n private readonly overrideTokenIds = new Map<unknown, string>();\n\n public static configure(\n options: DependencyInjectionOptions,\n ): DependencyInjection {\n DependencyInjection.configuredInstance = new DependencyInjection(options);\n\n return DependencyInjection.configuredInstance;\n }\n\n public static get instance(): DependencyInjection {\n if (!DependencyInjection.configuredInstance) {\n throw new Error('DependencyInjection has not been configured.');\n }\n\n return DependencyInjection.configuredInstance;\n }\n\n constructor(\n private readonly options: DependencyInjectionOptions = {\n containerBuild: process.env.CONTAINER_BUILD === 'true',\n servicesYamlPath: path.resolve(\n process.cwd(),\n 'config',\n 'container',\n 'services.yaml',\n ),\n sourceDirectory: path.resolve(process.cwd(), 'src'),\n },\n ) {\n this.container = new ContainerBuilder(false, this.options.sourceDirectory);\n }\n\n private get definitions(): Map<string, DefinitionMetadata> {\n const container = this.container as unknown as ContainerInternals;\n\n return container._definitions || new Map();\n }\n\n private get aliases(): Map<string, string> {\n const container = this.container as unknown as ContainerInternals;\n\n return container._alias || new Map();\n }\n\n private async ensureFolderExists(filePath: string): Promise<void> {\n await fs.mkdir(path.dirname(filePath), { recursive: true });\n }\n\n private getServiceClassName(serviceName: unknown): string | undefined {\n return typeof serviceName === 'function' ? serviceName.name : undefined;\n }\n\n private getOverrideId(prefix: string, token: unknown): string {\n const tokenName = this.getServiceClassName(token) ?? String(token);\n\n return `ddd-kernel.override.${prefix}.${tokenName}`;\n }\n\n private ensureSyntheticService(id: string, value: unknown): void {\n const definition = this.container.register(id);\n\n definition.public = true;\n definition.synthetic = true;\n this.container.set(id, value);\n }\n\n private parentMatchesService(\n parentId: string | null | undefined,\n serviceClassName: string,\n ): boolean {\n if (!parentId) {\n return false;\n }\n\n const parentName = Buffer.from(parentId, 'base64').toString('utf8');\n\n return parentName.endsWith(`__${serviceClassName}__${serviceClassName}`);\n }\n\n private serviceIdMatchesService(\n serviceId: string,\n serviceClassName: string,\n ): boolean {\n const serviceName = Buffer.from(serviceId, 'base64').toString('utf8');\n\n return serviceName.endsWith(`__${serviceClassName}__${serviceClassName}`);\n }\n\n private serviceIdReferencesService(\n serviceId: string,\n serviceClassName: string,\n ): boolean {\n const serviceName = Buffer.from(serviceId, 'base64').toString('utf8');\n\n return serviceName.endsWith(`__${serviceClassName}`);\n }\n\n private getReferenceId(value: unknown): string | undefined {\n if (\n typeof value === 'object' &&\n value !== null &&\n 'id' in value &&\n typeof value.id === 'string'\n ) {\n return value.id;\n }\n\n return undefined;\n }\n\n private getDefinitionArgumentReferences(\n definition: DefinitionMetadata,\n ): string[] {\n return [\n ...(definition._args ?? []),\n ...(definition._appendArgs ?? []),\n ...(definition._overrideArgs ?? []),\n ].flatMap((argument) => {\n const referenceId = this.getReferenceId(argument);\n\n return referenceId ? [referenceId] : [];\n });\n }\n\n private findConcreteChildServiceId(serviceName: unknown): string | undefined {\n const serviceClassName = this.getServiceClassName(serviceName);\n\n if (!serviceClassName) {\n return undefined;\n }\n\n const matches = [...this.definitions.entries()]\n .filter(([, definition]) => definition._abstract !== true)\n .filter(([, definition]) =>\n this.parentMatchesService(definition._parent, serviceClassName),\n )\n .map(([id]) => id);\n\n return matches[matches.length - 1];\n }\n\n private findRegisteredServiceId(serviceName: unknown): string | undefined {\n const serviceClassName = this.getServiceClassName(serviceName);\n\n if (!serviceClassName) {\n return undefined;\n }\n\n const matches = [...this.definitions.keys()].filter((id) =>\n this.serviceIdMatchesService(id, serviceClassName),\n );\n\n return matches[matches.length - 1];\n }\n\n private findAliasServiceId(serviceName: unknown): string | undefined {\n const serviceClassName = this.getServiceClassName(serviceName);\n\n if (!serviceClassName) {\n return undefined;\n }\n\n const matches = [...this.aliases.keys()].filter((id) =>\n this.serviceIdMatchesService(id, serviceClassName),\n );\n\n return matches[matches.length - 1];\n }\n\n private findReferencedServiceIds(serviceName: unknown): string[] {\n const serviceClassName = this.getServiceClassName(serviceName);\n\n if (!serviceClassName) {\n return [];\n }\n\n return [\n ...new Set(\n [...this.definitions.values()]\n .flatMap((definition) =>\n this.getDefinitionArgumentReferences(definition),\n )\n .filter((id) =>\n this.serviceIdReferencesService(id, serviceClassName),\n ),\n ),\n ];\n }\n\n private getOverrideTokenIds(token: unknown): string[] {\n const tokenIds = [\n this.findRegisteredServiceId(token),\n this.findAliasServiceId(token),\n ...this.findReferencedServiceIds(token),\n ].filter((id): id is string => id !== undefined);\n const existingTokenIds = [...new Set(tokenIds)];\n\n if (existingTokenIds.length > 0) {\n return existingTokenIds;\n }\n\n const overrideTokenId = this.getOverrideId('token', token);\n\n this.ensureSyntheticService(overrideTokenId, undefined);\n\n return [overrideTokenId];\n }\n\n private getOverrideClassServiceId(\n ClassDefinition: new () => unknown,\n ): string {\n const registeredServiceId = this.findRegisteredServiceId(ClassDefinition);\n\n if (registeredServiceId) {\n return registeredServiceId;\n }\n\n const overrideClassId = this.getOverrideId('class', ClassDefinition);\n\n this.container.register(overrideClassId, ClassDefinition);\n\n return overrideClassId;\n }\n\n private applyClassOverride(override: DependencyOverride): void {\n if (!('useClass' in override)) {\n return;\n }\n\n const tokenIds = this.getOverrideTokenIds(override.token);\n const classId = this.getOverrideClassServiceId(override.useClass);\n\n this.overrideTokenIds.set(override.token, tokenIds[0]);\n for (const tokenId of tokenIds) {\n this.container.setAlias(tokenId, classId);\n }\n }\n\n private applyFactoryOverride(override: DependencyOverride): void {\n if (!('useFactory' in override)) {\n return;\n }\n\n const tokenIds = this.getOverrideTokenIds(override.token);\n const factoryId = this.getOverrideId('factory', override.token);\n\n this.ensureSyntheticService(factoryId, override.useFactory(this));\n this.overrideTokenIds.set(override.token, tokenIds[0]);\n for (const tokenId of tokenIds) {\n this.container.setAlias(tokenId, factoryId);\n }\n }\n\n private applyValueOverride(override: DependencyOverride): void {\n if (!('useValue' in override)) {\n return;\n }\n\n const tokenIds = this.getOverrideTokenIds(override.token);\n const valueId = this.getOverrideId('value', override.token);\n\n this.ensureSyntheticService(valueId, override.useValue);\n this.overrideTokenIds.set(override.token, tokenIds[0]);\n for (const tokenId of tokenIds) {\n this.container.setAlias(tokenId, valueId);\n }\n }\n\n private applyOverrides(): void {\n for (const override of this.options.overrides ?? []) {\n this.applyClassOverride(override);\n this.applyFactoryOverride(override);\n this.applyValueOverride(override);\n }\n }\n\n private registerParentAliases(): void {\n for (const [id, definition] of this.definitions.entries()) {\n if (definition._abstract === true || !definition._parent) {\n continue;\n }\n\n this.container.setAlias(definition._parent, id);\n }\n }\n\n public async compile(): Promise<void> {\n if (this.options.containerBuild) {\n await this.ensureFolderExists(this.options.servicesYamlPath);\n this.autowire = new Autowire(this.container);\n this.autowire.serviceFile = new ServiceFile(\n this.options.servicesYamlPath,\n false,\n );\n await this.autowire.process();\n } else {\n this.loader = new YamlFileLoader(this.container);\n await this.loader.load(this.options.servicesYamlPath);\n }\n\n this.registerParentAliases();\n this.applyOverrides();\n await this.container.compile();\n }\n\n public getService<T>(serviceName: unknown): T {\n const overrideTokenId = this.overrideTokenIds.get(serviceName);\n\n if (overrideTokenId) {\n return this.container.get<T>(overrideTokenId);\n }\n\n const aliasServiceId = this.findAliasServiceId(serviceName);\n\n if (aliasServiceId) {\n return this.container.get<T>(aliasServiceId);\n }\n\n const childServiceId = this.findConcreteChildServiceId(serviceName);\n\n if (childServiceId) {\n return this.container.get<T>(childServiceId);\n }\n\n const registeredServiceId = this.findRegisteredServiceId(serviceName);\n\n if (registeredServiceId) {\n return this.container.get<T>(registeredServiceId);\n }\n\n return this.container.get<T>(serviceName);\n }\n}\n\nexport default DependencyInjection;\n"],"mappings":"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","names":[]}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
8
|
var __export = (target, all) => {
|
|
7
9
|
for (var name in all)
|
|
@@ -15,39 +17,114 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
17
|
}
|
|
16
18
|
return to;
|
|
17
19
|
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
18
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
29
|
|
|
20
30
|
// src/infrastructure/express/index.ts
|
|
21
31
|
var express_exports = {};
|
|
22
32
|
__export(express_exports, {
|
|
23
33
|
ExpressKernelServer: () => ExpressKernelServer,
|
|
34
|
+
HttpErrorHandler: () => HttpErrorHandler,
|
|
24
35
|
RoutePrefix: () => RoutePrefix
|
|
25
36
|
});
|
|
26
37
|
module.exports = __toCommonJS(express_exports);
|
|
27
38
|
|
|
28
39
|
// src/adapters/ui/express/ExpressKernelServer.ts
|
|
29
|
-
var
|
|
40
|
+
var import_node_module = require("module");
|
|
41
|
+
var import_node_path = __toESM(require("path"), 1);
|
|
30
42
|
var ExpressKernelServer = class {
|
|
31
43
|
constructor(options) {
|
|
32
44
|
this.options = options;
|
|
45
|
+
this.afterControllersHooks = this.copy(options.afterControllersHooks);
|
|
46
|
+
this.beforeControllersHooks = this.copy(options.beforeControllersHooks);
|
|
47
|
+
this.controllers = this.copy(options.controllers);
|
|
48
|
+
this.errorHandlers = this.copy(options.errorHandlers);
|
|
49
|
+
this.hooks = this.copy(options.hooks);
|
|
50
|
+
this.middlewares = this.copy(options.middlewares);
|
|
51
|
+
this.postControllerMiddlewares = this.copy(
|
|
52
|
+
options.postControllerMiddlewares
|
|
53
|
+
);
|
|
54
|
+
this.preControllerMiddlewares = this.copy(options.preControllerMiddlewares);
|
|
55
|
+
this.staticHooks = this.copy(options.staticHooks);
|
|
56
|
+
this.swaggerHooks = this.copy(options.swaggerHooks);
|
|
33
57
|
}
|
|
34
58
|
options;
|
|
59
|
+
applicationRequire = (0, import_node_module.createRequire)(
|
|
60
|
+
import_node_path.default.resolve(process.cwd(), "package.json")
|
|
61
|
+
);
|
|
62
|
+
afterControllersHooks;
|
|
35
63
|
appInstance;
|
|
64
|
+
beforeControllersHooks;
|
|
65
|
+
controllers;
|
|
66
|
+
errorHandlers;
|
|
67
|
+
hooks;
|
|
68
|
+
middlewares;
|
|
69
|
+
postControllerMiddlewares;
|
|
70
|
+
preControllerMiddlewares;
|
|
36
71
|
serverInstance;
|
|
37
|
-
|
|
38
|
-
|
|
72
|
+
staticHooks;
|
|
73
|
+
swaggerHooks;
|
|
74
|
+
copy(items) {
|
|
75
|
+
return [...items ?? []];
|
|
76
|
+
}
|
|
77
|
+
configureControllerContainer() {
|
|
78
|
+
const { useContainer } = this.getRoutingControllers();
|
|
79
|
+
useContainer(
|
|
80
|
+
{
|
|
81
|
+
/* c8 ignore next */
|
|
82
|
+
get: (ClassDefinition) => this.options.kernel.di.getService(ClassDefinition)
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
fallback: true,
|
|
86
|
+
fallbackOnErrors: true
|
|
87
|
+
}
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
getExpress() {
|
|
91
|
+
return this.applicationRequire("express");
|
|
92
|
+
}
|
|
93
|
+
getRoutingControllers() {
|
|
94
|
+
return this.applicationRequire("routing-controllers");
|
|
95
|
+
}
|
|
96
|
+
applyErrorHandlers(app) {
|
|
97
|
+
const handlers = this.errorHandlers.length > 0 ? this.errorHandlers : [this.defaultErrorHandler()];
|
|
39
98
|
for (const handler of handlers) {
|
|
40
99
|
app.use(handler);
|
|
41
100
|
}
|
|
42
101
|
}
|
|
43
102
|
defaultErrorHandler() {
|
|
44
|
-
return (error, request, response) => {
|
|
103
|
+
return (error, request, response, next) => {
|
|
104
|
+
void next;
|
|
45
105
|
void request;
|
|
46
106
|
response.status(500).json({
|
|
47
107
|
error: error instanceof Error ? error.message : String(error)
|
|
48
108
|
});
|
|
49
109
|
};
|
|
50
110
|
}
|
|
111
|
+
async runHooks(hooks, app) {
|
|
112
|
+
for (const hook of hooks) {
|
|
113
|
+
await hook(app);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
async runPhaseHooks(phase, app) {
|
|
117
|
+
for (const hook of this.hooks) {
|
|
118
|
+
if (hook.phase === phase) {
|
|
119
|
+
await hook.handle(app);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
applyMiddlewares(app, middlewares) {
|
|
124
|
+
for (const middleware of middlewares) {
|
|
125
|
+
app.use(middleware);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
51
128
|
get app() {
|
|
52
129
|
if (!this.appInstance) {
|
|
53
130
|
throw new Error("HTTP server is not running.");
|
|
@@ -60,6 +137,11 @@ var ExpressKernelServer = class {
|
|
|
60
137
|
}
|
|
61
138
|
return this.serverInstance;
|
|
62
139
|
}
|
|
140
|
+
assertServerIsNotRunning() {
|
|
141
|
+
if (this.serverInstance) {
|
|
142
|
+
throw new Error("HTTP server is already running.");
|
|
143
|
+
}
|
|
144
|
+
}
|
|
63
145
|
close() {
|
|
64
146
|
if (!this.serverInstance) {
|
|
65
147
|
return Promise.resolve();
|
|
@@ -76,15 +158,74 @@ var ExpressKernelServer = class {
|
|
|
76
158
|
});
|
|
77
159
|
});
|
|
78
160
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
161
|
+
registerAfterControllersHooks(...hooks) {
|
|
162
|
+
this.assertServerIsNotRunning();
|
|
163
|
+
this.afterControllersHooks?.push(...hooks);
|
|
164
|
+
return this;
|
|
165
|
+
}
|
|
166
|
+
registerBeforeControllersHooks(...hooks) {
|
|
167
|
+
this.assertServerIsNotRunning();
|
|
168
|
+
this.beforeControllersHooks?.push(...hooks);
|
|
169
|
+
return this;
|
|
170
|
+
}
|
|
171
|
+
registerControllers(...controllers) {
|
|
172
|
+
this.assertServerIsNotRunning();
|
|
173
|
+
this.controllers.push(...controllers);
|
|
174
|
+
return this;
|
|
175
|
+
}
|
|
176
|
+
registerErrorHandlers(...handlers) {
|
|
177
|
+
this.assertServerIsNotRunning();
|
|
178
|
+
this.errorHandlers.push(...handlers);
|
|
179
|
+
return this;
|
|
180
|
+
}
|
|
181
|
+
registerHooks(...hooks) {
|
|
182
|
+
this.assertServerIsNotRunning();
|
|
183
|
+
this.hooks.push(...hooks);
|
|
184
|
+
return this;
|
|
185
|
+
}
|
|
186
|
+
registerMiddlewares(...middlewares) {
|
|
187
|
+
this.assertServerIsNotRunning();
|
|
188
|
+
this.middlewares.push(...middlewares);
|
|
189
|
+
return this;
|
|
190
|
+
}
|
|
191
|
+
registerPostControllerMiddlewares(...middlewares) {
|
|
192
|
+
this.assertServerIsNotRunning();
|
|
193
|
+
this.postControllerMiddlewares.push(...middlewares);
|
|
194
|
+
return this;
|
|
195
|
+
}
|
|
196
|
+
registerPreControllerMiddlewares(...middlewares) {
|
|
197
|
+
this.assertServerIsNotRunning();
|
|
198
|
+
this.preControllerMiddlewares.push(...middlewares);
|
|
199
|
+
return this;
|
|
200
|
+
}
|
|
201
|
+
async run() {
|
|
202
|
+
if (this.serverInstance) {
|
|
203
|
+
throw new Error("HTTP server is already running.");
|
|
204
|
+
}
|
|
205
|
+
const controllers = [
|
|
206
|
+
...this.options.kernel.getRoutes(),
|
|
207
|
+
...this.controllers
|
|
208
|
+
];
|
|
209
|
+
const express = this.getExpress();
|
|
210
|
+
const { useExpressServer } = this.getRoutingControllers();
|
|
211
|
+
const app = express();
|
|
212
|
+
this.applyMiddlewares(app, this.middlewares);
|
|
213
|
+
this.applyMiddlewares(app, this.preControllerMiddlewares);
|
|
214
|
+
await this.runHooks(this.beforeControllersHooks, app);
|
|
215
|
+
await this.runPhaseHooks("beforeControllers", app);
|
|
216
|
+
this.configureControllerContainer();
|
|
217
|
+
useExpressServer(app, {
|
|
218
|
+
...this.options.routingControllersOptions,
|
|
219
|
+
controllers,
|
|
82
220
|
routePrefix: this.options.routePrefix
|
|
83
221
|
});
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
this.
|
|
222
|
+
this.applyMiddlewares(app, this.postControllerMiddlewares);
|
|
223
|
+
await this.runHooks(this.afterControllersHooks, app);
|
|
224
|
+
await this.runPhaseHooks("afterControllers", app);
|
|
225
|
+
await this.runHooks(this.swaggerHooks, app);
|
|
226
|
+
await this.runHooks(this.staticHooks, app);
|
|
227
|
+
await this.runPhaseHooks("beforeErrors", app);
|
|
228
|
+
this.applyErrorHandlers(app);
|
|
88
229
|
this.appInstance = app;
|
|
89
230
|
return new Promise((resolve) => {
|
|
90
231
|
this.serverInstance = app.listen(this.options.port ?? 3e3, () => {
|
|
@@ -94,6 +235,132 @@ var ExpressKernelServer = class {
|
|
|
94
235
|
}
|
|
95
236
|
};
|
|
96
237
|
|
|
238
|
+
// src/adapters/ui/express/HttpErrorHandler.ts
|
|
239
|
+
var import_routing_controllers = require("routing-controllers");
|
|
240
|
+
|
|
241
|
+
// src/contracts/ui/HttpRouteStatusEnum.ts
|
|
242
|
+
var HttpRouteStatusEnum = {
|
|
243
|
+
BAD_REQUEST: 400,
|
|
244
|
+
CONFLICT: 409,
|
|
245
|
+
CREATED: 201,
|
|
246
|
+
DEPRECATED: 299,
|
|
247
|
+
FORBIDDEN: 403,
|
|
248
|
+
INTERNAL_SERVER_ERROR: 500,
|
|
249
|
+
NO_CONTENT: 204,
|
|
250
|
+
NOT_FOUND: 404,
|
|
251
|
+
OK: 200,
|
|
252
|
+
PAYLOAD_TOO_LARGE: 413,
|
|
253
|
+
SERVICE_UNAVAILABLE: 503,
|
|
254
|
+
TOO_MANY_REQUESTS: 429,
|
|
255
|
+
UNAUTHORIZED: 401,
|
|
256
|
+
UNPROCESSABLE_ENTITY: 422
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
// src/adapters/ui/express/HttpErrorHandler.ts
|
|
260
|
+
var HttpErrorHandler = class {
|
|
261
|
+
constructor(options = {}) {
|
|
262
|
+
this.options = options;
|
|
263
|
+
this.handlers = options.handlers ?? [];
|
|
264
|
+
this.exposeUnhandledErrorsIn = options.exposeUnhandledErrorsIn ?? [
|
|
265
|
+
"local",
|
|
266
|
+
"test"
|
|
267
|
+
];
|
|
268
|
+
}
|
|
269
|
+
options;
|
|
270
|
+
handlers;
|
|
271
|
+
exposeUnhandledErrorsIn;
|
|
272
|
+
formatValidationErrors(errors) {
|
|
273
|
+
return errors.flatMap((error) => {
|
|
274
|
+
if (error.children && error.children.length > 0) {
|
|
275
|
+
return this.formatValidationErrors(error.children);
|
|
276
|
+
}
|
|
277
|
+
return [
|
|
278
|
+
{
|
|
279
|
+
details: error.constraints,
|
|
280
|
+
property: error.property,
|
|
281
|
+
value: error.value
|
|
282
|
+
}
|
|
283
|
+
];
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
getErrorMessage(error) {
|
|
287
|
+
return error instanceof Error ? error.message : String(error);
|
|
288
|
+
}
|
|
289
|
+
getHttpStatus(error) {
|
|
290
|
+
return error.httpCode ?? error.statusCode ?? error.status;
|
|
291
|
+
}
|
|
292
|
+
isPayloadTooLargeError(error) {
|
|
293
|
+
return error.type === "entity.too.large" || this.getHttpStatus(error) === HttpRouteStatusEnum.PAYLOAD_TOO_LARGE;
|
|
294
|
+
}
|
|
295
|
+
logUnhandledError(error) {
|
|
296
|
+
this.options.logger?.error(`Unhandled error: ${error.message}`);
|
|
297
|
+
this.options.logger?.debug(error.stack ?? "No stack trace available");
|
|
298
|
+
}
|
|
299
|
+
handleSyntaxError(error, response) {
|
|
300
|
+
if (!(error instanceof SyntaxError)) {
|
|
301
|
+
return false;
|
|
302
|
+
}
|
|
303
|
+
response.status(HttpRouteStatusEnum.BAD_REQUEST).json({
|
|
304
|
+
code: "SyntaxError",
|
|
305
|
+
message: "Malformed JSON"
|
|
306
|
+
});
|
|
307
|
+
return true;
|
|
308
|
+
}
|
|
309
|
+
handlePayloadTooLargeError(error, response) {
|
|
310
|
+
if (!this.isPayloadTooLargeError(error)) {
|
|
311
|
+
return false;
|
|
312
|
+
}
|
|
313
|
+
response.status(HttpRouteStatusEnum.PAYLOAD_TOO_LARGE).json({
|
|
314
|
+
code: "PayloadTooLargeError",
|
|
315
|
+
httpStatus: HttpRouteStatusEnum.PAYLOAD_TOO_LARGE,
|
|
316
|
+
message: "Request entity too large."
|
|
317
|
+
});
|
|
318
|
+
return true;
|
|
319
|
+
}
|
|
320
|
+
handleHttpError(error, response) {
|
|
321
|
+
const httpError = error;
|
|
322
|
+
const httpStatus = this.getHttpStatus(httpError);
|
|
323
|
+
if (!httpStatus && !(error instanceof import_routing_controllers.HttpError)) {
|
|
324
|
+
return false;
|
|
325
|
+
}
|
|
326
|
+
response.status(httpStatus ?? HttpRouteStatusEnum.INTERNAL_SERVER_ERROR).json({
|
|
327
|
+
code: error.name,
|
|
328
|
+
errors: this.formatValidationErrors(
|
|
329
|
+
error.errors ?? []
|
|
330
|
+
),
|
|
331
|
+
httpStatus: httpStatus ?? HttpRouteStatusEnum.INTERNAL_SERVER_ERROR,
|
|
332
|
+
message: error.message
|
|
333
|
+
});
|
|
334
|
+
return true;
|
|
335
|
+
}
|
|
336
|
+
handleUnhandledError(error, response) {
|
|
337
|
+
if (this.exposeUnhandledErrorsIn.includes(process.env.NODE_ENV ?? "")) {
|
|
338
|
+
this.logUnhandledError(error);
|
|
339
|
+
}
|
|
340
|
+
response.status(HttpRouteStatusEnum.INTERNAL_SERVER_ERROR).json({
|
|
341
|
+
code: error.constructor.name || String(HttpRouteStatusEnum.INTERNAL_SERVER_ERROR),
|
|
342
|
+
message: error.message || "Unknown error"
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
error(error, request, response, next) {
|
|
346
|
+
void request;
|
|
347
|
+
const handlers = [
|
|
348
|
+
this.handleSyntaxError.bind(this),
|
|
349
|
+
this.handlePayloadTooLargeError.bind(this),
|
|
350
|
+
...this.handlers,
|
|
351
|
+
this.handleHttpError.bind(this)
|
|
352
|
+
];
|
|
353
|
+
if (handlers.some((handler) => handler(error, response))) {
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
void next;
|
|
357
|
+
this.handleUnhandledError(error, response);
|
|
358
|
+
}
|
|
359
|
+
handle = (error, request, response, next) => {
|
|
360
|
+
this.error(error, request, response, next);
|
|
361
|
+
};
|
|
362
|
+
};
|
|
363
|
+
|
|
97
364
|
// src/adapters/ui/express/RoutePrefix.ts
|
|
98
365
|
var RoutePrefix = class _RoutePrefix {
|
|
99
366
|
value;
|
|
@@ -121,6 +388,7 @@ var RoutePrefix = class _RoutePrefix {
|
|
|
121
388
|
// Annotate the CommonJS export names for ESM import in node:
|
|
122
389
|
0 && (module.exports = {
|
|
123
390
|
ExpressKernelServer,
|
|
391
|
+
HttpErrorHandler,
|
|
124
392
|
RoutePrefix
|
|
125
393
|
});
|
|
126
394
|
//# sourceMappingURL=index.cjs.map
|