@mxweb/core 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.
Files changed (51) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +61 -0
  3. package/dist/application.d.ts +402 -0
  4. package/dist/application.js +1 -0
  5. package/dist/application.mjs +1 -0
  6. package/dist/common.d.ts +323 -0
  7. package/dist/common.js +1 -0
  8. package/dist/common.mjs +1 -0
  9. package/dist/config.d.ts +258 -0
  10. package/dist/config.js +1 -0
  11. package/dist/config.mjs +1 -0
  12. package/dist/context.d.ts +48 -0
  13. package/dist/context.js +1 -0
  14. package/dist/context.mjs +1 -0
  15. package/dist/controller.d.ts +238 -0
  16. package/dist/controller.js +1 -0
  17. package/dist/controller.mjs +1 -0
  18. package/dist/decorator.d.ts +349 -0
  19. package/dist/decorator.js +1 -0
  20. package/dist/decorator.mjs +1 -0
  21. package/dist/error.d.ts +301 -0
  22. package/dist/error.js +1 -0
  23. package/dist/error.mjs +1 -0
  24. package/dist/execute.d.ts +469 -0
  25. package/dist/execute.js +1 -0
  26. package/dist/execute.mjs +1 -0
  27. package/dist/feature.d.ts +239 -0
  28. package/dist/feature.js +1 -0
  29. package/dist/feature.mjs +1 -0
  30. package/dist/hooks.d.ts +251 -0
  31. package/dist/hooks.js +1 -0
  32. package/dist/hooks.mjs +1 -0
  33. package/dist/index.d.ts +14 -0
  34. package/dist/index.js +1 -0
  35. package/dist/index.mjs +1 -0
  36. package/dist/logger.d.ts +360 -0
  37. package/dist/logger.js +1 -0
  38. package/dist/logger.mjs +1 -0
  39. package/dist/response.d.ts +665 -0
  40. package/dist/response.js +1 -0
  41. package/dist/response.mjs +1 -0
  42. package/dist/route.d.ts +298 -0
  43. package/dist/route.js +1 -0
  44. package/dist/route.mjs +1 -0
  45. package/dist/router.d.ts +205 -0
  46. package/dist/router.js +1 -0
  47. package/dist/router.mjs +1 -0
  48. package/dist/service.d.ts +261 -0
  49. package/dist/service.js +1 -0
  50. package/dist/service.mjs +1 -0
  51. package/package.json +168 -0
