fragment-ts 1.0.31 → 1.0.32
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/API.md +752 -0
- package/DOCS.md +555 -0
- package/README.md +76 -339
- package/USAGE.md +309 -1306
- package/dist/cli/commands/init.command.js +1 -1
- package/dist/core/decorators/exception-filter.decorator.d.ts +5 -0
- package/dist/core/decorators/exception-filter.decorator.d.ts.map +1 -0
- package/dist/core/decorators/exception-filter.decorator.js +23 -0
- package/dist/core/decorators/exception-filter.decorator.js.map +1 -0
- package/dist/core/decorators/guard.decorator.d.ts +5 -0
- package/dist/core/decorators/guard.decorator.d.ts.map +1 -0
- package/dist/core/decorators/guard.decorator.js +23 -0
- package/dist/core/decorators/guard.decorator.js.map +1 -0
- package/dist/core/decorators/interceptor.decorator.d.ts +5 -0
- package/dist/core/decorators/interceptor.decorator.d.ts.map +1 -0
- package/dist/core/decorators/interceptor.decorator.js +23 -0
- package/dist/core/decorators/interceptor.decorator.js.map +1 -0
- package/dist/core/decorators/middleware.decorator.d.ts +8 -0
- package/dist/core/decorators/middleware.decorator.d.ts.map +1 -0
- package/dist/core/decorators/middleware.decorator.js +28 -0
- package/dist/core/decorators/middleware.decorator.js.map +1 -0
- package/dist/core/metadata/metadata-keys.d.ts +1 -0
- package/dist/core/metadata/metadata-keys.d.ts.map +1 -1
- package/dist/core/metadata/metadata-keys.js +1 -0
- package/dist/core/metadata/metadata-keys.js.map +1 -1
- package/dist/core/metadata/metadata-storage.d.ts +18 -0
- package/dist/core/metadata/metadata-storage.d.ts.map +1 -1
- package/dist/core/metadata/metadata-storage.js +82 -0
- package/dist/core/metadata/metadata-storage.js.map +1 -1
- package/dist/web/application.d.ts.map +1 -1
- package/dist/web/application.js +74 -5
- package/dist/web/application.js.map +1 -1
- package/dist/web/interfaces.d.ts +5 -1
- package/dist/web/interfaces.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/cli/commands/init.command.ts +1 -1
- package/src/core/decorators/exception-filter.decorator.ts +20 -0
- package/src/core/decorators/guard.decorator.ts +20 -0
- package/src/core/decorators/interceptor.decorator.ts +20 -0
- package/src/core/decorators/middleware.decorator.ts +25 -0
- package/src/core/metadata/metadata-keys.ts +1 -0
- package/src/core/metadata/metadata-storage.ts +114 -0
- package/src/web/application.ts +141 -6
- package/src/web/interfaces.ts +11 -2
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Guard } from "../../web/interfaces";
|
|
2
|
+
import { METADATA_KEYS } from "../metadata/metadata-keys";
|
|
3
|
+
import { MetadataStorage } from "../metadata/metadata-storage";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @Guard - Apply authorization/activation guard
|
|
7
|
+
*/
|
|
8
|
+
export function Guard(guardClass: new () => any): ClassDecorator & MethodDecorator {
|
|
9
|
+
return (target: any, propertyKey?: string | symbol) => {
|
|
10
|
+
if (propertyKey === undefined) {
|
|
11
|
+
Reflect.defineMetadata(METADATA_KEYS.USE_GUARDS, guardClass, target);
|
|
12
|
+
const storage = MetadataStorage.getInstance();
|
|
13
|
+
storage.addClassMetadata?.(target, 'guard', guardClass);
|
|
14
|
+
} else {
|
|
15
|
+
Reflect.defineMetadata(METADATA_KEYS.USE_GUARDS, guardClass, target, propertyKey);
|
|
16
|
+
const storage = MetadataStorage.getInstance();
|
|
17
|
+
storage.addMethodMetadata?.(target.constructor, propertyKey.toString(), 'guard', guardClass);
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Interceptor } from "../../web/interfaces";
|
|
2
|
+
import { METADATA_KEYS } from "../metadata/metadata-keys";
|
|
3
|
+
import { MetadataStorage } from "../metadata/metadata-storage";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @Interceptor - Intercept and transform request/response
|
|
7
|
+
*/
|
|
8
|
+
export function Interceptor(interceptorClass: new () => any): ClassDecorator & MethodDecorator {
|
|
9
|
+
return (target: any, propertyKey?: string | symbol) => {
|
|
10
|
+
if (propertyKey === undefined) {
|
|
11
|
+
Reflect.defineMetadata(METADATA_KEYS.USE_INTERCEPTORS, interceptorClass, target);
|
|
12
|
+
const storage = MetadataStorage.getInstance();
|
|
13
|
+
storage.addClassMetadata?.(target, 'interceptor', interceptorClass);
|
|
14
|
+
} else {
|
|
15
|
+
Reflect.defineMetadata(METADATA_KEYS.USE_INTERCEPTORS, interceptorClass, target, propertyKey);
|
|
16
|
+
const storage = MetadataStorage.getInstance();
|
|
17
|
+
storage.addMethodMetadata?.(target.constructor, propertyKey.toString(), 'interceptor', interceptorClass);
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Middleware } from "../../web/interfaces";
|
|
2
|
+
import { METADATA_KEYS } from "../metadata/metadata-keys";
|
|
3
|
+
import { MetadataStorage } from "../metadata/metadata-storage";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @Middleware - Apply Express-compatible middleware at class or method level
|
|
7
|
+
* Usage:
|
|
8
|
+
* @Middleware(AuthMiddleware) class MyController { }
|
|
9
|
+
* @Middleware(AuthMiddleware) @Get('/') handler() { }
|
|
10
|
+
*/
|
|
11
|
+
export function Middleware(middlewareClass: new () => any): ClassDecorator & MethodDecorator {
|
|
12
|
+
return (target: any, propertyKey?: string | symbol) => {
|
|
13
|
+
if (propertyKey === undefined) {
|
|
14
|
+
// Class-level
|
|
15
|
+
Reflect.defineMetadata(METADATA_KEYS.USE_MIDDLEWARE, middlewareClass, target);
|
|
16
|
+
const storage = MetadataStorage.getInstance();
|
|
17
|
+
storage.addClassMetadata?.(target, 'middleware', middlewareClass);
|
|
18
|
+
} else {
|
|
19
|
+
// Method-level
|
|
20
|
+
Reflect.defineMetadata(METADATA_KEYS.USE_MIDDLEWARE, middlewareClass, target, propertyKey);
|
|
21
|
+
const storage = MetadataStorage.getInstance();
|
|
22
|
+
storage.addMethodMetadata?.(target.constructor, propertyKey.toString(), 'middleware', middlewareClass);
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
}
|
|
@@ -33,6 +33,7 @@ export const METADATA_KEYS = {
|
|
|
33
33
|
CONDITIONAL_ON_BEAN: "fragment:conditional-on-bean",
|
|
34
34
|
|
|
35
35
|
// Middleware & Guards
|
|
36
|
+
USE_MIDDLEWARE: "fragment:use-middleware",
|
|
36
37
|
USE_GUARDS: "fragment:use-guards",
|
|
37
38
|
USE_INTERCEPTORS: "fragment:use-interceptors",
|
|
38
39
|
USE_FILTERS: "fragment:use-filters",
|
|
@@ -35,6 +35,20 @@ export interface PropertyInjectionMetadata {
|
|
|
35
35
|
metadata?: any;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
export interface ExtendedClassMetadata extends ClassMetadata {
|
|
39
|
+
middlewares: any[];
|
|
40
|
+
guards: any[];
|
|
41
|
+
interceptors: any[];
|
|
42
|
+
exceptionFilters: any[];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface ExtendedMethodMetadata extends MethodMetadata {
|
|
46
|
+
middlewares?: any[];
|
|
47
|
+
guards?: any[];
|
|
48
|
+
interceptors?: any[];
|
|
49
|
+
exceptionFilters?: any[];
|
|
50
|
+
}
|
|
51
|
+
|
|
38
52
|
export class MetadataStorage {
|
|
39
53
|
private static instance: MetadataStorage;
|
|
40
54
|
private classes: Map<any, ClassMetadata> = new Map();
|
|
@@ -42,6 +56,8 @@ export class MetadataStorage {
|
|
|
42
56
|
private params: Map<string, ParamMetadata[]> = new Map();
|
|
43
57
|
private propertyInjections: Map<string, PropertyInjectionMetadata[]> =
|
|
44
58
|
new Map();
|
|
59
|
+
private extendedClasses: Map<any, ExtendedClassMetadata> = new Map();
|
|
60
|
+
private extendedMethods: Map<string, ExtendedMethodMetadata> = new Map();
|
|
45
61
|
|
|
46
62
|
static getInstance(): MetadataStorage {
|
|
47
63
|
if (!MetadataStorage.instance) {
|
|
@@ -125,4 +141,102 @@ export class MetadataStorage {
|
|
|
125
141
|
|
|
126
142
|
return injections;
|
|
127
143
|
}
|
|
144
|
+
|
|
145
|
+
addClassMetadata(target: any, type: string, value: any): void {
|
|
146
|
+
let meta = this.extendedClasses.get(target);
|
|
147
|
+
|
|
148
|
+
if (!meta) {
|
|
149
|
+
const base = this.classes.get(target);
|
|
150
|
+
if (!base) {
|
|
151
|
+
// If no base ClassMetadata exists (e.g., decorator used on non-@Controller/@Service class),
|
|
152
|
+
// we cannot safely create ExtendedClassMetadata — skip or warn.
|
|
153
|
+
console.warn(
|
|
154
|
+
`⚠️ @${type} applied to ${target.name}, but it's not registered as a known component (missing @Controller, @Service, etc.). Ignoring.`,
|
|
155
|
+
);
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Clone base and add enhancement arrays
|
|
160
|
+
meta = {
|
|
161
|
+
...base,
|
|
162
|
+
middlewares: [],
|
|
163
|
+
guards: [],
|
|
164
|
+
interceptors: [],
|
|
165
|
+
exceptionFilters: [],
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
switch (type) {
|
|
170
|
+
case "middleware":
|
|
171
|
+
meta.middlewares.push(value);
|
|
172
|
+
break;
|
|
173
|
+
case "guard":
|
|
174
|
+
meta.guards.push(value);
|
|
175
|
+
break;
|
|
176
|
+
case "interceptor":
|
|
177
|
+
meta.interceptors.push(value);
|
|
178
|
+
break;
|
|
179
|
+
case "exceptionFilter":
|
|
180
|
+
meta.exceptionFilters.push(value);
|
|
181
|
+
break;
|
|
182
|
+
default:
|
|
183
|
+
console.warn(`Unknown metadata type: ${type}`);
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
this.extendedClasses.set(target, meta);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
addMethodMetadata(
|
|
191
|
+
target: any,
|
|
192
|
+
propertyKey: string,
|
|
193
|
+
type: string,
|
|
194
|
+
value: any,
|
|
195
|
+
): void {
|
|
196
|
+
const key = `${target.name}.${propertyKey}`;
|
|
197
|
+
let meta = this.extendedMethods.get(key);
|
|
198
|
+
if (!meta) {
|
|
199
|
+
const base = this.methods.get(key);
|
|
200
|
+
meta = {
|
|
201
|
+
...(base || {
|
|
202
|
+
target,
|
|
203
|
+
propertyKey,
|
|
204
|
+
method: "",
|
|
205
|
+
path: "",
|
|
206
|
+
paramMetadata: [],
|
|
207
|
+
}),
|
|
208
|
+
middlewares: [],
|
|
209
|
+
guards: [],
|
|
210
|
+
interceptors: [],
|
|
211
|
+
exceptionFilters: [],
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
switch (type) {
|
|
215
|
+
case "middleware":
|
|
216
|
+
meta.middlewares!.push(value);
|
|
217
|
+
break;
|
|
218
|
+
case "guard":
|
|
219
|
+
meta.guards!.push(value);
|
|
220
|
+
break;
|
|
221
|
+
case "interceptor":
|
|
222
|
+
meta.interceptors!.push(value);
|
|
223
|
+
break;
|
|
224
|
+
case "exceptionFilter":
|
|
225
|
+
meta.exceptionFilters!.push(value);
|
|
226
|
+
break;
|
|
227
|
+
}
|
|
228
|
+
this.extendedMethods.set(key, meta);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
getExtendedClass(target: any): ExtendedClassMetadata | undefined {
|
|
232
|
+
return this.extendedClasses.get(target);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
getExtendedMethod(
|
|
236
|
+
target: any,
|
|
237
|
+
propertyKey: string,
|
|
238
|
+
): ExtendedMethodMetadata | undefined {
|
|
239
|
+
const key = `${target.name}.${propertyKey}`;
|
|
240
|
+
return this.extendedMethods.get(key);
|
|
241
|
+
}
|
|
128
242
|
}
|
package/src/web/application.ts
CHANGED
|
@@ -9,6 +9,16 @@ import { MetadataStorage } from "../core/metadata/metadata-storage";
|
|
|
9
9
|
import { METADATA_KEYS } from "../core/metadata/metadata-keys";
|
|
10
10
|
import { ComponentScanner } from "../core/scanner/component-scanner";
|
|
11
11
|
import { TypeORMModule } from "../typeorm/typeorm-module";
|
|
12
|
+
import {
|
|
13
|
+
MiddlewareClass,
|
|
14
|
+
GuardClass,
|
|
15
|
+
InterceptorClass,
|
|
16
|
+
ExceptionFilterClass,
|
|
17
|
+
Middleware,
|
|
18
|
+
Guard,
|
|
19
|
+
Interceptor,
|
|
20
|
+
ExceptionFilter,
|
|
21
|
+
} from "./interfaces";
|
|
12
22
|
|
|
13
23
|
export class FragmentWebApplication {
|
|
14
24
|
private app: Express;
|
|
@@ -286,6 +296,27 @@ export class FragmentWebApplication {
|
|
|
286
296
|
const controller = this.container.resolve(controllerMetadata.target);
|
|
287
297
|
const basePath = controllerMetadata.path || "";
|
|
288
298
|
|
|
299
|
+
// Get controller-level enhancements
|
|
300
|
+
const controllerMiddlewares = (Reflect.getMetadata(
|
|
301
|
+
METADATA_KEYS.USE_MIDDLEWARE,
|
|
302
|
+
controllerMetadata.target,
|
|
303
|
+
) || []) as MiddlewareClass[];
|
|
304
|
+
|
|
305
|
+
const controllerGuards = (Reflect.getMetadata(
|
|
306
|
+
METADATA_KEYS.USE_GUARDS,
|
|
307
|
+
controllerMetadata.target,
|
|
308
|
+
) || []) as GuardClass[];
|
|
309
|
+
|
|
310
|
+
const controllerInterceptors = (Reflect.getMetadata(
|
|
311
|
+
METADATA_KEYS.USE_INTERCEPTORS,
|
|
312
|
+
controllerMetadata.target,
|
|
313
|
+
) || []) as InterceptorClass[];
|
|
314
|
+
|
|
315
|
+
const controllerFilters = (Reflect.getMetadata(
|
|
316
|
+
METADATA_KEYS.USE_FILTERS,
|
|
317
|
+
controllerMetadata.target,
|
|
318
|
+
) || []) as ExceptionFilterClass[];
|
|
319
|
+
|
|
289
320
|
const methods = this.metadataStorage
|
|
290
321
|
.getAllMethods()
|
|
291
322
|
.filter((m) => m.target === controllerMetadata.target);
|
|
@@ -307,10 +338,78 @@ export class FragmentWebApplication {
|
|
|
307
338
|
|
|
308
339
|
totalRoutes++;
|
|
309
340
|
|
|
341
|
+
// Collect method-level enhancements
|
|
342
|
+
const methodMiddlewares = (Reflect.getMetadata(
|
|
343
|
+
METADATA_KEYS.USE_MIDDLEWARE,
|
|
344
|
+
controllerMetadata.target.prototype,
|
|
345
|
+
methodMetadata.propertyKey,
|
|
346
|
+
) || []) as MiddlewareClass[];
|
|
347
|
+
|
|
348
|
+
const methodGuards = (Reflect.getMetadata(
|
|
349
|
+
METADATA_KEYS.USE_GUARDS,
|
|
350
|
+
controllerMetadata.target.prototype,
|
|
351
|
+
methodMetadata.propertyKey,
|
|
352
|
+
) || []) as GuardClass[];
|
|
353
|
+
|
|
354
|
+
const methodInterceptors = (Reflect.getMetadata(
|
|
355
|
+
METADATA_KEYS.USE_INTERCEPTORS,
|
|
356
|
+
controllerMetadata.target.prototype,
|
|
357
|
+
methodMetadata.propertyKey,
|
|
358
|
+
) || []) as InterceptorClass[];
|
|
359
|
+
|
|
360
|
+
const methodFilters = (Reflect.getMetadata(
|
|
361
|
+
METADATA_KEYS.USE_FILTERS,
|
|
362
|
+
controllerMetadata.target.prototype,
|
|
363
|
+
methodMetadata.propertyKey,
|
|
364
|
+
) || []) as ExceptionFilterClass[];
|
|
365
|
+
|
|
366
|
+
// Combine: controller + method
|
|
367
|
+
const allMiddlewares = [
|
|
368
|
+
...controllerMiddlewares,
|
|
369
|
+
...methodMiddlewares,
|
|
370
|
+
];
|
|
371
|
+
const allGuards = [...controllerGuards, ...methodGuards];
|
|
372
|
+
const allInterceptors = [
|
|
373
|
+
...controllerInterceptors,
|
|
374
|
+
...methodInterceptors,
|
|
375
|
+
];
|
|
376
|
+
const allFilters = [...controllerFilters, ...methodFilters];
|
|
377
|
+
|
|
378
|
+
// Resolve via DI container
|
|
379
|
+
const resolvedMiddlewares = allMiddlewares.map(
|
|
380
|
+
(M) => this.container.resolve(M) as Middleware,
|
|
381
|
+
);
|
|
382
|
+
const resolvedGuards = allGuards.map(
|
|
383
|
+
(G) => this.container.resolve(G) as Guard,
|
|
384
|
+
);
|
|
385
|
+
const resolvedInterceptors = allInterceptors.map(
|
|
386
|
+
(I) => this.container.resolve(I) as Interceptor,
|
|
387
|
+
);
|
|
388
|
+
|
|
389
|
+
// Build Express route handler with pipeline
|
|
310
390
|
(this.app as any)[httpMethod](
|
|
311
391
|
fullPath,
|
|
392
|
+
// Middleware stack (Express-compatible)
|
|
393
|
+
...resolvedMiddlewares.map(
|
|
394
|
+
(mw) => (req: Request, res: Response, next: NextFunction) =>
|
|
395
|
+
Promise.resolve(mw.use(req, res, next)).catch(next),
|
|
396
|
+
),
|
|
397
|
+
// Final unified handler
|
|
312
398
|
async (req: Request, res: Response, next: NextFunction) => {
|
|
313
399
|
try {
|
|
400
|
+
// ➤ Step 1: Guards
|
|
401
|
+
for (const guard of resolvedGuards) {
|
|
402
|
+
const canActivate = await Promise.resolve(
|
|
403
|
+
guard.canActivate(req),
|
|
404
|
+
);
|
|
405
|
+
if (!canActivate) {
|
|
406
|
+
const error = new Error("Forbidden");
|
|
407
|
+
(error as any).status = 403;
|
|
408
|
+
throw error;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
// ➤ Step 2: Resolve parameters
|
|
314
413
|
const args = this.resolveMethodParameters(
|
|
315
414
|
methodMetadata,
|
|
316
415
|
req,
|
|
@@ -320,18 +419,54 @@ export class FragmentWebApplication {
|
|
|
320
419
|
console.log(
|
|
321
420
|
`\n🔍 Handling ${httpMethod.toUpperCase()} ${fullPath}`,
|
|
322
421
|
);
|
|
323
|
-
// console.log(` Parameters:`, args);
|
|
324
422
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
423
|
+
// ➤ Step 3: Interceptors (wrap handler)
|
|
424
|
+
let result: any;
|
|
425
|
+
if (resolvedInterceptors.length > 0) {
|
|
426
|
+
// First, call the real handler
|
|
427
|
+
const rawResult = await (controller as any)[
|
|
428
|
+
methodMetadata.propertyKey
|
|
429
|
+
](...args);
|
|
430
|
+
|
|
431
|
+
// Then pass result through interceptors in reverse order (or forward — your choice)
|
|
432
|
+
result = rawResult;
|
|
433
|
+
for (const interceptor of resolvedInterceptors) {
|
|
434
|
+
// Allow interceptor to transform the result
|
|
435
|
+
result = await Promise.resolve(
|
|
436
|
+
interceptor.intercept(req, res, result),
|
|
437
|
+
);
|
|
438
|
+
}
|
|
439
|
+
} else {
|
|
440
|
+
result = await (controller as any)[
|
|
441
|
+
methodMetadata.propertyKey
|
|
442
|
+
](...args);
|
|
443
|
+
}
|
|
328
444
|
|
|
445
|
+
// ➤ Step 4: Send response
|
|
329
446
|
if (!res.headersSent) {
|
|
330
447
|
res.json(result);
|
|
331
448
|
}
|
|
332
449
|
} catch (error) {
|
|
333
|
-
|
|
334
|
-
|
|
450
|
+
// ➤ Step 5: Exception Filters (method + controller level)
|
|
451
|
+
let handled = false;
|
|
452
|
+
for (const FilterClass of allFilters) {
|
|
453
|
+
const filter = this.container.resolve(
|
|
454
|
+
FilterClass,
|
|
455
|
+
) as ExceptionFilter;
|
|
456
|
+
try {
|
|
457
|
+
const err =
|
|
458
|
+
error instanceof Error ? error : new Error(String(error));
|
|
459
|
+
filter.catch(err, req, res);
|
|
460
|
+
handled = true;
|
|
461
|
+
break;
|
|
462
|
+
} catch (e) {
|
|
463
|
+
console.error(`❌ Exception filter failed:`, e);
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
if (!handled) {
|
|
468
|
+
next(error);
|
|
469
|
+
}
|
|
335
470
|
}
|
|
336
471
|
},
|
|
337
472
|
);
|
package/src/web/interfaces.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Request, Response, NextFunction } from
|
|
1
|
+
import { Request, Response, NextFunction } from "express";
|
|
2
2
|
|
|
3
3
|
export interface Middleware {
|
|
4
4
|
use(req: Request, res: Response, next: NextFunction): void | Promise<void>;
|
|
@@ -9,9 +9,18 @@ export interface Guard {
|
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
export interface Interceptor {
|
|
12
|
-
intercept(
|
|
12
|
+
intercept(
|
|
13
|
+
req: Request,
|
|
14
|
+
res: Response,
|
|
15
|
+
next: NextFunction,
|
|
16
|
+
): void | Promise<void>;
|
|
13
17
|
}
|
|
14
18
|
|
|
15
19
|
export interface ExceptionFilter {
|
|
16
20
|
catch(exception: Error, req: Request, res: Response): void;
|
|
17
21
|
}
|
|
22
|
+
|
|
23
|
+
export type MiddlewareClass = new () => Middleware;
|
|
24
|
+
export type GuardClass = new () => Guard;
|
|
25
|
+
export type InterceptorClass = new () => Interceptor;
|
|
26
|
+
export type ExceptionFilterClass = new () => ExceptionFilter;
|