wynkjs 1.0.8 → 1.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/common/http-status.enum.d.ts +129 -0
- package/dist/common/http-status.enum.js +135 -0
- package/dist/cors.d.ts +0 -1
- package/dist/cors.js +2 -2
- package/dist/database.d.ts +0 -1
- package/dist/decorators/database.decorators.d.ts +0 -1
- package/dist/decorators/database.decorators.js +2 -2
- package/dist/decorators/di.decorators.d.ts +13 -0
- package/dist/decorators/di.decorators.js +28 -0
- package/dist/decorators/exception.decorators.d.ts +34 -1
- package/dist/decorators/exception.decorators.js +44 -6
- package/dist/decorators/formatter.decorators.d.ts +0 -1
- package/dist/decorators/guard.decorators.d.ts +22 -3
- package/dist/decorators/guard.decorators.js +1 -0
- package/dist/decorators/http.decorators.d.ts +30 -1
- package/dist/decorators/http.decorators.js +25 -4
- package/dist/decorators/interceptor.advanced.d.ts +0 -1
- package/dist/decorators/interceptor.decorators.d.ts +40 -3
- package/dist/decorators/metadata.decorators.d.ts +71 -0
- package/dist/decorators/metadata.decorators.js +134 -0
- package/dist/decorators/param.decorators.d.ts +27 -2
- package/dist/decorators/pipe.advanced.d.ts +19 -26
- package/dist/decorators/pipe.advanced.js +84 -54
- package/dist/decorators/pipe.decorators.d.ts +76 -12
- package/dist/decorators/pipe.decorators.js +55 -8
- package/dist/dto.d.ts +0 -1
- package/dist/factory.d.ts +270 -20
- package/dist/factory.js +284 -68
- package/dist/filters/exception.filters.d.ts +0 -1
- package/dist/filters/exception.filters.js +3 -3
- package/dist/global-prefix.d.ts +2 -3
- package/dist/global-prefix.js +4 -6
- package/dist/index.d.ts +6 -1
- package/dist/index.js +10 -0
- package/dist/interfaces/interceptor.interface.d.ts +0 -1
- package/dist/interfaces/lifecycle.interface.d.ts +53 -0
- package/dist/interfaces/lifecycle.interface.js +1 -0
- package/dist/module.d.ts +53 -0
- package/dist/module.js +35 -0
- package/dist/pipes/validation.pipe.d.ts +1 -2
- package/dist/pipes/validation.pipe.js +1 -1
- package/dist/plugins/compression.d.ts +0 -1
- package/dist/plugins/compression.js +24 -9
- package/dist/request.d.ts +0 -1
- package/dist/request.js +1 -0
- package/dist/response.d.ts +0 -1
- package/dist/response.js +1 -0
- package/dist/schema-registry.d.ts +0 -1
- package/dist/testing/index.d.ts +0 -1
- package/dist/testing/test-utils.d.ts +0 -1
- package/dist/ultra-optimized-handler.d.ts +0 -1
- package/dist/ultra-optimized-handler.js +16 -3
- package/package.json +13 -4
- package/dist/cors.d.ts.map +0 -1
- package/dist/database.d.ts.map +0 -1
- package/dist/decorators/database.decorators.d.ts.map +0 -1
- package/dist/decorators/exception.advanced.d.ts +0 -457
- package/dist/decorators/exception.advanced.d.ts.map +0 -1
- package/dist/decorators/exception.advanced.js +0 -742
- package/dist/decorators/exception.decorators.d.ts.map +0 -1
- package/dist/decorators/formatter.decorators.d.ts.map +0 -1
- package/dist/decorators/guard.decorators.d.ts.map +0 -1
- package/dist/decorators/http.decorators.d.ts.map +0 -1
- package/dist/decorators/interceptor.advanced.d.ts.map +0 -1
- package/dist/decorators/interceptor.decorators.d.ts.map +0 -1
- package/dist/decorators/param.decorators.d.ts.map +0 -1
- package/dist/decorators/pipe.advanced.d.ts.map +0 -1
- package/dist/decorators/pipe.decorators.d.ts.map +0 -1
- package/dist/dto.d.ts.map +0 -1
- package/dist/factory.d.ts.map +0 -1
- package/dist/filters/exception.filters.d.ts.map +0 -1
- package/dist/global-prefix.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/interfaces/interceptor.interface.d.ts.map +0 -1
- package/dist/optimized-handler.d.ts +0 -31
- package/dist/optimized-handler.d.ts.map +0 -1
- package/dist/optimized-handler.js +0 -180
- package/dist/pipes/validation.pipe.d.ts.map +0 -1
- package/dist/plugins/compression.d.ts.map +0 -1
- package/dist/request.d.ts.map +0 -1
- package/dist/response.d.ts.map +0 -1
- package/dist/schema-registry.d.ts.map +0 -1
- package/dist/testing/index.d.ts.map +0 -1
- package/dist/testing/test-utils.d.ts.map +0 -1
- package/dist/ultra-optimized-handler.d.ts.map +0 -1
|
@@ -4,17 +4,37 @@ import "reflect-metadata";
|
|
|
4
4
|
* Guards for route protection and authorization
|
|
5
5
|
*/
|
|
6
6
|
/**
|
|
7
|
-
* Execution context interface
|
|
7
|
+
* Execution context interface — provides typed access to the current request cycle.
|
|
8
|
+
* Passed to guards, interceptors, and exception filters.
|
|
8
9
|
*/
|
|
9
10
|
export interface ExecutionContext {
|
|
11
|
+
/** Returns the underlying request object (typed as `T`). */
|
|
10
12
|
getRequest<T = any>(): T;
|
|
13
|
+
/** Returns the underlying response/set object (typed as `T`). */
|
|
11
14
|
getResponse<T = any>(): T;
|
|
15
|
+
/** Returns the full Elysia context object (typed as `T`). */
|
|
12
16
|
getContext<T = any>(): T;
|
|
17
|
+
/** Returns the route handler function currently being invoked. */
|
|
13
18
|
getHandler(): Function;
|
|
19
|
+
/** Returns the controller class that owns the current route handler. */
|
|
14
20
|
getClass(): any;
|
|
21
|
+
/**
|
|
22
|
+
* Returns the transport type of the current request.
|
|
23
|
+
* WynkJS currently always returns `'http'`.
|
|
24
|
+
*/
|
|
25
|
+
getType(): 'http' | 'ws' | 'rpc';
|
|
15
26
|
}
|
|
16
27
|
/**
|
|
17
|
-
*
|
|
28
|
+
* Interface that all guards must implement.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* @Injectable()
|
|
32
|
+
* export class AuthGuard implements CanActivate {
|
|
33
|
+
* canActivate(context: ExecutionContext): boolean {
|
|
34
|
+
* const req = context.getRequest<Request>();
|
|
35
|
+
* return req.headers.get('authorization') !== null;
|
|
36
|
+
* }
|
|
37
|
+
* }
|
|
18
38
|
*/
|
|
19
39
|
export interface CanActivate {
|
|
20
40
|
canActivate(context: ExecutionContext): boolean | Promise<boolean>;
|
|
@@ -40,4 +60,3 @@ export declare function createExecutionContext(ctx: any, handler: Function, cont
|
|
|
40
60
|
* Helper function to execute guards
|
|
41
61
|
*/
|
|
42
62
|
export declare function executeGuards(guards: (Function | CanActivate)[], context: ExecutionContext): Promise<boolean>;
|
|
43
|
-
//# sourceMappingURL=guard.decorators.d.ts.map
|
|
@@ -4,12 +4,25 @@ import "reflect-metadata";
|
|
|
4
4
|
* RESTful route handlers with TypeScript decorators
|
|
5
5
|
* Optimized for WynkJS's performance on Bun runtime
|
|
6
6
|
*/
|
|
7
|
+
/**
|
|
8
|
+
* Options accepted by HTTP method decorators when passed as an object.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* @Post({ path: '/users', body: CreateUserDTO, query: PaginationDTO })
|
|
12
|
+
* create(@Body() dto: CreateUserType, @Query() q: PaginationQuery) {}
|
|
13
|
+
*/
|
|
7
14
|
export interface RouteOptions {
|
|
15
|
+
/** Route path (e.g. `'/'`, `'/:id'`). Defaults to `''`. */
|
|
8
16
|
path?: string;
|
|
17
|
+
/** TypeBox schema used to validate and type the request body. */
|
|
9
18
|
body?: any;
|
|
19
|
+
/** TypeBox schema used to validate route path parameters. */
|
|
10
20
|
params?: any;
|
|
21
|
+
/** TypeBox schema used to validate query string parameters. */
|
|
11
22
|
query?: any;
|
|
23
|
+
/** TypeBox schema used to validate request headers. */
|
|
12
24
|
headers?: any;
|
|
25
|
+
/** TypeBox schema describing the response shape (informational / Swagger). */
|
|
13
26
|
response?: any;
|
|
14
27
|
}
|
|
15
28
|
/**
|
|
@@ -121,6 +134,23 @@ export declare function Header(name: string, value: string): MethodDecorator;
|
|
|
121
134
|
* redirect() {}
|
|
122
135
|
*/
|
|
123
136
|
export declare function Redirect(url: string, statusCode?: number): MethodDecorator;
|
|
137
|
+
/**
|
|
138
|
+
* Server-Sent Events (SSE) decorator — registers a GET route and marks it as
|
|
139
|
+
* an SSE endpoint via metadata. Note: the caller is responsible for setting
|
|
140
|
+
* `Content-Type: text/event-stream` and streaming the response appropriately;
|
|
141
|
+
* WynkJS does not configure this automatically at this time.
|
|
142
|
+
*
|
|
143
|
+
* @param pathOrOptions Route path string or {@link RouteOptions} object.
|
|
144
|
+
*
|
|
145
|
+
* @example
|
|
146
|
+
* ```typescript
|
|
147
|
+
* @Sse('/events')
|
|
148
|
+
* streamEvents() {
|
|
149
|
+
* // Set Content-Type header and return a streaming response manually
|
|
150
|
+
* }
|
|
151
|
+
* ```
|
|
152
|
+
*/
|
|
153
|
+
export declare function Sse(pathOrOptions?: string | RouteOptions): MethodDecorator;
|
|
124
154
|
/**
|
|
125
155
|
* Use decorator - Apply middleware to controller or method
|
|
126
156
|
* Simple middleware pattern like your working code
|
|
@@ -135,4 +165,3 @@ export declare function Redirect(url: string, statusCode?: number): MethodDecora
|
|
|
135
165
|
* async findAll() {}
|
|
136
166
|
*/
|
|
137
167
|
export declare function Use(...middlewares: any[]): ClassDecorator & MethodDecorator;
|
|
138
|
-
//# sourceMappingURL=http.decorators.d.ts.map
|
|
@@ -143,13 +143,9 @@ function createRouteDecorator(method, path, options) {
|
|
|
143
143
|
methodName: propertyKey,
|
|
144
144
|
options,
|
|
145
145
|
});
|
|
146
|
-
console.log(`🔹 Storing route: ${method} ${path} on ${constructor.name}.${String(propertyKey)} (routes: ${routes.length})`);
|
|
147
146
|
Reflect.defineMetadata("routes", routes, constructor.prototype);
|
|
148
147
|
// Also store on constructor for compatibility
|
|
149
148
|
Reflect.defineMetadata("routes", routes, constructor);
|
|
150
|
-
// Verify it was stored
|
|
151
|
-
const verify = Reflect.getMetadata("routes", constructor.prototype) || [];
|
|
152
|
-
console.log(`✅ Verified ${verify.length} routes stored on ${constructor.name}.prototype`);
|
|
153
149
|
// Store method-specific metadata
|
|
154
150
|
Reflect.defineMetadata("route:method", method, target, propertyKey);
|
|
155
151
|
Reflect.defineMetadata("route:path", path, target, propertyKey);
|
|
@@ -204,6 +200,31 @@ export function Redirect(url, statusCode = 302) {
|
|
|
204
200
|
return descriptor;
|
|
205
201
|
};
|
|
206
202
|
}
|
|
203
|
+
/**
|
|
204
|
+
* Server-Sent Events (SSE) decorator — registers a GET route and marks it as
|
|
205
|
+
* an SSE endpoint via metadata. Note: the caller is responsible for setting
|
|
206
|
+
* `Content-Type: text/event-stream` and streaming the response appropriately;
|
|
207
|
+
* WynkJS does not configure this automatically at this time.
|
|
208
|
+
*
|
|
209
|
+
* @param pathOrOptions Route path string or {@link RouteOptions} object.
|
|
210
|
+
*
|
|
211
|
+
* @example
|
|
212
|
+
* ```typescript
|
|
213
|
+
* @Sse('/events')
|
|
214
|
+
* streamEvents() {
|
|
215
|
+
* // Set Content-Type header and return a streaming response manually
|
|
216
|
+
* }
|
|
217
|
+
* ```
|
|
218
|
+
*/
|
|
219
|
+
export function Sse(pathOrOptions) {
|
|
220
|
+
const path = typeof pathOrOptions === "string"
|
|
221
|
+
? pathOrOptions
|
|
222
|
+
: pathOrOptions?.path || "";
|
|
223
|
+
const options = typeof pathOrOptions === "object" && pathOrOptions !== null
|
|
224
|
+
? { ...pathOrOptions, sse: true }
|
|
225
|
+
: { sse: true };
|
|
226
|
+
return createRouteDecorator("GET", path, options);
|
|
227
|
+
}
|
|
207
228
|
/**
|
|
208
229
|
* Use decorator - Apply middleware to controller or method
|
|
209
230
|
* Simple middleware pattern like your working code
|
|
@@ -90,4 +90,3 @@ export declare class SanitizeInterceptor implements WynkInterceptor {
|
|
|
90
90
|
export declare class PaginationInterceptor implements WynkInterceptor {
|
|
91
91
|
intercept(context: InterceptorContext, next: () => Promise<any>): Promise<any>;
|
|
92
92
|
}
|
|
93
|
-
//# sourceMappingURL=interceptor.advanced.d.ts.map
|
|
@@ -6,17 +6,55 @@ type ExecutionContext = InterceptorContext;
|
|
|
6
6
|
* Interceptors for request/response transformation
|
|
7
7
|
*/
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
9
|
+
* Provides access to the handler return value as a promise.
|
|
10
|
+
*
|
|
11
|
+
* Passed as the second argument to `WynkInterceptor.intercept()`. Call
|
|
12
|
+
* `handle()` to invoke the next interceptor in the chain or the actual route
|
|
13
|
+
* handler. You can `await` the result to inspect or transform the response.
|
|
14
|
+
*
|
|
15
|
+
* @template T - The type of value returned by the handler
|
|
10
16
|
*/
|
|
11
17
|
export interface CallHandler<T = any> {
|
|
18
|
+
/** Invoke the next interceptor or the route handler and return its result. */
|
|
12
19
|
handle(): Promise<T>;
|
|
13
20
|
}
|
|
14
21
|
/**
|
|
15
|
-
*
|
|
22
|
+
* Interface that all WynkJS interceptors must implement.
|
|
23
|
+
*
|
|
24
|
+
* Interceptors sit between the client request and the route handler. They can
|
|
25
|
+
* execute logic before AND after the handler, transform the result, catch errors,
|
|
26
|
+
* and even override the response entirely.
|
|
27
|
+
*
|
|
28
|
+
* Use `@UseInterceptors()` to apply an interceptor to a controller or route.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```typescript
|
|
32
|
+
* import { Injectable } from "wynkjs";
|
|
33
|
+
* import { WynkInterceptor } from "wynkjs";
|
|
34
|
+
*
|
|
35
|
+
* @Injectable()
|
|
36
|
+
* export class LoggingInterceptor implements WynkInterceptor {
|
|
37
|
+
* async intercept(context: ExecutionContext, next: () => Promise<any>) {
|
|
38
|
+
* console.log("Before handler");
|
|
39
|
+
* const result = await next();
|
|
40
|
+
* console.log("After handler");
|
|
41
|
+
* return result;
|
|
42
|
+
* }
|
|
43
|
+
* }
|
|
44
|
+
* ```
|
|
16
45
|
*/
|
|
17
46
|
export interface WynkInterceptor {
|
|
47
|
+
/**
|
|
48
|
+
* Called for every request that passes through this interceptor.
|
|
49
|
+
*
|
|
50
|
+
* @param context - The execution context for the current request
|
|
51
|
+
* @param next - Call `next()` to invoke the next interceptor / route handler
|
|
52
|
+
* @returns The (possibly transformed) response value
|
|
53
|
+
*/
|
|
18
54
|
intercept(context: ExecutionContext, next: () => Promise<any>): Promise<any>;
|
|
19
55
|
}
|
|
56
|
+
/** NestJS-compatible generic alias for {@link WynkInterceptor}. */
|
|
57
|
+
export type NestInterceptor<T = any, R = any> = WynkInterceptor;
|
|
20
58
|
/**
|
|
21
59
|
* @UseInterceptors decorator - Apply interceptors to routes or controllers
|
|
22
60
|
* @param interceptors Interceptor classes to apply
|
|
@@ -90,4 +128,3 @@ export declare class LoggingInterceptor implements WynkInterceptor {
|
|
|
90
128
|
intercept(context: InterceptorContext, next: () => Promise<any>): Promise<any>;
|
|
91
129
|
}
|
|
92
130
|
export {};
|
|
93
|
-
//# sourceMappingURL=interceptor.decorators.d.ts.map
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import "reflect-metadata";
|
|
2
|
+
import type { ExecutionContext } from "./guard.decorators";
|
|
3
|
+
/**
|
|
4
|
+
* Attaches custom metadata to a class or method using the reflect-metadata API.
|
|
5
|
+
* Retrieve the value at runtime via the `Reflector` class.
|
|
6
|
+
*
|
|
7
|
+
* @param metadataKey - The key under which the value is stored
|
|
8
|
+
* @param metadataValue - The value to store
|
|
9
|
+
* @returns A decorator applicable to both classes and methods
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* // Define a helper decorator
|
|
13
|
+
* export const Roles = (...roles: string[]) => SetMetadata('roles', roles);
|
|
14
|
+
*
|
|
15
|
+
* // Use in controller
|
|
16
|
+
* @Roles('admin', 'editor')
|
|
17
|
+
* @Get('/secret')
|
|
18
|
+
* getSecret() {}
|
|
19
|
+
*/
|
|
20
|
+
export declare function SetMetadata<K = string, V = any>(metadataKey: K, metadataValue: V): MethodDecorator & ClassDecorator;
|
|
21
|
+
/**
|
|
22
|
+
* Reads metadata stored by `SetMetadata` across one or multiple targets.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* const reflector = new Reflector();
|
|
26
|
+
*
|
|
27
|
+
* // In a guard:
|
|
28
|
+
* const roles = reflector.getAllAndOverride<string[]>('roles', [
|
|
29
|
+
* context.getHandler(),
|
|
30
|
+
* context.getClass(),
|
|
31
|
+
* ]);
|
|
32
|
+
*/
|
|
33
|
+
export declare class Reflector {
|
|
34
|
+
get<TResult = any>(metadataKey: string, target: Function | object): TResult | undefined;
|
|
35
|
+
getAllAndOverride<TResult = any>(metadataKey: string, targets: (Function | object)[]): TResult | undefined;
|
|
36
|
+
getAllAndMerge<TResult = any>(metadataKey: string, targets: (Function | object)[]): TResult[];
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Composes multiple decorators into one, applying them left-to-right.
|
|
40
|
+
*
|
|
41
|
+
* @param decorators - One or more class/method/property decorators
|
|
42
|
+
* @returns A single decorator that applies all provided decorators
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* export const Auth = (...roles: string[]) => applyDecorators(
|
|
46
|
+
* SetMetadata('roles', roles),
|
|
47
|
+
* UseGuards(AuthGuard, RolesGuard),
|
|
48
|
+
* );
|
|
49
|
+
*
|
|
50
|
+
* @Get('/admin')
|
|
51
|
+
* @Auth('admin')
|
|
52
|
+
* adminOnly() {}
|
|
53
|
+
*/
|
|
54
|
+
export declare function applyDecorators(...decorators: (ClassDecorator | MethodDecorator | PropertyDecorator)[]): (target: any, key?: any, descriptor?: any) => any;
|
|
55
|
+
/**
|
|
56
|
+
* Creates a custom parameter decorator that calls `factory` to produce the
|
|
57
|
+
* injected value at request time.
|
|
58
|
+
*
|
|
59
|
+
* @param factory - Called with `(data, ctx)` where `data` is the argument passed
|
|
60
|
+
* to the decorator and `ctx` is the current `ExecutionContext`.
|
|
61
|
+
* @returns A decorator factory: `(data?) => ParameterDecorator`
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* const CurrentUser = createParamDecorator((data, ctx: ExecutionContext) => {
|
|
65
|
+
* return ctx.getRequest().user;
|
|
66
|
+
* });
|
|
67
|
+
*
|
|
68
|
+
* @Get('/profile')
|
|
69
|
+
* getProfile(@CurrentUser() user: User) {}
|
|
70
|
+
*/
|
|
71
|
+
export declare function createParamDecorator<TData = unknown>(factory: (data: TData, ctx: ExecutionContext) => any): (data?: TData) => ParameterDecorator;
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import "reflect-metadata";
|
|
2
|
+
/**
|
|
3
|
+
* Attaches custom metadata to a class or method using the reflect-metadata API.
|
|
4
|
+
* Retrieve the value at runtime via the `Reflector` class.
|
|
5
|
+
*
|
|
6
|
+
* @param metadataKey - The key under which the value is stored
|
|
7
|
+
* @param metadataValue - The value to store
|
|
8
|
+
* @returns A decorator applicable to both classes and methods
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* // Define a helper decorator
|
|
12
|
+
* export const Roles = (...roles: string[]) => SetMetadata('roles', roles);
|
|
13
|
+
*
|
|
14
|
+
* // Use in controller
|
|
15
|
+
* @Roles('admin', 'editor')
|
|
16
|
+
* @Get('/secret')
|
|
17
|
+
* getSecret() {}
|
|
18
|
+
*/
|
|
19
|
+
export function SetMetadata(metadataKey, metadataValue) {
|
|
20
|
+
return (target, propertyKey, descriptor) => {
|
|
21
|
+
if (propertyKey !== undefined && descriptor !== undefined) {
|
|
22
|
+
Reflect.defineMetadata(metadataKey, metadataValue, target, propertyKey);
|
|
23
|
+
return descriptor;
|
|
24
|
+
}
|
|
25
|
+
Reflect.defineMetadata(metadataKey, metadataValue, target);
|
|
26
|
+
return target;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Reads metadata stored by `SetMetadata` across one or multiple targets.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* const reflector = new Reflector();
|
|
34
|
+
*
|
|
35
|
+
* // In a guard:
|
|
36
|
+
* const roles = reflector.getAllAndOverride<string[]>('roles', [
|
|
37
|
+
* context.getHandler(),
|
|
38
|
+
* context.getClass(),
|
|
39
|
+
* ]);
|
|
40
|
+
*/
|
|
41
|
+
export class Reflector {
|
|
42
|
+
get(metadataKey, target) {
|
|
43
|
+
return Reflect.getMetadata(metadataKey, target);
|
|
44
|
+
}
|
|
45
|
+
getAllAndOverride(metadataKey, targets) {
|
|
46
|
+
for (const target of targets) {
|
|
47
|
+
const value = Reflect.getMetadata(metadataKey, target);
|
|
48
|
+
if (value !== undefined)
|
|
49
|
+
return value;
|
|
50
|
+
}
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
53
|
+
getAllAndMerge(metadataKey, targets) {
|
|
54
|
+
const result = [];
|
|
55
|
+
for (const target of targets) {
|
|
56
|
+
const value = Reflect.getMetadata(metadataKey, target);
|
|
57
|
+
if (value !== undefined) {
|
|
58
|
+
if (Array.isArray(value))
|
|
59
|
+
result.push(...value);
|
|
60
|
+
else
|
|
61
|
+
result.push(value);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return result;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Composes multiple decorators into one, applying them left-to-right.
|
|
69
|
+
*
|
|
70
|
+
* @param decorators - One or more class/method/property decorators
|
|
71
|
+
* @returns A single decorator that applies all provided decorators
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* export const Auth = (...roles: string[]) => applyDecorators(
|
|
75
|
+
* SetMetadata('roles', roles),
|
|
76
|
+
* UseGuards(AuthGuard, RolesGuard),
|
|
77
|
+
* );
|
|
78
|
+
*
|
|
79
|
+
* @Get('/admin')
|
|
80
|
+
* @Auth('admin')
|
|
81
|
+
* adminOnly() {}
|
|
82
|
+
*/
|
|
83
|
+
export function applyDecorators(...decorators) {
|
|
84
|
+
return (target, key, descriptor) => {
|
|
85
|
+
let currentTarget = target;
|
|
86
|
+
let currentDescriptor = descriptor;
|
|
87
|
+
for (const decorator of decorators) {
|
|
88
|
+
if (key !== undefined && currentDescriptor !== undefined) {
|
|
89
|
+
const nextDescriptor = decorator(currentTarget, key, currentDescriptor);
|
|
90
|
+
currentDescriptor = nextDescriptor ?? currentDescriptor;
|
|
91
|
+
}
|
|
92
|
+
else if (key !== undefined) {
|
|
93
|
+
decorator(currentTarget, key);
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
const nextTarget = decorator(currentTarget);
|
|
97
|
+
currentTarget = nextTarget ?? currentTarget;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return currentDescriptor ?? currentTarget;
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Creates a custom parameter decorator that calls `factory` to produce the
|
|
105
|
+
* injected value at request time.
|
|
106
|
+
*
|
|
107
|
+
* @param factory - Called with `(data, ctx)` where `data` is the argument passed
|
|
108
|
+
* to the decorator and `ctx` is the current `ExecutionContext`.
|
|
109
|
+
* @returns A decorator factory: `(data?) => ParameterDecorator`
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* const CurrentUser = createParamDecorator((data, ctx: ExecutionContext) => {
|
|
113
|
+
* return ctx.getRequest().user;
|
|
114
|
+
* });
|
|
115
|
+
*
|
|
116
|
+
* @Get('/profile')
|
|
117
|
+
* getProfile(@CurrentUser() user: User) {}
|
|
118
|
+
*/
|
|
119
|
+
export function createParamDecorator(factory) {
|
|
120
|
+
return (data) => {
|
|
121
|
+
return (target, propertyKey, parameterIndex) => {
|
|
122
|
+
if (!propertyKey)
|
|
123
|
+
return;
|
|
124
|
+
const existingParams = Reflect.getMetadata("params", target, propertyKey) || [];
|
|
125
|
+
existingParams.push({
|
|
126
|
+
index: parameterIndex,
|
|
127
|
+
type: "custom",
|
|
128
|
+
data: data,
|
|
129
|
+
factory: (d, ctx) => factory(d, ctx),
|
|
130
|
+
});
|
|
131
|
+
Reflect.defineMetadata("params", existingParams, target, propertyKey);
|
|
132
|
+
};
|
|
133
|
+
};
|
|
134
|
+
}
|
|
@@ -3,12 +3,38 @@ import "reflect-metadata";
|
|
|
3
3
|
* Parameter Decorators for WynkJS Framework
|
|
4
4
|
* Extract data from request context
|
|
5
5
|
*/
|
|
6
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Identifies the source from which a parameter decorator extracts its value.
|
|
8
|
+
*
|
|
9
|
+
* - `body` — request body (JSON payload)
|
|
10
|
+
* - `param` — URL path parameter (e.g. `/users/:id`)
|
|
11
|
+
* - `query` — query string parameter (e.g. `?page=1`)
|
|
12
|
+
* - `headers` — HTTP request headers
|
|
13
|
+
* - `request` — full Elysia request object
|
|
14
|
+
* - `response` — Elysia response/set object
|
|
15
|
+
* - `context` — full Elysia context
|
|
16
|
+
* - `user` — user object attached to context by a guard
|
|
17
|
+
* - `file` — single uploaded file
|
|
18
|
+
* - `files` — multiple uploaded files
|
|
19
|
+
* - `custom` — value produced by a `createParamDecorator` factory function
|
|
20
|
+
*/
|
|
21
|
+
export type ParamType = "body" | "param" | "query" | "headers" | "request" | "response" | "context" | "user" | "file" | "files" | "custom";
|
|
22
|
+
/**
|
|
23
|
+
* Internal metadata stored for each decorated parameter in a controller method.
|
|
24
|
+
* Populated by parameter decorators (`@Body`, `@Param`, `@Query`, etc.) and
|
|
25
|
+
* consumed by the ultra-optimized handler at request time.
|
|
26
|
+
*/
|
|
7
27
|
export interface ParamMetadata {
|
|
28
|
+
/** Zero-based position of this parameter in the method signature. */
|
|
8
29
|
index: number;
|
|
30
|
+
/** Where to extract the value from — see {@link ParamType}. */
|
|
9
31
|
type: ParamType;
|
|
32
|
+
/** Optional key to pluck from the source (e.g. param name or header name). */
|
|
10
33
|
data?: string;
|
|
34
|
+
/** Optional pipes applied to the extracted value before it reaches the handler. */
|
|
11
35
|
pipes?: any[];
|
|
36
|
+
/** Factory function used when `type === 'custom'` (from `createParamDecorator`). */
|
|
37
|
+
factory?: (data: any, ctx: any) => any;
|
|
12
38
|
}
|
|
13
39
|
/**
|
|
14
40
|
* @Body decorator - Extracts request body
|
|
@@ -141,4 +167,3 @@ export declare function Session(property?: string): ParameterDecorator;
|
|
|
141
167
|
* }
|
|
142
168
|
*/
|
|
143
169
|
export declare function HostParam(property: string): ParameterDecorator;
|
|
144
|
-
//# sourceMappingURL=param.decorators.d.ts.map
|
|
@@ -11,33 +11,27 @@ import { WynkPipeTransform, ArgumentMetadata } from "./pipe.decorators";
|
|
|
11
11
|
* async getByDate(@Param('date', ParseDatePipe) date: Date) {}
|
|
12
12
|
*/
|
|
13
13
|
export declare class ParseDatePipe implements WynkPipeTransform<string, Date> {
|
|
14
|
-
transform(value: string,
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Parse File Pipe - Validates and transforms file uploads
|
|
18
|
-
* @example
|
|
19
|
-
* @Post('/upload')
|
|
20
|
-
* async uploadFile(@UploadedFile(ParseFilePipe) file: any) {}
|
|
21
|
-
*/
|
|
22
|
-
export declare class ParseFilePipe implements WynkPipeTransform<any, any> {
|
|
23
|
-
private options?;
|
|
24
|
-
constructor(options?: {
|
|
25
|
-
maxSize?: number;
|
|
26
|
-
allowedTypes?: string[];
|
|
27
|
-
required?: boolean;
|
|
28
|
-
} | undefined);
|
|
29
|
-
transform(value: any, metadata?: ArgumentMetadata): any;
|
|
14
|
+
transform(value: string, _metadata?: ArgumentMetadata): Date;
|
|
30
15
|
}
|
|
31
16
|
/**
|
|
32
17
|
* Sanitize Pipe - Sanitizes input by removing dangerous characters
|
|
18
|
+
*
|
|
19
|
+
* SECURITY NOTICE: This pipe provides basic normalization (script tag removal,
|
|
20
|
+
* javascript: protocol stripping, inline event handler removal). It is NOT a
|
|
21
|
+
* replacement for a dedicated XSS sanitization library such as `sanitize-html`
|
|
22
|
+
* or `DOMPurify` when rendering user content as HTML. Use this pipe for
|
|
23
|
+
* light input cleaning only; apply a full sanitizer at the HTML rendering layer.
|
|
24
|
+
*
|
|
33
25
|
* @example
|
|
34
26
|
* @Post()
|
|
35
27
|
* async create(@Body(SanitizePipe) data: any) {}
|
|
36
28
|
*/
|
|
37
29
|
export declare class SanitizePipe implements WynkPipeTransform {
|
|
38
30
|
private dangerousPatterns;
|
|
39
|
-
transform(value: any,
|
|
31
|
+
transform(value: any, _metadata?: ArgumentMetadata): any;
|
|
40
32
|
private sanitizeString;
|
|
33
|
+
private removeEventHandlers;
|
|
34
|
+
private removeScriptTags;
|
|
41
35
|
}
|
|
42
36
|
/**
|
|
43
37
|
* Transform Case Pipe - Transforms string case
|
|
@@ -48,7 +42,7 @@ export declare class SanitizePipe implements WynkPipeTransform {
|
|
|
48
42
|
export declare class TransformCasePipe implements WynkPipeTransform<string, string> {
|
|
49
43
|
private caseType;
|
|
50
44
|
constructor(caseType?: "lower" | "upper" | "title");
|
|
51
|
-
transform(value: string,
|
|
45
|
+
transform(value: string, _metadata?: ArgumentMetadata): string;
|
|
52
46
|
}
|
|
53
47
|
/**
|
|
54
48
|
* Parse JSON Pipe - Parses JSON strings
|
|
@@ -57,7 +51,7 @@ export declare class TransformCasePipe implements WynkPipeTransform<string, stri
|
|
|
57
51
|
* async create(@Body('metadata', ParseJSONPipe) metadata: any) {}
|
|
58
52
|
*/
|
|
59
53
|
export declare class ParseJSONPipe implements WynkPipeTransform<string, any> {
|
|
60
|
-
transform(value: string,
|
|
54
|
+
transform(value: string, _metadata?: ArgumentMetadata): any;
|
|
61
55
|
}
|
|
62
56
|
/**
|
|
63
57
|
* Validate Email Pipe - Validates email format
|
|
@@ -67,7 +61,7 @@ export declare class ParseJSONPipe implements WynkPipeTransform<string, any> {
|
|
|
67
61
|
*/
|
|
68
62
|
export declare class ValidateEmailPipe implements WynkPipeTransform<string, string> {
|
|
69
63
|
private emailRegex;
|
|
70
|
-
transform(value: string,
|
|
64
|
+
transform(value: string, _metadata?: ArgumentMetadata): string;
|
|
71
65
|
}
|
|
72
66
|
/**
|
|
73
67
|
* Validate Length Pipe - Validates string/array length
|
|
@@ -79,7 +73,7 @@ export declare class ValidateLengthPipe implements WynkPipeTransform {
|
|
|
79
73
|
private min?;
|
|
80
74
|
private max?;
|
|
81
75
|
constructor(min?: number | undefined, max?: number | undefined);
|
|
82
|
-
transform(value: any,
|
|
76
|
+
transform(value: any, _metadata?: ArgumentMetadata): any;
|
|
83
77
|
}
|
|
84
78
|
/**
|
|
85
79
|
* Validate Range Pipe - Validates number is within range
|
|
@@ -91,7 +85,7 @@ export declare class ValidateRangePipe implements WynkPipeTransform<number, numb
|
|
|
91
85
|
private min?;
|
|
92
86
|
private max?;
|
|
93
87
|
constructor(min?: number | undefined, max?: number | undefined);
|
|
94
|
-
transform(value: number,
|
|
88
|
+
transform(value: number, _metadata?: ArgumentMetadata): number;
|
|
95
89
|
}
|
|
96
90
|
/**
|
|
97
91
|
* Strip HTML Pipe - Removes HTML tags from string
|
|
@@ -100,7 +94,7 @@ export declare class ValidateRangePipe implements WynkPipeTransform<number, numb
|
|
|
100
94
|
* async create(@Body('comment', StripHTMLPipe) comment: string) {}
|
|
101
95
|
*/
|
|
102
96
|
export declare class StripHTMLPipe implements WynkPipeTransform<string, string> {
|
|
103
|
-
transform(value: string,
|
|
97
|
+
transform(value: string, _metadata?: ArgumentMetadata): string;
|
|
104
98
|
}
|
|
105
99
|
/**
|
|
106
100
|
* Slugify Pipe - Converts string to URL-friendly slug
|
|
@@ -109,7 +103,7 @@ export declare class StripHTMLPipe implements WynkPipeTransform<string, string>
|
|
|
109
103
|
* async create(@Body('title', SlugifyPipe) slug: string) {}
|
|
110
104
|
*/
|
|
111
105
|
export declare class SlugifyPipe implements WynkPipeTransform<string, string> {
|
|
112
|
-
transform(value: string,
|
|
106
|
+
transform(value: string, _metadata?: ArgumentMetadata): string;
|
|
113
107
|
}
|
|
114
108
|
/**
|
|
115
109
|
* Parse Comma Separated Pipe - Converts comma-separated string to array
|
|
@@ -120,6 +114,5 @@ export declare class SlugifyPipe implements WynkPipeTransform<string, string> {
|
|
|
120
114
|
export declare class ParseCommaSeparatedPipe implements WynkPipeTransform<string, string[]> {
|
|
121
115
|
private trim;
|
|
122
116
|
constructor(trim?: boolean);
|
|
123
|
-
transform(value: string,
|
|
117
|
+
transform(value: string, _metadata?: ArgumentMetadata): string[];
|
|
124
118
|
}
|
|
125
|
-
//# sourceMappingURL=pipe.advanced.d.ts.map
|