@@ -0,0 +1,238 @@
1
+ import { ExecuteContext } from "./execute";
2
+ import { ClassContructor } from "./common";
3
+ /**
4
+ * Type registry interface for InjectionRegistry.
5
+ * Services can augment this interface to provide type-safe injection by name.
6
+ *
7
+ * @remarks
8
+ * When using string-based injection (legacy pattern), augment this interface
9
+ * to get proper typing for injected properties.
10
+ *
11
+ * @example
12
+ * ```ts
13
+ * // In your service file
14
+ * declare module "@mxweb/core" {
15
+ * interface InjectionTypeRegistry {
16
+ * userService: UserService;
17
+ * productService: ProductService;
18
+ * }
19
+ * }
20
+ * ```
21
+ */
22
+ export interface InjectionTypeRegistry {
23
+ }
24
+ /**
25
+ * Type for controller injection map configuration.
26
+ * Can be a static object mapping property names to service classes,
27
+ * or an async function that resolves the map with access to global injects.
28
+ *
29
+ * @template T - Record type mapping property names to class constructors
30
+ *
31
+ * @example
32
+ * ```ts
33
+ * // Static object
34
+ * const map: ControllerInjectMap<{ userService: typeof UserService }> = {
35
+ * userService: UserService,
36
+ * };
37
+ *
38
+ * // Async function with access to global injects
39
+ * const map: ControllerInjectMap<{ userService: typeof UserService }> = async (injects) => {
40
+ * const db = injects.get("db");
41
+ * return { userService: UserService };
42
+ * };
43
+ * ```
44
+ */
45
+ type ControllerInjectMap<T extends Record<string, ClassContructor<any>>> = T | ((injects: Map<string, unknown>) => T | Promise<T>);
46
+ /**
47
+ * Utility type that builds property types from an array of injection names.
48
+ * Uses InjectionTypeRegistry for type lookup.
49
+ *
50
+ * @template Names - Readonly array of injection name strings
51
+ * @internal
52
+ */
53
+ type InjectPropertiesByName<Names extends readonly string[]> = {
54
+ readonly [K in Names[number]]: K extends keyof InjectionTypeRegistry ? InjectionTypeRegistry[K] : unknown;
55
+ };
56
+ /**
57
+ * Utility type that builds property types from a class constructor map.
58
+ * Maps each property to the instance type of its corresponding class.
59
+ *
60
+ * @template T - Record type mapping property names to class constructors
61
+ * @internal
62
+ */
63
+ type InjectPropertiesByClass<T extends Record<string, ClassContructor<any>>> = {
64
+ readonly [K in keyof T]: InstanceType<T[K]>;
65
+ };
66
+ /**
67
+ * Base Controller class providing dependency injection and request context access.
68
+ *
69
+ * This class serves as the foundation for all controllers in the framework.
70
+ * It provides:
71
+ * - Automatic dependency injection via static `injects` or `injectMap`
72
+ * - Access to the current request context via `this.context`
73
+ * - Lazy initialization of async dependencies
74
+ *
75
+ * @remarks
76
+ * Do not instantiate this class directly. Use the {@link controller} helper
77
+ * function to create a typed controller base class with injections.
78
+ *
79
+ * @example
80
+ * ```ts
81
+ * // Using controller() helper (recommended)
82
+ * const MyController = controller({
83
+ * userService: UserService,
84
+ * productService: ProductService,
85
+ * });
86
+ *
87
+ * export class ProductController extends MyController {
88
+ * async findAll() {
89
+ * // Access injected services
90
+ * const products = await this.productService.findAll();
91
+ *
92
+ * // Access request context
93
+ * const query = this.context.switchHttp().query();
94
+ *
95
+ * return products;
96
+ * }
97
+ * }
98
+ * ```
99
+ */
100
+ declare class BaseController {
101
+ /** Flag indicating if async dependencies have been initialized */
102
+ private _initialized;
103
+ /**
104
+ * Creates a new controller instance.
105
+ * Automatically injects dependencies defined in static `injects` array.
106
+ */
107
+ constructor();
108
+ /**
109
+ * Provides access to the current request's ExecuteContext.
110
+ * Use this to access request data, response helpers, and other context utilities.
111
+ *
112
+ * @returns The ExecuteContext singleton with current request scope
113
+ *
114
+ * @example
115
+ * ```ts
116
+ * async findById() {
117
+ * const { id } = this.context.switchHttp().params();
118
+ * const body = await this.context.switchHttp().json();
119
+ * const headers = this.context.switchHttp().headers();
120
+ * return this.service.findById(id);
121
+ * }
122
+ * ```
123
+ */
124
+ protected get context(): ExecuteContext;
125
+ /**
126
+ * Initializes async dependencies defined in static `injectMap`.
127
+ * This method is called automatically by the framework before handler execution.
128
+ *
129
+ * @remarks
130
+ * - Only runs once per controller instance
131
+ * - Resolves async inject map functions with access to global injects
132
+ * - Caches resolved maps for subsequent requests
133
+ *
134
+ * @internal
135
+ */
136
+ _initDependencies(): Promise<void>;
137
+ /**
138
+ * Injects dependencies by looking up names in the InjectionRegistry.
139
+ * Used for legacy string-based injection pattern.
140
+ *
141
+ * @param names - Array of injection names to look up and inject
142
+ * @internal
143
+ */
144
+ private injectDependenciesByName;
145
+ /**
146
+ * Injects dependencies from a property-name-to-class map.
147
+ * Creates singleton instances for each service class.
148
+ *
149
+ * @param map - Object mapping property names to service class constructors
150
+ * @internal
151
+ */
152
+ private injectDependenciesByMap;
153
+ }
154
+ /**
155
+ * Factory function to create a typed Controller base class with dependency injection.
156
+ *
157
+ * This is the recommended way to create controllers with injected services.
158
+ * It provides full TypeScript support for injected properties.
159
+ *
160
+ * @overload
161
+ * Creates a controller base class with object map injection (recommended).
162
+ *
163
+ * @template T - Record type mapping property names to service class constructors
164
+ * @param map - Object mapping property names to service classes, or async resolver function
165
+ * @returns A controller class constructor with typed injected properties
166
+ *
167
+ * @example
168
+ * ```ts
169
+ * // Static object map
170
+ * const ProductControllerBase = controller({
171
+ * productService: ProductService,
172
+ * categoryService: CategoryService,
173
+ * });
174
+ *
175
+ * export class ProductController extends ProductControllerBase {
176
+ * async findAll() {
177
+ * // this.productService is typed as ProductService
178
+ * return this.productService.findAll();
179
+ * }
180
+ * }
181
+ * ```
182
+ *
183
+ * @example
184
+ * ```ts
185
+ * // Async function with access to global injects
186
+ * const ProductControllerBase = controller(async (injects) => {
187
+ * const db = injects.get("db") as DatabaseConnection;
188
+ * console.log("DB type:", db.type);
189
+ *
190
+ * return {
191
+ * productService: ProductService,
192
+ * };
193
+ * });
194
+ * ```
195
+ */
196
+ export declare function controller<T extends Record<string, ClassContructor<any>>>(map: ControllerInjectMap<T>): new () => BaseController & InjectPropertiesByClass<T>;
197
+ /**
198
+ * @overload
199
+ * Creates a controller base class with string array injection (legacy pattern).
200
+ *
201
+ * @template T - Readonly array of injection name strings
202
+ * @param injects - Array of injection names from InjectionRegistry
203
+ * @returns A controller class constructor with typed injected properties
204
+ *
205
+ * @example
206
+ * ```ts
207
+ * // Legacy pattern using InjectionRegistry
208
+ * const MyController = controller(["userService", "productService"] as const);
209
+ *
210
+ * export class ProductController extends MyController {
211
+ * async findAll() {
212
+ * return this.productService.findAll();
213
+ * }
214
+ * }
215
+ * ```
216
+ */
217
+ export declare function controller<const T extends readonly string[]>(injects: T): new () => BaseController & InjectPropertiesByName<T>;
218
+ /**
219
+ * Base Controller class without any injections.
220
+ * Use this when you don't need dependency injection.
221
+ *
222
+ * @example
223
+ * ```ts
224
+ * export class SimpleController extends Controller {
225
+ * async healthCheck() {
226
+ * return { status: "ok" };
227
+ * }
228
+ * }
229
+ * ```
230
+ */
231
+ export declare const Controller: typeof BaseController;
232
+ /**
233
+ * Type alias for a controller class constructor.
234
+ *
235
+ * @template T - The controller instance type (must extend BaseController)
236
+ */
237
+ export type ControllerConstructor<T extends BaseController> = new () => T;
238
+ export {};
@@ -0,0 +1 @@
1
+ "use strict";var t=require("./context.js"),e=require("./common.js");const n=new WeakMap,i=new WeakMap;class s{constructor(){this._initialized=!1;const t=this.constructor.injects||[];this.injectDependenciesByName(t)}get context(){return t.executeContext}async _initDependencies(){if(this._initialized)return;const e=this.constructor.injectMap;if(!e)return void(this._initialized=!0);let n;i.has(this.constructor)?n=i.get(this.constructor):(n="function"==typeof e?await e(t.executeContext.injections):e,i.set(this.constructor,n)),this.injectDependenciesByMap(n),this._initialized=!0}injectDependenciesByName(t){for(const n of t){const t=e.InjectionRegistry.get(n);if(t){const e=t.singleton();e&&(this[n]=e)}}}injectDependenciesByMap(t){for(const[e,i]of Object.entries(t))if(n.has(i))this[e]=n.get(i);else if("singleton"in i&&"function"==typeof i.singleton){const t=i.singleton();n.set(i,t),this[e]=t}else{const t=new i;n.set(i,t),this[e]=t}}}const c=s;exports.Controller=c,exports.controller=function(t){if(Array.isArray(t)&&(0===t.length||"string"==typeof t[0])){const e=t;class n extends s{}return n.injects=e,n}const e=t;class n extends s{}return n.injectMap=e,n};
@@ -0,0 +1 @@
1
+ import{executeContext as t}from"./context.mjs";import{InjectionRegistry as e}from"./common.mjs";const n=new WeakMap,i=new WeakMap;class s{constructor(){this._initialized=!1;const t=this.constructor.injects||[];this.injectDependenciesByName(t)}get context(){return t}async _initDependencies(){if(this._initialized)return;const e=this.constructor.injectMap;if(!e)return void(this._initialized=!0);let n;i.has(this.constructor)?n=i.get(this.constructor):(n="function"==typeof e?await e(t.injections):e,i.set(this.constructor,n)),this.injectDependenciesByMap(n),this._initialized=!0}injectDependenciesByName(t){for(const n of t){const t=e.get(n);if(t){const e=t.singleton();e&&(this[n]=e)}}}injectDependenciesByMap(t){for(const[e,i]of Object.entries(t))if(n.has(i))this[e]=n.get(i);else if("singleton"in i&&"function"==typeof i.singleton){const t=i.singleton();n.set(i,t),this[e]=t}else{const t=new i;n.set(i,t),this[e]=t}}}function c(t){if(Array.isArray(t)&&(0===t.length||"string"==typeof t[0])){const e=t;class n extends s{}return n.injects=e,n}const e=t;class n extends s{}return n.injectMap=e,n}const o=s;export{o as Controller,c as controller};
@@ -0,0 +1,349 @@
1
+ /**
2
+ * @fileoverview Decorator utilities and context extractors for route handling.
3
+ *
4
+ * This module provides:
5
+ * - Route-level decorators for guards, filters, interceptors, pipes, and metadata
6
+ * - Context extractors for accessing request data (body, query, params, headers)
7
+ * - Custom decorator creation utilities
8
+ *
9
+ * @module decorator
10
+ */
11
+ import { ExecuteContext, Filter, Guard, Interceptor } from "./execute";
12
+ import { FeatureInject, Pipe } from "./common";
13
+ /**
14
+ * Result object from decorator functions.
15
+ * Contains sets of guards, filters, interceptors, pipes, and metadata
16
+ * that will be applied to a route.
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * const result: DecoratorResult = UseGuards(AuthGuard);
21
+ * // result.guards contains AuthGuard
22
+ * ```
23
+ */
24
+ export interface DecoratorResult {
25
+ /** Set of guard classes to apply */
26
+ guards: Set<Guard>;
27
+ /** Set of exception filter classes to apply */
28
+ filters: Set<Filter>;
29
+ /** Set of interceptor classes to apply */
30
+ interceptors: Set<Interceptor>;
31
+ /** Set of pipe classes to apply */
32
+ pipes: Set<Pipe>;
33
+ /** Map of metadata key-value pairs */
34
+ metadata: Map<string, unknown>;
35
+ }
36
+ /**
37
+ * Sets custom metadata on a route.
38
+ * Metadata can be retrieved in guards, interceptors, or handlers via `Metadata()`.
39
+ *
40
+ * @param key - The metadata key
41
+ * @param value - The metadata value
42
+ * @returns DecoratorResult containing the metadata
43
+ *
44
+ * @example
45
+ * ```ts
46
+ * // In route definition
47
+ * Route.get("/admin", "dashboard", SetMetadata("roles", ["admin"]))
48
+ *
49
+ * // In guard
50
+ * const roles = Metadata<string[]>("roles"); // ["admin"]
51
+ * ```
52
+ */
53
+ export declare function SetMetadata(key: string, value: unknown): DecoratorResult;
54
+ /**
55
+ * Applies guard classes to a route.
56
+ * Guards determine if a request should be processed by the handler.
57
+ *
58
+ * @param guards - Guard classes to apply (executed in order)
59
+ * @returns DecoratorResult containing the guards
60
+ *
61
+ * @example
62
+ * ```ts
63
+ * Route.post("/products", "create", UseGuards(AuthGuard, RolesGuard))
64
+ * ```
65
+ */
66
+ export declare function UseGuards(...guards: Guard[]): DecoratorResult;
67
+ /**
68
+ * Applies exception filter classes to a route.
69
+ * Filters handle exceptions thrown during request processing.
70
+ *
71
+ * @param filters - Exception filter classes to apply
72
+ * @returns DecoratorResult containing the filters
73
+ *
74
+ * @example
75
+ * ```ts
76
+ * Route.get("/products", "findAll", UseFilters(HttpExceptionFilter))
77
+ * ```
78
+ */
79
+ export declare function UseFilters(...filters: Filter[]): DecoratorResult;
80
+ /**
81
+ * Applies interceptor classes to a route.
82
+ * Interceptors can transform the request/response or add extra logic.
83
+ *
84
+ * @param interceptors - Interceptor classes to apply
85
+ * @returns DecoratorResult containing the interceptors
86
+ *
87
+ * @example
88
+ * ```ts
89
+ * Route.get("/products", "findAll", UseInterceptors(LoggingInterceptor, CacheInterceptor))
90
+ * ```
91
+ */
92
+ export declare function UseInterceptors(...interceptors: Interceptor[]): DecoratorResult;
93
+ /**
94
+ * Applies pipe classes to a route.
95
+ * Pipes transform input data before it reaches the handler.
96
+ *
97
+ * @param pipes - Pipe classes to apply
98
+ * @returns DecoratorResult containing the pipes
99
+ *
100
+ * @example
101
+ * ```ts
102
+ * Route.post("/products", "create", UsePipes(ValidationPipe))
103
+ * ```
104
+ */
105
+ export declare function UsePipes(...pipes: Pipe[]): DecoratorResult;
106
+ /**
107
+ * Combines multiple decorator results into a single result.
108
+ * Use this to apply multiple decorators to a single route.
109
+ *
110
+ * @param results - Array of DecoratorResult objects to combine
111
+ * @returns Combined DecoratorResult with all guards, filters, interceptors, pipes, and metadata
112
+ *
113
+ * @example
114
+ * ```ts
115
+ * const AdminRoute = applyDecorators(
116
+ * SetMetadata("roles", ["admin"]),
117
+ * UseGuards(AuthGuard, RolesGuard),
118
+ * UseInterceptors(LoggingInterceptor)
119
+ * );
120
+ *
121
+ * Route.get("/admin/dashboard", "dashboard", AdminRoute)
122
+ * ```
123
+ */
124
+ export declare function applyDecorators(...results: DecoratorResult[]): DecoratorResult;
125
+ /**
126
+ * Extracts and parses the JSON body from the request.
127
+ *
128
+ * @template T - Expected type of the parsed body
129
+ * @returns Promise resolving to the parsed JSON body
130
+ *
131
+ * @example
132
+ * ```ts
133
+ * async create() {
134
+ * const body = await Body<CreateProductDto>();
135
+ * return this.productService.create(body);
136
+ * }
137
+ * ```
138
+ */
139
+ export declare function Body<T = unknown>(): Promise<T>;
140
+ /**
141
+ * Extracts all query parameters from the request URL.
142
+ *
143
+ * @template T - Expected type of the query object
144
+ * @returns Object containing all query parameters
145
+ *
146
+ * @example
147
+ * ```ts
148
+ * findAll() {
149
+ * const query = Query<{ page?: string; limit?: string }>();
150
+ * const page = parseInt(query.page ?? "1");
151
+ * return this.productService.findAll({ page });
152
+ * }
153
+ * ```
154
+ */
155
+ export declare function Query<T extends Record<string, string> = Record<string, string>>(): T;
156
+ /**
157
+ * Extracts all route parameters from the matched route.
158
+ *
159
+ * @template T - Expected type of the params object
160
+ * @returns Object containing all route parameters
161
+ *
162
+ * @example
163
+ * ```ts
164
+ * // Route: /products/:category/:id
165
+ * findOne() {
166
+ * const params = Params<{ category: string; id: string }>();
167
+ * return this.productService.findOne(params.category, params.id);
168
+ * }
169
+ * ```
170
+ */
171
+ export declare function Params<T extends Record<string, string> = Record<string, string>>(): T;
172
+ /**
173
+ * Extracts all headers from the request.
174
+ *
175
+ * @template T - Expected type of the headers object
176
+ * @returns Object containing all request headers (lowercase keys)
177
+ *
178
+ * @example
179
+ * ```ts
180
+ * findAll() {
181
+ * const headers = Headers();
182
+ * const authToken = headers["authorization"];
183
+ * const contentType = headers["content-type"];
184
+ * }
185
+ * ```
186
+ */
187
+ export declare function Headers<T extends Record<string, string> = Record<string, string>>(): T;
188
+ /**
189
+ * Extracts a single route parameter by key.
190
+ *
191
+ * @param key - The parameter key to extract
192
+ * @returns The parameter value or undefined if not found
193
+ *
194
+ * @example
195
+ * ```ts
196
+ * // Route: /products/:id
197
+ * findById() {
198
+ * const id = Param("id");
199
+ * return this.productService.findById(id!);
200
+ * }
201
+ * ```
202
+ */
203
+ export declare function Param(key: string): string | undefined;
204
+ /**
205
+ * Extracts a single header by key.
206
+ *
207
+ * @param key - The header key to extract (case-insensitive)
208
+ * @returns The header value or undefined if not found
209
+ *
210
+ * @example
211
+ * ```ts
212
+ * findAll() {
213
+ * const token = Header("Authorization");
214
+ * const userAgent = Header("User-Agent");
215
+ * }
216
+ * ```
217
+ */
218
+ export declare function Header(key: string): string | undefined;
219
+ /**
220
+ * Extracts a single query parameter by key.
221
+ *
222
+ * @param key - The query parameter key to extract
223
+ * @returns The query parameter value or undefined if not found
224
+ *
225
+ * @example
226
+ * ```ts
227
+ * findAll() {
228
+ * const page = QueryParam("page") ?? "1";
229
+ * const limit = QueryParam("limit") ?? "10";
230
+ * }
231
+ * ```
232
+ */
233
+ export declare function QueryParam(key: string): string | undefined;
234
+ /**
235
+ * Extracts the raw Request object.
236
+ *
237
+ * @returns The underlying Request object (NextRequest)
238
+ *
239
+ * @example
240
+ * ```ts
241
+ * findAll() {
242
+ * const request = Request();
243
+ * const url = request.url;
244
+ * const method = request.method;
245
+ * }
246
+ * ```
247
+ */
248
+ export declare function Request(): globalThis.Request;
249
+ /**
250
+ * Extracts and parses FormData from the request body.
251
+ *
252
+ * @returns Promise resolving to the FormData object
253
+ *
254
+ * @example
255
+ * ```ts
256
+ * async upload() {
257
+ * const formData = await FormData();
258
+ * const file = formData.get("file");
259
+ * const name = formData.get("name");
260
+ * }
261
+ * ```
262
+ */
263
+ export declare function FormData(): Promise<globalThis.FormData>;
264
+ /**
265
+ * Extracts the raw text body from the request.
266
+ *
267
+ * @returns Promise resolving to the text body
268
+ *
269
+ * @example
270
+ * ```ts
271
+ * async webhook() {
272
+ * const rawBody = await Text();
273
+ * const signature = Header("x-signature");
274
+ * // Verify webhook signature with raw body
275
+ * }
276
+ * ```
277
+ */
278
+ export declare function Text(): Promise<string>;
279
+ /**
280
+ * Retrieves a feature-local inject by name.
281
+ *
282
+ * @template T - Expected type of the inject (must extend FeatureInject)
283
+ * @param name - The name of the inject to retrieve
284
+ * @returns The inject instance or undefined if not found
285
+ *
286
+ * @example
287
+ * ```ts
288
+ * findAll() {
289
+ * const repository = Inject<ProductRepository>("productRepository");
290
+ * return repository?.findAll();
291
+ * }
292
+ * ```
293
+ */
294
+ export declare function Inject<T extends FeatureInject = FeatureInject>(name: string): T | undefined;
295
+ /**
296
+ * Retrieves route metadata by key.
297
+ * Use with `SetMetadata()` to pass data to handlers/guards.
298
+ *
299
+ * @template T - Expected type of the metadata value
300
+ * @param key - The metadata key to retrieve
301
+ * @returns The metadata value or undefined if not found
302
+ *
303
+ * @example
304
+ * ```ts
305
+ * // Route definition
306
+ * Route.get("/admin", "dashboard", SetMetadata("roles", ["admin"]))
307
+ *
308
+ * // In handler or guard
309
+ * const roles = Metadata<string[]>("roles"); // ["admin"]
310
+ * ```
311
+ */
312
+ export declare function Metadata<T = unknown>(key: string): T | undefined;
313
+ /**
314
+ * Type for custom decorator creator functions.
315
+ *
316
+ * @template Result - The return type of the decorator
317
+ * @template Data - Tuple type of arguments passed to the decorator
318
+ */
319
+ export type DecoratorCreator<Result, Data extends any[] = []> = (context: ExecuteContext, data: Data) => Result | Promise<Result>;
320
+ /**
321
+ * Factory function to create custom context extractors/decorators.
322
+ *
323
+ * @template Result - The return type of the custom decorator
324
+ * @template Data - Tuple type of arguments the decorator accepts
325
+ * @param callback - Function that receives ExecuteContext and arguments, returns result
326
+ * @returns A function that can be called with arguments to extract/compute data
327
+ *
328
+ * @example
329
+ * ```ts
330
+ * // Create a custom decorator to get current user
331
+ * const CurrentUser = createDecorator<User | null>((context) => {
332
+ * const token = context.switchHttp().headers()["authorization"];
333
+ * return token ? parseToken(token) : null;
334
+ * });
335
+ *
336
+ * // Create a decorator with arguments
337
+ * const HasRole = createDecorator<boolean, [string]>((context, [role]) => {
338
+ * const user = getCurrentUser(context);
339
+ * return user?.roles.includes(role) ?? false;
340
+ * });
341
+ *
342
+ * // Usage in handler
343
+ * async dashboard() {
344
+ * const user = CurrentUser();
345
+ * const isAdmin = HasRole("admin");
346
+ * }
347
+ * ```
348
+ */
349
+ export declare function createDecorator<Result, Data extends any[] = []>(callback: DecoratorCreator<Result, Data>): (...args: Data) => Result | Promise<Result>;
@@ -0,0 +1 @@
1
+ "use strict";var e=require("./context.js");exports.Body=function(){return e.executeContext.switchHttp().json()},exports.FormData=function(){return e.executeContext.switchHttp().formData()},exports.Header=function(t){return e.executeContext.switchHttp().headers()[t.toLowerCase()]},exports.Headers=function(){return e.executeContext.switchHttp().headers()},exports.Inject=function(t){return e.executeContext.getLocalInject(t)},exports.Metadata=function(t){return e.executeContext.getMetadata(t)},exports.Param=function(t){return e.executeContext.switchHttp().params()[t]},exports.Params=function(){return e.executeContext.switchHttp().params()},exports.Query=function(){return e.executeContext.switchHttp().query()},exports.QueryParam=function(t){return e.executeContext.switchHttp().query()[t]},exports.Request=function(){return e.executeContext.switchHttp().getRequest()},exports.SetMetadata=function(e,t){return{guards:new Set,filters:new Set,interceptors:new Set,pipes:new Set,metadata:new Map([[e,t]])}},exports.Text=function(){return e.executeContext.switchHttp().text()},exports.UseFilters=function(...e){return{guards:new Set,filters:new Set(e),interceptors:new Set,pipes:new Set,metadata:new Map}},exports.UseGuards=function(...e){return{guards:new Set(e),filters:new Set,interceptors:new Set,pipes:new Set,metadata:new Map}},exports.UseInterceptors=function(...e){return{guards:new Set,filters:new Set,interceptors:new Set(e),pipes:new Set,metadata:new Map}},exports.UsePipes=function(...e){return{guards:new Set,filters:new Set,interceptors:new Set,pipes:new Set(e),metadata:new Map}},exports.applyDecorators=function(...e){const t=new Set,r=new Set,n=new Set,s=new Set,a=new Map;return e.forEach(e=>{e.guards.forEach(e=>t.add(e)),e.filters.forEach(e=>r.add(e)),e.interceptors.forEach(e=>n.add(e)),e.pipes.forEach(e=>s.add(e)),e.metadata.forEach((e,t)=>a.set(t,e))}),{guards:t,filters:r,interceptors:n,pipes:s,metadata:a}},exports.createDecorator=function(t){return(...r)=>t(e.executeContext,r)};
@@ -0,0 +1 @@
1
+ import{executeContext as t}from"./context.mjs";function e(t,e){return{guards:new Set,filters:new Set,interceptors:new Set,pipes:new Set,metadata:new Map([[t,e]])}}function n(...t){return{guards:new Set(t),filters:new Set,interceptors:new Set,pipes:new Set,metadata:new Map}}function r(...t){return{guards:new Set,filters:new Set(t),interceptors:new Set,pipes:new Set,metadata:new Map}}function a(...t){return{guards:new Set,filters:new Set,interceptors:new Set(t),pipes:new Set,metadata:new Map}}function i(...t){return{guards:new Set,filters:new Set,interceptors:new Set,pipes:new Set(t),metadata:new Map}}function s(...t){const e=new Set,n=new Set,r=new Set,a=new Set,i=new Map;return t.forEach(t=>{t.guards.forEach(t=>e.add(t)),t.filters.forEach(t=>n.add(t)),t.interceptors.forEach(t=>r.add(t)),t.pipes.forEach(t=>a.add(t)),t.metadata.forEach((t,e)=>i.set(e,t))}),{guards:e,filters:n,interceptors:r,pipes:a,metadata:i}}function u(){return t.switchHttp().json()}function c(){return t.switchHttp().query()}function o(){return t.switchHttp().params()}function p(){return t.switchHttp().headers()}function w(e){return t.switchHttp().params()[e]}function f(e){return t.switchHttp().headers()[e.toLowerCase()]}function d(e){return t.switchHttp().query()[e]}function S(){return t.switchHttp().getRequest()}function h(){return t.switchHttp().formData()}function m(){return t.switchHttp().text()}function g(e){return t.getLocalInject(e)}function H(e){return t.getMetadata(e)}function l(e){return(...n)=>e(t,n)}export{u as Body,h as FormData,f as Header,p as Headers,g as Inject,H as Metadata,w as Param,o as Params,c as Query,d as QueryParam,S as Request,e as SetMetadata,m as Text,r as UseFilters,n as UseGuards,a as UseInterceptors,i as UsePipes,s as applyDecorators,l as createDecorator};