@digitaldefiance/node-express-suite 3.11.32 → 3.12.1
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 +874 -8
- package/package.json +5 -5
- package/src/controllers/openapi.d.ts +67 -0
- package/src/controllers/openapi.d.ts.map +1 -0
- package/src/controllers/openapi.js +89 -0
- package/src/controllers/openapi.js.map +1 -0
- package/src/decorators/auth.d.ts +128 -0
- package/src/decorators/auth.d.ts.map +1 -0
- package/src/decorators/auth.js +230 -0
- package/src/decorators/auth.js.map +1 -0
- package/src/decorators/base-controller.d.ts +144 -6
- package/src/decorators/base-controller.d.ts.map +1 -1
- package/src/decorators/base-controller.js +487 -31
- package/src/decorators/base-controller.js.map +1 -1
- package/src/decorators/controller.d.ts +63 -7
- package/src/decorators/controller.d.ts.map +1 -1
- package/src/decorators/controller.js +70 -39
- package/src/decorators/controller.js.map +1 -1
- package/src/decorators/handler-args.d.ts +68 -0
- package/src/decorators/handler-args.d.ts.map +1 -0
- package/src/decorators/handler-args.js +83 -0
- package/src/decorators/handler-args.js.map +1 -0
- package/src/decorators/http-methods.d.ts +143 -0
- package/src/decorators/http-methods.d.ts.map +1 -0
- package/src/decorators/http-methods.js +265 -0
- package/src/decorators/http-methods.js.map +1 -0
- package/src/decorators/index.d.ts +22 -0
- package/src/decorators/index.d.ts.map +1 -1
- package/src/decorators/index.js +56 -0
- package/src/decorators/index.js.map +1 -1
- package/src/decorators/lifecycle.d.ts +248 -0
- package/src/decorators/lifecycle.d.ts.map +1 -0
- package/src/decorators/lifecycle.js +301 -0
- package/src/decorators/lifecycle.js.map +1 -0
- package/src/decorators/metadata-collector.d.ts +175 -0
- package/src/decorators/metadata-collector.d.ts.map +1 -0
- package/src/decorators/metadata-collector.js +272 -0
- package/src/decorators/metadata-collector.js.map +1 -0
- package/src/decorators/metadata-keys.d.ts +121 -0
- package/src/decorators/metadata-keys.d.ts.map +1 -0
- package/src/decorators/metadata-keys.js +116 -0
- package/src/decorators/metadata-keys.js.map +1 -0
- package/src/decorators/middleware.d.ts +181 -0
- package/src/decorators/middleware.d.ts.map +1 -0
- package/src/decorators/middleware.js +400 -0
- package/src/decorators/middleware.js.map +1 -0
- package/src/decorators/openapi-params.d.ts +192 -0
- package/src/decorators/openapi-params.d.ts.map +1 -0
- package/src/decorators/openapi-params.js +332 -0
- package/src/decorators/openapi-params.js.map +1 -0
- package/src/decorators/openapi.d.ts +201 -0
- package/src/decorators/openapi.d.ts.map +1 -0
- package/src/decorators/openapi.js +334 -0
- package/src/decorators/openapi.js.map +1 -0
- package/src/decorators/params.d.ts +217 -0
- package/src/decorators/params.d.ts.map +1 -0
- package/src/decorators/params.js +323 -0
- package/src/decorators/params.js.map +1 -0
- package/src/decorators/response.d.ts +200 -0
- package/src/decorators/response.d.ts.map +1 -0
- package/src/decorators/response.js +315 -0
- package/src/decorators/response.js.map +1 -0
- package/src/decorators/schema.d.ts +99 -0
- package/src/decorators/schema.d.ts.map +1 -0
- package/src/decorators/schema.js +329 -0
- package/src/decorators/schema.js.map +1 -0
- package/src/decorators/transaction.d.ts +69 -0
- package/src/decorators/transaction.d.ts.map +1 -0
- package/src/decorators/transaction.js +80 -0
- package/src/decorators/transaction.js.map +1 -0
- package/src/decorators/validation.d.ts +188 -0
- package/src/decorators/validation.d.ts.map +1 -0
- package/src/decorators/validation.js +269 -0
- package/src/decorators/validation.js.map +1 -0
- package/src/decorators/zod-validation.d.ts +164 -4
- package/src/decorators/zod-validation.d.ts.map +1 -1
- package/src/decorators/zod-validation.js +692 -13
- package/src/decorators/zod-validation.js.map +1 -1
- package/src/index.d.ts +1 -0
- package/src/index.d.ts.map +1 -1
- package/src/index.js +1 -0
- package/src/index.js.map +1 -1
- package/src/interfaces/openApi/decoratorOptions.d.ts +760 -0
- package/src/interfaces/openApi/decoratorOptions.d.ts.map +1 -0
- package/src/interfaces/openApi/decoratorOptions.js +734 -0
- package/src/interfaces/openApi/decoratorOptions.js.map +1 -0
- package/src/interfaces/openApi/index.d.ts +1 -0
- package/src/interfaces/openApi/index.d.ts.map +1 -1
- package/src/interfaces/openApi/index.js +23 -0
- package/src/interfaces/openApi/index.js.map +1 -1
- package/src/interfaces/openApi/parameter.d.ts +2 -0
- package/src/interfaces/openApi/parameter.d.ts.map +1 -1
- package/src/interfaces/openApi/parameter.js +3 -1
- package/src/interfaces/openApi/parameter.js.map +1 -1
- package/src/interfaces/openApi/parameterSchema.d.ts +2 -0
- package/src/interfaces/openApi/parameterSchema.d.ts.map +1 -1
- package/src/interfaces/openApi/parameterSchema.js +3 -0
- package/src/interfaces/openApi/parameterSchema.js.map +1 -1
- package/src/openapi/builder.d.ts +249 -0
- package/src/openapi/builder.d.ts.map +1 -0
- package/src/openapi/builder.js +352 -0
- package/src/openapi/builder.js.map +1 -0
- package/src/openapi/controller.d.ts +153 -0
- package/src/openapi/controller.d.ts.map +1 -0
- package/src/openapi/controller.js +331 -0
- package/src/openapi/controller.js.map +1 -0
- package/src/openapi/index.d.ts +12 -0
- package/src/openapi/index.d.ts.map +1 -0
- package/src/openapi/index.js +20 -0
- package/src/openapi/index.js.map +1 -0
- package/src/openapi/markdown-generator.d.ts +52 -0
- package/src/openapi/markdown-generator.d.ts.map +1 -0
- package/src/openapi/markdown-generator.js +569 -0
- package/src/openapi/markdown-generator.js.map +1 -0
- package/src/openapi/middleware/index.d.ts +9 -0
- package/src/openapi/middleware/index.d.ts.map +1 -0
- package/src/openapi/middleware/index.js +15 -0
- package/src/openapi/middleware/index.js.map +1 -0
- package/src/openapi/middleware/redoc.d.ts +314 -0
- package/src/openapi/middleware/redoc.d.ts.map +1 -0
- package/src/openapi/middleware/redoc.js +181 -0
- package/src/openapi/middleware/redoc.js.map +1 -0
- package/src/openapi/middleware/swagger-ui.d.ts +123 -0
- package/src/openapi/middleware/swagger-ui.d.ts.map +1 -0
- package/src/openapi/middleware/swagger-ui.js +227 -0
- package/src/openapi/middleware/swagger-ui.js.map +1 -0
- package/src/openapi/schemas.d.ts +170 -0
- package/src/openapi/schemas.d.ts.map +1 -0
- package/src/openapi/schemas.js +340 -0
- package/src/openapi/schemas.js.map +1 -0
- package/src/registry/controller-registry.d.ts +78 -0
- package/src/registry/controller-registry.d.ts.map +1 -0
- package/src/registry/controller-registry.js +86 -0
- package/src/registry/controller-registry.js.map +1 -0
- package/src/registry/index.d.ts +2 -0
- package/src/registry/index.d.ts.map +1 -1
- package/src/registry/index.js +3 -1
- package/src/registry/index.js.map +1 -1
- package/src/routers/api.d.ts +2 -1
- package/src/routers/api.d.ts.map +1 -1
- package/src/routers/api.js +7 -1
- package/src/routers/api.js.map +1 -1
- package/src/types.d.ts +1 -0
- package/src/types.d.ts.map +1 -1
- package/src/types.js +1 -0
- package/src/types.js.map +1 -1
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Middleware decorators for Express Suite.
|
|
3
|
+
* Provides @UseMiddleware, @CacheResponse, and @RateLimit decorators.
|
|
4
|
+
* Supports both class-level and method-level application.
|
|
5
|
+
* @module decorators/middleware
|
|
6
|
+
*/
|
|
7
|
+
import 'reflect-metadata';
|
|
8
|
+
import { RequestHandler } from 'express';
|
|
9
|
+
import { CacheDecoratorOptions, RateLimitDecoratorOptions } from '../interfaces/openApi/decoratorOptions';
|
|
10
|
+
/**
|
|
11
|
+
* Decorator that attaches Express middleware to a route or all routes in a controller.
|
|
12
|
+
* Can be applied at class level (affects all methods) or method level.
|
|
13
|
+
* Middleware execution order follows decorator order (top to bottom).
|
|
14
|
+
*
|
|
15
|
+
* @param middleware - Single middleware function or array of middleware functions
|
|
16
|
+
* @returns Class or method decorator
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```typescript
|
|
20
|
+
* // Single middleware
|
|
21
|
+
* @UseMiddleware(loggerMiddleware)
|
|
22
|
+
* @ApiController('/api/users')
|
|
23
|
+
* class UserController {
|
|
24
|
+
* @Get('/')
|
|
25
|
+
* listUsers() {}
|
|
26
|
+
* }
|
|
27
|
+
*
|
|
28
|
+
* // Multiple middleware
|
|
29
|
+
* @ApiController('/api/items')
|
|
30
|
+
* class ItemController {
|
|
31
|
+
* @UseMiddleware([validateMiddleware, sanitizeMiddleware])
|
|
32
|
+
* @Post('/')
|
|
33
|
+
* createItem() {}
|
|
34
|
+
* }
|
|
35
|
+
*
|
|
36
|
+
* // Stacked middleware (executed top to bottom)
|
|
37
|
+
* @ApiController('/api/data')
|
|
38
|
+
* class DataController {
|
|
39
|
+
* @UseMiddleware(firstMiddleware)
|
|
40
|
+
* @UseMiddleware(secondMiddleware)
|
|
41
|
+
* @Get('/')
|
|
42
|
+
* getData() {}
|
|
43
|
+
* }
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export declare function UseMiddleware(middleware: RequestHandler | RequestHandler[]): ClassDecorator & MethodDecorator;
|
|
47
|
+
/**
|
|
48
|
+
* Decorator that adds response caching to a route.
|
|
49
|
+
* Caches successful responses for the specified TTL.
|
|
50
|
+
*
|
|
51
|
+
* @param options - Cache options including TTL, key prefix, and vary options
|
|
52
|
+
* @returns Method decorator
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```typescript
|
|
56
|
+
* @ApiController('/api/data')
|
|
57
|
+
* class DataController {
|
|
58
|
+
* // Cache for 60 seconds
|
|
59
|
+
* @CacheResponse({ ttl: 60 })
|
|
60
|
+
* @Get('/static')
|
|
61
|
+
* getStaticData() {}
|
|
62
|
+
*
|
|
63
|
+
* // Cache with user variation
|
|
64
|
+
* @CacheResponse({ ttl: 300, varyByUser: true })
|
|
65
|
+
* @Get('/user-data')
|
|
66
|
+
* getUserData() {}
|
|
67
|
+
*
|
|
68
|
+
* // Cache with query parameter variation
|
|
69
|
+
* @CacheResponse({ ttl: 120, varyByQuery: ['page', 'limit'] })
|
|
70
|
+
* @Get('/items')
|
|
71
|
+
* listItems() {}
|
|
72
|
+
* }
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
export declare function CacheResponse(options: CacheDecoratorOptions): MethodDecorator;
|
|
76
|
+
/**
|
|
77
|
+
* Decorator that adds rate limiting to a route or all routes in a controller.
|
|
78
|
+
* Automatically adds 429 response to OpenAPI spec.
|
|
79
|
+
*
|
|
80
|
+
* @param options - Rate limit options including requests, window, and key options
|
|
81
|
+
* @returns Class or method decorator
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* ```typescript
|
|
85
|
+
* @ApiController('/api/auth')
|
|
86
|
+
* class AuthController {
|
|
87
|
+
* // Limit to 5 requests per minute
|
|
88
|
+
* @RateLimit({ requests: 5, window: 60 })
|
|
89
|
+
* @Post('/login')
|
|
90
|
+
* login() {}
|
|
91
|
+
*
|
|
92
|
+
* // Limit by user with custom message
|
|
93
|
+
* @RateLimit({
|
|
94
|
+
* requests: 100,
|
|
95
|
+
* window: 3600,
|
|
96
|
+
* byUser: true,
|
|
97
|
+
* message: 'Hourly limit exceeded'
|
|
98
|
+
* })
|
|
99
|
+
* @Get('/profile')
|
|
100
|
+
* getProfile() {}
|
|
101
|
+
* }
|
|
102
|
+
*
|
|
103
|
+
* // Class-level rate limiting
|
|
104
|
+
* @RateLimit({ requests: 1000, window: 3600 })
|
|
105
|
+
* @ApiController('/api/data')
|
|
106
|
+
* class DataController {
|
|
107
|
+
* @Get('/')
|
|
108
|
+
* getData() {}
|
|
109
|
+
* }
|
|
110
|
+
* ```
|
|
111
|
+
*/
|
|
112
|
+
export declare function RateLimit(options: RateLimitDecoratorOptions): ClassDecorator & MethodDecorator;
|
|
113
|
+
/**
|
|
114
|
+
* Gets all middleware metadata for a method.
|
|
115
|
+
*
|
|
116
|
+
* @param target - The class constructor
|
|
117
|
+
* @param propertyKey - The method name
|
|
118
|
+
* @returns Array of middleware functions
|
|
119
|
+
*/
|
|
120
|
+
export declare function getMiddlewareMetadata(target: object, propertyKey: string | symbol): RequestHandler[];
|
|
121
|
+
/**
|
|
122
|
+
* Gets the effective middleware for a method, merging class-level and method-level.
|
|
123
|
+
* Class-level middleware runs first, then method-level.
|
|
124
|
+
*
|
|
125
|
+
* @param target - The class constructor
|
|
126
|
+
* @param propertyKey - The method name
|
|
127
|
+
* @returns Merged array of middleware functions
|
|
128
|
+
*/
|
|
129
|
+
export declare function getEffectiveMiddleware(target: object, propertyKey: string | symbol): RequestHandler[];
|
|
130
|
+
/**
|
|
131
|
+
* Gets cache metadata for a method.
|
|
132
|
+
*
|
|
133
|
+
* @param target - The class constructor
|
|
134
|
+
* @param propertyKey - The method name
|
|
135
|
+
* @returns Cache options or undefined if not cached
|
|
136
|
+
*/
|
|
137
|
+
export declare function getCacheMetadata(target: object, propertyKey: string | symbol): CacheDecoratorOptions | undefined;
|
|
138
|
+
/**
|
|
139
|
+
* Gets rate limit metadata for a method.
|
|
140
|
+
*
|
|
141
|
+
* @param target - The class constructor
|
|
142
|
+
* @param propertyKey - The method name
|
|
143
|
+
* @returns Rate limit options or undefined if not rate limited
|
|
144
|
+
*/
|
|
145
|
+
export declare function getRateLimitMetadata(target: object, propertyKey: string | symbol): RateLimitDecoratorOptions | undefined;
|
|
146
|
+
/**
|
|
147
|
+
* Gets the effective rate limit metadata for a method, merging class-level and method-level.
|
|
148
|
+
* Method-level settings override class-level settings.
|
|
149
|
+
*
|
|
150
|
+
* @param target - The class constructor
|
|
151
|
+
* @param propertyKey - The method name
|
|
152
|
+
* @returns Rate limit options or undefined if not rate limited
|
|
153
|
+
*/
|
|
154
|
+
export declare function getEffectiveRateLimitMetadata(target: object, propertyKey: string | symbol): RateLimitDecoratorOptions | undefined;
|
|
155
|
+
/**
|
|
156
|
+
* Checks if a method has caching enabled.
|
|
157
|
+
*
|
|
158
|
+
* @param target - The class constructor
|
|
159
|
+
* @param propertyKey - The method name
|
|
160
|
+
* @returns True if caching is enabled
|
|
161
|
+
*/
|
|
162
|
+
export declare function isCached(target: object, propertyKey: string | symbol): boolean;
|
|
163
|
+
/**
|
|
164
|
+
* Checks if a method has rate limiting enabled.
|
|
165
|
+
*
|
|
166
|
+
* @param target - The class constructor
|
|
167
|
+
* @param propertyKey - The method name
|
|
168
|
+
* @returns True if rate limiting is enabled
|
|
169
|
+
*/
|
|
170
|
+
export declare function isRateLimited(target: object, propertyKey: string | symbol): boolean;
|
|
171
|
+
/**
|
|
172
|
+
* Clears the in-memory cache store.
|
|
173
|
+
* Useful for testing.
|
|
174
|
+
*/
|
|
175
|
+
export declare function clearCacheStore(): void;
|
|
176
|
+
/**
|
|
177
|
+
* Clears the in-memory rate limit store.
|
|
178
|
+
* Useful for testing.
|
|
179
|
+
*/
|
|
180
|
+
export declare function clearRateLimitStore(): void;
|
|
181
|
+
//# sourceMappingURL=middleware.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../../../../packages/digitaldefiance-node-express-suite/src/decorators/middleware.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,kBAAkB,CAAC;AAC1B,OAAO,EAAE,cAAc,EAAmC,MAAM,SAAS,CAAC;AAC1E,OAAO,EACL,qBAAqB,EACrB,yBAAyB,EAC1B,MAAM,wCAAwC,CAAC;AAiGhD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAgB,aAAa,CAC3B,UAAU,EAAE,cAAc,GAAG,cAAc,EAAE,GAC5C,cAAc,GAAG,eAAe,CAQlC;AAwDD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,qBAAqB,GAAG,eAAe,CAoB7E;AA0ED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAgB,SAAS,CACvB,OAAO,EAAE,yBAAyB,GACjC,cAAc,GAAG,eAAe,CAiBlC;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GAAG,MAAM,GAC3B,cAAc,EAAE,CAOlB;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GAAG,MAAM,GAC3B,cAAc,EAAE,CAgBlB;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GAAG,MAAM,GAC3B,qBAAqB,GAAG,SAAS,CAMnC;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GAAG,MAAM,GAC3B,yBAAyB,GAAG,SAAS,CAMvC;AAED;;;;;;;GAOG;AACH,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GAAG,MAAM,GAC3B,yBAAyB,GAAG,SAAS,CAgBvC;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CACtB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GAAG,MAAM,GAC3B,OAAO,CAET;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GAAG,MAAM,GAC3B,OAAO,CAET;AAED;;;GAGG;AACH,wBAAgB,eAAe,IAAI,IAAI,CAEtC;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C"}
|
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview Middleware decorators for Express Suite.
|
|
4
|
+
* Provides @UseMiddleware, @CacheResponse, and @RateLimit decorators.
|
|
5
|
+
* Supports both class-level and method-level application.
|
|
6
|
+
* @module decorators/middleware
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.UseMiddleware = UseMiddleware;
|
|
10
|
+
exports.CacheResponse = CacheResponse;
|
|
11
|
+
exports.RateLimit = RateLimit;
|
|
12
|
+
exports.getMiddlewareMetadata = getMiddlewareMetadata;
|
|
13
|
+
exports.getEffectiveMiddleware = getEffectiveMiddleware;
|
|
14
|
+
exports.getCacheMetadata = getCacheMetadata;
|
|
15
|
+
exports.getRateLimitMetadata = getRateLimitMetadata;
|
|
16
|
+
exports.getEffectiveRateLimitMetadata = getEffectiveRateLimitMetadata;
|
|
17
|
+
exports.isCached = isCached;
|
|
18
|
+
exports.isRateLimited = isRateLimited;
|
|
19
|
+
exports.clearCacheStore = clearCacheStore;
|
|
20
|
+
exports.clearRateLimitStore = clearRateLimitStore;
|
|
21
|
+
require("reflect-metadata");
|
|
22
|
+
const metadata_keys_1 = require("./metadata-keys");
|
|
23
|
+
const metadata_collector_1 = require("./metadata-collector");
|
|
24
|
+
/**
|
|
25
|
+
* Response metadata for 429 Too Many Requests response.
|
|
26
|
+
*/
|
|
27
|
+
const TOO_MANY_REQUESTS_RESPONSE = {
|
|
28
|
+
statusCode: 429,
|
|
29
|
+
description: 'Too Many Requests - Rate limit exceeded',
|
|
30
|
+
schema: 'ErrorResponse',
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* In-memory cache store for @CacheResponse decorator.
|
|
34
|
+
* In production, this should be replaced with Redis or similar.
|
|
35
|
+
*/
|
|
36
|
+
const cacheStore = new Map();
|
|
37
|
+
/**
|
|
38
|
+
* In-memory rate limit store for @RateLimit decorator.
|
|
39
|
+
* In production, this should be replaced with Redis or similar.
|
|
40
|
+
*/
|
|
41
|
+
const rateLimitStore = new Map();
|
|
42
|
+
/**
|
|
43
|
+
* Creates a decorator that can be applied to both classes and methods.
|
|
44
|
+
* @param applyMetadata - Function to apply the metadata
|
|
45
|
+
* @returns A decorator function
|
|
46
|
+
*/
|
|
47
|
+
function createMiddlewareDecorator(applyMetadata) {
|
|
48
|
+
function decorator(target, propertyKey, descriptor) {
|
|
49
|
+
if (propertyKey !== undefined && descriptor !== undefined) {
|
|
50
|
+
// Method decorator
|
|
51
|
+
applyMetadata(target.constructor, propertyKey);
|
|
52
|
+
return descriptor;
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
// Class decorator
|
|
56
|
+
applyMetadata(target);
|
|
57
|
+
return target;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return decorator;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Adds 429 response to OpenAPI metadata for rate-limited routes.
|
|
64
|
+
* @param target - The target object (class constructor or prototype)
|
|
65
|
+
* @param propertyKey - Optional property key for method-level metadata
|
|
66
|
+
*/
|
|
67
|
+
function addTooManyRequestsResponse(target, propertyKey) {
|
|
68
|
+
const existingResponses = (0, metadata_collector_1.getMetadataOrDefault)(metadata_keys_1.RESPONSE_METADATA, target, propertyKey, []);
|
|
69
|
+
// Check if 429 response already exists
|
|
70
|
+
const has429 = existingResponses.some((r) => r.statusCode === 429);
|
|
71
|
+
if (!has429) {
|
|
72
|
+
existingResponses.push(TOO_MANY_REQUESTS_RESPONSE);
|
|
73
|
+
(0, metadata_collector_1.setMetadata)(metadata_keys_1.RESPONSE_METADATA, existingResponses, target, propertyKey);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Decorator that attaches Express middleware to a route or all routes in a controller.
|
|
78
|
+
* Can be applied at class level (affects all methods) or method level.
|
|
79
|
+
* Middleware execution order follows decorator order (top to bottom).
|
|
80
|
+
*
|
|
81
|
+
* @param middleware - Single middleware function or array of middleware functions
|
|
82
|
+
* @returns Class or method decorator
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```typescript
|
|
86
|
+
* // Single middleware
|
|
87
|
+
* @UseMiddleware(loggerMiddleware)
|
|
88
|
+
* @ApiController('/api/users')
|
|
89
|
+
* class UserController {
|
|
90
|
+
* @Get('/')
|
|
91
|
+
* listUsers() {}
|
|
92
|
+
* }
|
|
93
|
+
*
|
|
94
|
+
* // Multiple middleware
|
|
95
|
+
* @ApiController('/api/items')
|
|
96
|
+
* class ItemController {
|
|
97
|
+
* @UseMiddleware([validateMiddleware, sanitizeMiddleware])
|
|
98
|
+
* @Post('/')
|
|
99
|
+
* createItem() {}
|
|
100
|
+
* }
|
|
101
|
+
*
|
|
102
|
+
* // Stacked middleware (executed top to bottom)
|
|
103
|
+
* @ApiController('/api/data')
|
|
104
|
+
* class DataController {
|
|
105
|
+
* @UseMiddleware(firstMiddleware)
|
|
106
|
+
* @UseMiddleware(secondMiddleware)
|
|
107
|
+
* @Get('/')
|
|
108
|
+
* getData() {}
|
|
109
|
+
* }
|
|
110
|
+
* ```
|
|
111
|
+
*/
|
|
112
|
+
function UseMiddleware(middleware) {
|
|
113
|
+
const middlewareArray = Array.isArray(middleware) ? middleware : [middleware];
|
|
114
|
+
return createMiddlewareDecorator((target, propertyKey) => {
|
|
115
|
+
for (const mw of middlewareArray) {
|
|
116
|
+
(0, metadata_collector_1.appendToMetadataArray)(metadata_keys_1.MIDDLEWARE_METADATA, mw, target, propertyKey);
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Creates a cache middleware factory that caches responses.
|
|
122
|
+
* @param options - Cache options
|
|
123
|
+
* @returns Express middleware function
|
|
124
|
+
*/
|
|
125
|
+
function createCacheMiddleware(options) {
|
|
126
|
+
const { ttl, keyPrefix = '', varyByUser = false, varyByQuery = [] } = options;
|
|
127
|
+
return (req, res, next) => {
|
|
128
|
+
// Build cache key
|
|
129
|
+
let cacheKey = `${keyPrefix}:${req.method}:${req.originalUrl}`;
|
|
130
|
+
if (varyByUser && req.user) {
|
|
131
|
+
const userId = typeof req.user === 'object' && 'id' in req.user
|
|
132
|
+
? req.user.id
|
|
133
|
+
: String(req.user);
|
|
134
|
+
cacheKey += `:user:${userId}`;
|
|
135
|
+
}
|
|
136
|
+
if (varyByQuery.length > 0) {
|
|
137
|
+
const queryParts = varyByQuery
|
|
138
|
+
.filter((key) => req.query[key] !== undefined)
|
|
139
|
+
.map((key) => `${key}=${req.query[key]}`)
|
|
140
|
+
.sort()
|
|
141
|
+
.join('&');
|
|
142
|
+
if (queryParts) {
|
|
143
|
+
cacheKey += `:query:${queryParts}`;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
// Check cache
|
|
147
|
+
const cached = cacheStore.get(cacheKey);
|
|
148
|
+
if (cached && cached.expiry > Date.now()) {
|
|
149
|
+
res.json(cached.data);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
// Store original json method
|
|
153
|
+
const originalJson = res.json.bind(res);
|
|
154
|
+
// Override json to cache the response
|
|
155
|
+
res.json = function (data) {
|
|
156
|
+
cacheStore.set(cacheKey, {
|
|
157
|
+
data,
|
|
158
|
+
expiry: Date.now() + ttl * 1000,
|
|
159
|
+
});
|
|
160
|
+
return originalJson(data);
|
|
161
|
+
};
|
|
162
|
+
next();
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Decorator that adds response caching to a route.
|
|
167
|
+
* Caches successful responses for the specified TTL.
|
|
168
|
+
*
|
|
169
|
+
* @param options - Cache options including TTL, key prefix, and vary options
|
|
170
|
+
* @returns Method decorator
|
|
171
|
+
*
|
|
172
|
+
* @example
|
|
173
|
+
* ```typescript
|
|
174
|
+
* @ApiController('/api/data')
|
|
175
|
+
* class DataController {
|
|
176
|
+
* // Cache for 60 seconds
|
|
177
|
+
* @CacheResponse({ ttl: 60 })
|
|
178
|
+
* @Get('/static')
|
|
179
|
+
* getStaticData() {}
|
|
180
|
+
*
|
|
181
|
+
* // Cache with user variation
|
|
182
|
+
* @CacheResponse({ ttl: 300, varyByUser: true })
|
|
183
|
+
* @Get('/user-data')
|
|
184
|
+
* getUserData() {}
|
|
185
|
+
*
|
|
186
|
+
* // Cache with query parameter variation
|
|
187
|
+
* @CacheResponse({ ttl: 120, varyByQuery: ['page', 'limit'] })
|
|
188
|
+
* @Get('/items')
|
|
189
|
+
* listItems() {}
|
|
190
|
+
* }
|
|
191
|
+
* ```
|
|
192
|
+
*/
|
|
193
|
+
function CacheResponse(options) {
|
|
194
|
+
return function (target, propertyKey, descriptor) {
|
|
195
|
+
// Store cache metadata
|
|
196
|
+
(0, metadata_collector_1.setMetadata)(metadata_keys_1.CACHE_METADATA, options, target.constructor, propertyKey);
|
|
197
|
+
// Add cache middleware
|
|
198
|
+
const cacheMiddleware = createCacheMiddleware(options);
|
|
199
|
+
(0, metadata_collector_1.appendToMetadataArray)(metadata_keys_1.MIDDLEWARE_METADATA, cacheMiddleware, target.constructor, propertyKey);
|
|
200
|
+
return descriptor;
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Creates a rate limit middleware factory.
|
|
205
|
+
* @param options - Rate limit options
|
|
206
|
+
* @returns Express middleware function
|
|
207
|
+
*/
|
|
208
|
+
function createRateLimitMiddleware(options) {
|
|
209
|
+
const { requests, window, message = 'Too many requests, please try again later.', byUser = false, keyGenerator, } = options;
|
|
210
|
+
return (req, res, next) => {
|
|
211
|
+
// Build rate limit key
|
|
212
|
+
let rateLimitKey;
|
|
213
|
+
if (keyGenerator) {
|
|
214
|
+
rateLimitKey = keyGenerator(req);
|
|
215
|
+
}
|
|
216
|
+
else if (byUser && req.user) {
|
|
217
|
+
const userId = typeof req.user === 'object' && 'id' in req.user
|
|
218
|
+
? req.user.id
|
|
219
|
+
: String(req.user);
|
|
220
|
+
rateLimitKey = `ratelimit:user:${userId}:${req.method}:${req.path}`;
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
rateLimitKey = `ratelimit:ip:${req.ip}:${req.method}:${req.path}`;
|
|
224
|
+
}
|
|
225
|
+
const now = Date.now();
|
|
226
|
+
const windowMs = window * 1000;
|
|
227
|
+
// Get or create rate limit entry
|
|
228
|
+
let entry = rateLimitStore.get(rateLimitKey);
|
|
229
|
+
if (!entry || entry.resetTime <= now) {
|
|
230
|
+
// Create new entry or reset expired entry
|
|
231
|
+
entry = {
|
|
232
|
+
count: 1,
|
|
233
|
+
resetTime: now + windowMs,
|
|
234
|
+
};
|
|
235
|
+
rateLimitStore.set(rateLimitKey, entry);
|
|
236
|
+
next();
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
// Increment count
|
|
240
|
+
entry.count++;
|
|
241
|
+
if (entry.count > requests) {
|
|
242
|
+
// Rate limit exceeded
|
|
243
|
+
const retryAfter = Math.ceil((entry.resetTime - now) / 1000);
|
|
244
|
+
res.setHeader('Retry-After', retryAfter.toString());
|
|
245
|
+
res.setHeader('X-RateLimit-Limit', requests.toString());
|
|
246
|
+
res.setHeader('X-RateLimit-Remaining', '0');
|
|
247
|
+
res.setHeader('X-RateLimit-Reset', entry.resetTime.toString());
|
|
248
|
+
res.status(429).json({ error: message });
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
// Set rate limit headers
|
|
252
|
+
res.setHeader('X-RateLimit-Limit', requests.toString());
|
|
253
|
+
res.setHeader('X-RateLimit-Remaining', (requests - entry.count).toString());
|
|
254
|
+
res.setHeader('X-RateLimit-Reset', entry.resetTime.toString());
|
|
255
|
+
next();
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Decorator that adds rate limiting to a route or all routes in a controller.
|
|
260
|
+
* Automatically adds 429 response to OpenAPI spec.
|
|
261
|
+
*
|
|
262
|
+
* @param options - Rate limit options including requests, window, and key options
|
|
263
|
+
* @returns Class or method decorator
|
|
264
|
+
*
|
|
265
|
+
* @example
|
|
266
|
+
* ```typescript
|
|
267
|
+
* @ApiController('/api/auth')
|
|
268
|
+
* class AuthController {
|
|
269
|
+
* // Limit to 5 requests per minute
|
|
270
|
+
* @RateLimit({ requests: 5, window: 60 })
|
|
271
|
+
* @Post('/login')
|
|
272
|
+
* login() {}
|
|
273
|
+
*
|
|
274
|
+
* // Limit by user with custom message
|
|
275
|
+
* @RateLimit({
|
|
276
|
+
* requests: 100,
|
|
277
|
+
* window: 3600,
|
|
278
|
+
* byUser: true,
|
|
279
|
+
* message: 'Hourly limit exceeded'
|
|
280
|
+
* })
|
|
281
|
+
* @Get('/profile')
|
|
282
|
+
* getProfile() {}
|
|
283
|
+
* }
|
|
284
|
+
*
|
|
285
|
+
* // Class-level rate limiting
|
|
286
|
+
* @RateLimit({ requests: 1000, window: 3600 })
|
|
287
|
+
* @ApiController('/api/data')
|
|
288
|
+
* class DataController {
|
|
289
|
+
* @Get('/')
|
|
290
|
+
* getData() {}
|
|
291
|
+
* }
|
|
292
|
+
* ```
|
|
293
|
+
*/
|
|
294
|
+
function RateLimit(options) {
|
|
295
|
+
return createMiddlewareDecorator((target, propertyKey) => {
|
|
296
|
+
// Store rate limit metadata
|
|
297
|
+
(0, metadata_collector_1.setMetadata)(metadata_keys_1.RATE_LIMIT_METADATA, options, target, propertyKey);
|
|
298
|
+
// Add rate limit middleware
|
|
299
|
+
const rateLimitMiddleware = createRateLimitMiddleware(options);
|
|
300
|
+
(0, metadata_collector_1.appendToMetadataArray)(metadata_keys_1.MIDDLEWARE_METADATA, rateLimitMiddleware, target, propertyKey);
|
|
301
|
+
// Add 429 response to OpenAPI
|
|
302
|
+
addTooManyRequestsResponse(target, propertyKey);
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Gets all middleware metadata for a method.
|
|
307
|
+
*
|
|
308
|
+
* @param target - The class constructor
|
|
309
|
+
* @param propertyKey - The method name
|
|
310
|
+
* @returns Array of middleware functions
|
|
311
|
+
*/
|
|
312
|
+
function getMiddlewareMetadata(target, propertyKey) {
|
|
313
|
+
return (0, metadata_collector_1.getMetadataOrDefault)(metadata_keys_1.MIDDLEWARE_METADATA, target, propertyKey, []);
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Gets the effective middleware for a method, merging class-level and method-level.
|
|
317
|
+
* Class-level middleware runs first, then method-level.
|
|
318
|
+
*
|
|
319
|
+
* @param target - The class constructor
|
|
320
|
+
* @param propertyKey - The method name
|
|
321
|
+
* @returns Merged array of middleware functions
|
|
322
|
+
*/
|
|
323
|
+
function getEffectiveMiddleware(target, propertyKey) {
|
|
324
|
+
const classMiddleware = (0, metadata_collector_1.getMetadataOrDefault)(metadata_keys_1.MIDDLEWARE_METADATA, target, undefined, []);
|
|
325
|
+
const methodMiddleware = (0, metadata_collector_1.getMetadataOrDefault)(metadata_keys_1.MIDDLEWARE_METADATA, target, propertyKey, []);
|
|
326
|
+
// Class middleware runs first, then method middleware
|
|
327
|
+
return [...classMiddleware, ...methodMiddleware];
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Gets cache metadata for a method.
|
|
331
|
+
*
|
|
332
|
+
* @param target - The class constructor
|
|
333
|
+
* @param propertyKey - The method name
|
|
334
|
+
* @returns Cache options or undefined if not cached
|
|
335
|
+
*/
|
|
336
|
+
function getCacheMetadata(target, propertyKey) {
|
|
337
|
+
return (0, metadata_collector_1.getMetadata)(metadata_keys_1.CACHE_METADATA, target, propertyKey);
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Gets rate limit metadata for a method.
|
|
341
|
+
*
|
|
342
|
+
* @param target - The class constructor
|
|
343
|
+
* @param propertyKey - The method name
|
|
344
|
+
* @returns Rate limit options or undefined if not rate limited
|
|
345
|
+
*/
|
|
346
|
+
function getRateLimitMetadata(target, propertyKey) {
|
|
347
|
+
return (0, metadata_collector_1.getMetadata)(metadata_keys_1.RATE_LIMIT_METADATA, target, propertyKey);
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Gets the effective rate limit metadata for a method, merging class-level and method-level.
|
|
351
|
+
* Method-level settings override class-level settings.
|
|
352
|
+
*
|
|
353
|
+
* @param target - The class constructor
|
|
354
|
+
* @param propertyKey - The method name
|
|
355
|
+
* @returns Rate limit options or undefined if not rate limited
|
|
356
|
+
*/
|
|
357
|
+
function getEffectiveRateLimitMetadata(target, propertyKey) {
|
|
358
|
+
const classRateLimit = (0, metadata_collector_1.getMetadata)(metadata_keys_1.RATE_LIMIT_METADATA, target);
|
|
359
|
+
const methodRateLimit = (0, metadata_collector_1.getMetadata)(metadata_keys_1.RATE_LIMIT_METADATA, target, propertyKey);
|
|
360
|
+
// Method-level overrides class-level
|
|
361
|
+
if (methodRateLimit) {
|
|
362
|
+
return methodRateLimit;
|
|
363
|
+
}
|
|
364
|
+
return classRateLimit;
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Checks if a method has caching enabled.
|
|
368
|
+
*
|
|
369
|
+
* @param target - The class constructor
|
|
370
|
+
* @param propertyKey - The method name
|
|
371
|
+
* @returns True if caching is enabled
|
|
372
|
+
*/
|
|
373
|
+
function isCached(target, propertyKey) {
|
|
374
|
+
return getCacheMetadata(target, propertyKey) !== undefined;
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Checks if a method has rate limiting enabled.
|
|
378
|
+
*
|
|
379
|
+
* @param target - The class constructor
|
|
380
|
+
* @param propertyKey - The method name
|
|
381
|
+
* @returns True if rate limiting is enabled
|
|
382
|
+
*/
|
|
383
|
+
function isRateLimited(target, propertyKey) {
|
|
384
|
+
return getEffectiveRateLimitMetadata(target, propertyKey) !== undefined;
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Clears the in-memory cache store.
|
|
388
|
+
* Useful for testing.
|
|
389
|
+
*/
|
|
390
|
+
function clearCacheStore() {
|
|
391
|
+
cacheStore.clear();
|
|
392
|
+
}
|
|
393
|
+
/**
|
|
394
|
+
* Clears the in-memory rate limit store.
|
|
395
|
+
* Useful for testing.
|
|
396
|
+
*/
|
|
397
|
+
function clearRateLimitStore() {
|
|
398
|
+
rateLimitStore.clear();
|
|
399
|
+
}
|
|
400
|
+
//# sourceMappingURL=middleware.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../../../../packages/digitaldefiance-node-express-suite/src/decorators/middleware.ts"],"names":[],"mappings":"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"}
|