adorn-api 1.0.1 → 1.0.2
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 +4 -1
- package/dist/adapters/express/createApp.d.ts +149 -11
- package/dist/adapters/express/createApp.d.ts.map +1 -1
- package/dist/adapters/express/createApp.js +112 -6
- package/dist/adapters/express/createApp.js.map +1 -1
- package/dist/adapters/express/middleware/errorHandler.d.ts +193 -2
- package/dist/adapters/express/middleware/errorHandler.d.ts.map +1 -1
- package/dist/adapters/express/middleware/errorHandler.js +164 -3
- package/dist/adapters/express/middleware/errorHandler.js.map +1 -1
- package/dist/adapters/express/router.d.ts +1 -1
- package/dist/adapters/express/router.d.ts.map +1 -1
- package/dist/adapters/express/router.js +6 -4
- package/dist/adapters/express/router.js.map +1 -1
- package/dist/adapters/express/transport/request.js.map +1 -1
- package/dist/adapters/express/transport/response.d.ts +1 -1
- package/dist/adapters/express/transport/response.d.ts.map +1 -1
- package/dist/adapters/express/transport/response.js.map +1 -1
- package/dist/contracts/openapi-v3.d.ts +461 -0
- package/dist/contracts/openapi-v3.d.ts.map +1 -1
- package/dist/contracts/reply.d.ts +109 -1
- package/dist/contracts/reply.d.ts.map +1 -1
- package/dist/contracts/reply.js +40 -1
- package/dist/contracts/reply.js.map +1 -1
- package/dist/contracts/response-types.d.ts +5 -5
- package/dist/contracts/response-types.d.ts.map +1 -1
- package/dist/contracts/responses.d.ts +84 -4
- package/dist/contracts/responses.d.ts.map +1 -1
- package/dist/contracts/route-options.d.ts +134 -3
- package/dist/contracts/route-options.d.ts.map +1 -1
- package/dist/contracts/validator.d.ts +121 -0
- package/dist/contracts/validator.d.ts.map +1 -1
- package/dist/core/binding/binder.d.ts +56 -1
- package/dist/core/binding/binder.d.ts.map +1 -1
- package/dist/core/binding/binder.js +33 -0
- package/dist/core/binding/binder.js.map +1 -1
- package/dist/core/binding/coerce/primitives.d.ts +68 -1
- package/dist/core/binding/coerce/primitives.d.ts.map +1 -1
- package/dist/core/binding/coerce/primitives.js +82 -12
- package/dist/core/binding/coerce/primitives.js.map +1 -1
- package/dist/core/errors/http-error.d.ts +54 -0
- package/dist/core/errors/http-error.d.ts.map +1 -1
- package/dist/core/errors/http-error.js +54 -0
- package/dist/core/errors/http-error.js.map +1 -1
- package/dist/core/errors/validation-error.d.ts +65 -0
- package/dist/core/errors/validation-error.d.ts.map +1 -1
- package/dist/core/errors/validation-error.js +65 -0
- package/dist/core/errors/validation-error.js.map +1 -1
- package/dist/core/openapi/buildOpenApi.d.ts +65 -0
- package/dist/core/openapi/buildOpenApi.d.ts.map +1 -1
- package/dist/core/openapi/buildOpenApi.js +66 -4
- package/dist/core/openapi/buildOpenApi.js.map +1 -1
- package/dist/core/openapi/schema/registry.d.ts +1 -1
- package/dist/core/openapi/schema/registry.d.ts.map +1 -1
- package/dist/core/openapi/schema/registry.js.map +1 -1
- package/dist/core/registry/buildRegistry.d.ts.map +1 -1
- package/dist/core/registry/buildRegistry.js +49 -5
- package/dist/core/registry/buildRegistry.js.map +1 -1
- package/dist/core/registry/types.d.ts +194 -1
- package/dist/core/registry/types.d.ts.map +1 -1
- package/dist/core/reply/reply.d.ts +94 -0
- package/dist/core/reply/reply.d.ts.map +1 -1
- package/dist/core/reply/reply.js +87 -0
- package/dist/core/reply/reply.js.map +1 -1
- package/dist/core/reply/typed.d.ts +137 -3
- package/dist/core/reply/typed.d.ts.map +1 -1
- package/dist/core/reply/typed.js +137 -2
- package/dist/core/reply/typed.js.map +1 -1
- package/dist/core/responses/helpers.d.ts +1 -1
- package/dist/core/responses/helpers.d.ts.map +1 -1
- package/dist/core/responses/normalize.d.ts.map +1 -1
- package/dist/core/responses/normalize.js +2 -1
- package/dist/core/responses/normalize.js.map +1 -1
- package/dist/core/route/defineRoute.d.ts +48 -1
- package/dist/core/route/defineRoute.d.ts.map +1 -1
- package/dist/core/route/defineRoute.js +42 -1
- package/dist/core/route/defineRoute.js.map +1 -1
- package/dist/decorators/binding.d.ts +1 -1
- package/dist/decorators/binding.d.ts.map +1 -1
- package/dist/decorators/binding.js.map +1 -1
- package/dist/decorators/controller.d.ts +1 -1
- package/dist/decorators/controller.d.ts.map +1 -1
- package/dist/decorators/controller.js.map +1 -1
- package/dist/decorators/docs.d.ts +6 -0
- package/dist/decorators/docs.d.ts.map +1 -1
- package/dist/decorators/docs.js +45 -2
- package/dist/decorators/docs.js.map +1 -1
- package/dist/decorators/index.d.ts +3 -0
- package/dist/decorators/index.d.ts.map +1 -1
- package/dist/decorators/index.js +3 -0
- package/dist/decorators/index.js.map +1 -1
- package/dist/decorators/methods.d.ts +128 -6
- package/dist/decorators/methods.d.ts.map +1 -1
- package/dist/decorators/methods.js +124 -0
- package/dist/decorators/methods.js.map +1 -1
- package/dist/decorators/responses.d.ts +5 -0
- package/dist/decorators/responses.d.ts.map +1 -1
- package/dist/decorators/responses.js +43 -2
- package/dist/decorators/responses.js.map +1 -1
- package/dist/decorators/security.d.ts +6 -0
- package/dist/decorators/security.d.ts.map +1 -1
- package/dist/decorators/security.js +38 -2
- package/dist/decorators/security.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/integrations/metal-orm/schema/column-map.d.ts +91 -0
- package/dist/integrations/metal-orm/schema/column-map.d.ts.map +1 -1
- package/dist/integrations/metal-orm/schema/column-map.js +129 -2
- package/dist/integrations/metal-orm/schema/column-map.js.map +1 -1
- package/dist/integrations/metal-orm/schema/dto.d.ts +2 -2
- package/dist/integrations/metal-orm/schema/dto.d.ts.map +1 -1
- package/dist/integrations/metal-orm/schema/dto.js.map +1 -1
- package/dist/integrations/metal-orm/schema/entity.d.ts +90 -8
- package/dist/integrations/metal-orm/schema/entity.d.ts.map +1 -1
- package/dist/integrations/metal-orm/schema/entity.js +78 -6
- package/dist/integrations/metal-orm/schema/entity.js.map +1 -1
- package/dist/integrations/metal-orm/schema/filters.d.ts +1 -1
- package/dist/integrations/metal-orm/schema/filters.d.ts.map +1 -1
- package/dist/integrations/metal-orm/schema/filters.js +2 -1
- package/dist/integrations/metal-orm/schema/filters.js.map +1 -1
- package/dist/integrations/metal-orm/schema/tabledef.d.ts +1 -1
- package/dist/integrations/metal-orm/schema/tabledef.d.ts.map +1 -1
- package/dist/metadata/bag.d.ts +2 -1
- package/dist/metadata/bag.d.ts.map +1 -1
- package/dist/metadata/bag.js +2 -1
- package/dist/metadata/bag.js.map +1 -1
- package/dist/metadata/keys.d.ts +203 -1
- package/dist/metadata/keys.d.ts.map +1 -1
- package/dist/metadata/keys.js +3 -9
- package/dist/metadata/keys.js.map +1 -1
- package/dist/metadata/merge.d.ts.map +1 -1
- package/dist/metadata/merge.js +4 -1
- package/dist/metadata/merge.js.map +1 -1
- package/dist/validation/native/schema.d.ts +2 -2
- package/dist/validation/native/schema.d.ts.map +1 -1
- package/dist/validation/native/validator.d.ts +1 -1
- package/dist/validation/native/validator.d.ts.map +1 -1
- package/package.json +6 -2
package/dist/core/reply/reply.js
CHANGED
|
@@ -1,3 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates a typed HTTP response with body content.
|
|
3
|
+
*
|
|
4
|
+
* This function creates a Reply object with status code, body, and optional headers.
|
|
5
|
+
* It's the primary way to create successful responses with content in Adorn API.
|
|
6
|
+
*
|
|
7
|
+
* @template TBody - Type of the response body
|
|
8
|
+
* @template TStatus - HTTP status code (must be a number literal)
|
|
9
|
+
* @param status - HTTP status code
|
|
10
|
+
* @param body - Response body content
|
|
11
|
+
* @param init - Optional initialization options (headers, contentType)
|
|
12
|
+
* @returns Typed Reply object
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* // Simple JSON response
|
|
17
|
+
* return reply(200, { message: 'Success', data: user });
|
|
18
|
+
*
|
|
19
|
+
* // Response with custom headers
|
|
20
|
+
* return reply(201, createdUser, {
|
|
21
|
+
* headers: { 'Location': `/users/${createdUser.id}` },
|
|
22
|
+
* contentType: 'application/json'
|
|
23
|
+
* });
|
|
24
|
+
*
|
|
25
|
+
* // Error response
|
|
26
|
+
* return reply(404, { error: 'User not found', code: 'USER_NOT_FOUND' });
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```typescript
|
|
31
|
+
* // In a controller
|
|
32
|
+
* @Get('/users/:id')
|
|
33
|
+
* async getUser(id: string) {
|
|
34
|
+
* const user = await userService.findById(id);
|
|
35
|
+
* if (!user) {
|
|
36
|
+
* return reply(404, { error: 'User not found' });
|
|
37
|
+
* }
|
|
38
|
+
* return reply(200, user);
|
|
39
|
+
* }
|
|
40
|
+
* ```
|
|
41
|
+
*
|
|
42
|
+
* @see Reply for the return type structure
|
|
43
|
+
* @see noContent for responses without body
|
|
44
|
+
*/
|
|
1
45
|
export function reply(status, body, init = {}) {
|
|
2
46
|
return {
|
|
3
47
|
__adornReply: true,
|
|
@@ -7,6 +51,49 @@ export function reply(status, body, init = {}) {
|
|
|
7
51
|
...(init.contentType !== undefined ? { contentType: init.contentType } : {}),
|
|
8
52
|
};
|
|
9
53
|
}
|
|
54
|
+
/**
|
|
55
|
+
* Creates a typed HTTP response without body content.
|
|
56
|
+
*
|
|
57
|
+
* This function creates a Reply object for responses that don't include a body,
|
|
58
|
+
* such as 204 No Content responses. It's commonly used for successful DELETE operations
|
|
59
|
+
* or other operations where no response body is needed.
|
|
60
|
+
*
|
|
61
|
+
* @template TStatus - HTTP status code (default: 204, must be a number literal)
|
|
62
|
+
* @param status - Optional HTTP status code (default: 204)
|
|
63
|
+
* @param init - Optional initialization options (headers, contentType)
|
|
64
|
+
* @returns Typed Reply object without body
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* ```typescript
|
|
68
|
+
* // Standard 204 No Content response
|
|
69
|
+
* return noContent();
|
|
70
|
+
*
|
|
71
|
+
* // Custom no-content status with headers
|
|
72
|
+
* return noContent(202, {
|
|
73
|
+
* headers: { 'X-Request-Processed': 'true' }
|
|
74
|
+
* });
|
|
75
|
+
* ```
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* ```typescript
|
|
79
|
+
* // In a DELETE controller
|
|
80
|
+
* @Delete('/users/:id')
|
|
81
|
+
* async deleteUser(id: string) {
|
|
82
|
+
* await userService.delete(id);
|
|
83
|
+
* return noContent(); // 204 No Content
|
|
84
|
+
* }
|
|
85
|
+
*
|
|
86
|
+
* // Custom accepted response
|
|
87
|
+
* @Post('/users/bulk-delete')
|
|
88
|
+
* async bulkDeleteUser(ids: string[]) {
|
|
89
|
+
* await userService.bulkDelete(ids);
|
|
90
|
+
* return noContent(202); // 202 Accepted
|
|
91
|
+
* }
|
|
92
|
+
* ```
|
|
93
|
+
*
|
|
94
|
+
* @see Reply for the return type structure
|
|
95
|
+
* @see reply for responses with body content
|
|
96
|
+
*/
|
|
10
97
|
export function noContent(status, init = {}) {
|
|
11
98
|
return {
|
|
12
99
|
__adornReply: true,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reply.js","sourceRoot":"","sources":["../../../src/core/reply/reply.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"reply.js","sourceRoot":"","sources":["../../../src/core/reply/reply.ts"],"names":[],"mappings":"AAcA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,MAAM,UAAU,KAAK,CACnB,MAAe,EACf,IAAW,EACX,OAAkB,EAAE;IAEpB,OAAO;QACL,YAAY,EAAE,IAAI;QAClB,MAAM;QACN,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvC,GAAG,CAAC,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChE,GAAG,CAAC,IAAI,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC7E,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,MAAM,UAAU,SAAS,CACvB,MAAgB,EAChB,OAAkB,EAAE;IAEpB,OAAO;QACL,YAAY,EAAE,IAAI;QAClB,MAAM,EAAE,CAAC,MAAM,IAAK,GAAe,CAAC;QACpC,GAAG,CAAC,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChE,GAAG,CAAC,IAAI,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC7E,CAAC;AACJ,CAAC"}
|
|
@@ -4,22 +4,156 @@ import type { Schema, Infer } from '../../validation/native/schema.js';
|
|
|
4
4
|
import type { ReplyInit } from './reply.js';
|
|
5
5
|
import type { AllowedStatus, BodySchemaFor, HeadersDefFor, StatusesNoBody, StatusesWithBody } from '../../contracts/response-types.js';
|
|
6
6
|
type HeaderValueFromSpec<H> = H extends {
|
|
7
|
-
schema: infer S extends Schema<
|
|
7
|
+
schema: infer S extends Schema<unknown>;
|
|
8
8
|
} ? (Exclude<Infer<S>, undefined> extends ReplyHeaderValue ? Exclude<Infer<S>, undefined> : ReplyHeaderValue) : ReplyHeaderValue;
|
|
9
|
-
type HeaderValues<H> = H extends Record<string,
|
|
9
|
+
type HeaderValues<H> = H extends Record<string, unknown> ? string extends keyof H ? Record<string, HeaderValueFromSpec<H[string]>> : {
|
|
10
10
|
[K in keyof H]?: HeaderValueFromSpec<H[K]>;
|
|
11
11
|
} : never;
|
|
12
12
|
type InitFor<R extends ResponsesSpec, S extends number> = Omit<ReplyInit, 'headers'> & {
|
|
13
13
|
headers?: HeaderValues<HeadersDefFor<R, S>>;
|
|
14
14
|
};
|
|
15
|
+
/**
|
|
16
|
+
* Creates a typed reply builder function based on route responses specification.
|
|
17
|
+
*
|
|
18
|
+
* This function generates a reply builder that is type-safe based on the
|
|
19
|
+
* ResponsesSpec provided. It ensures that only valid status codes and
|
|
20
|
+
* body types can be used, providing excellent TypeScript support.
|
|
21
|
+
*
|
|
22
|
+
* @template R - Responses specification for the route
|
|
23
|
+
* @param _responses - Responses specification object
|
|
24
|
+
* @returns Typed reply builder with `reply` and `noContent` methods
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* // Define route with responses
|
|
29
|
+
* const userRoute = defineRoute('/users/:id', {
|
|
30
|
+
* responses: {
|
|
31
|
+
* 200: {
|
|
32
|
+
* description: 'User found',
|
|
33
|
+
* content: {
|
|
34
|
+
* 'application/json': {
|
|
35
|
+
* schema: Schema.Object({
|
|
36
|
+
* id: Schema.String().format('uuid'),
|
|
37
|
+
* name: Schema.String(),
|
|
38
|
+
* email: Schema.String().format('email')
|
|
39
|
+
* })
|
|
40
|
+
* }
|
|
41
|
+
* }
|
|
42
|
+
* },
|
|
43
|
+
* 404: {
|
|
44
|
+
* description: 'User not found',
|
|
45
|
+
* content: {
|
|
46
|
+
* 'application/json': {
|
|
47
|
+
* schema: Schema.Object({
|
|
48
|
+
* error: Schema.String(),
|
|
49
|
+
* code: Schema.String()
|
|
50
|
+
* })
|
|
51
|
+
* }
|
|
52
|
+
* }
|
|
53
|
+
* }
|
|
54
|
+
* }
|
|
55
|
+
* });
|
|
56
|
+
*
|
|
57
|
+
* // Use the typed reply function
|
|
58
|
+
* const reply = userRoute.reply;
|
|
59
|
+
*
|
|
60
|
+
* // Type-safe responses
|
|
61
|
+
* reply(200, { id: '123', name: 'John', email: 'john@example.com' }); // ✅ Valid
|
|
62
|
+
* reply(404, { error: 'Not found', code: 'USER_NOT_FOUND' }); // ✅ Valid
|
|
63
|
+
* reply(200, { error: 'Wrong' }); // ❌ Type error - wrong body type
|
|
64
|
+
* reply(500, { error: 'Server error' }); // ❌ Type error - 500 not in responses
|
|
65
|
+
* ```
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```typescript
|
|
69
|
+
* // In a controller with route definition
|
|
70
|
+
* const route = routeFor('/users')({
|
|
71
|
+
* responses: {
|
|
72
|
+
* 201: {
|
|
73
|
+
* description: 'User created',
|
|
74
|
+
* content: {
|
|
75
|
+
* 'application/json': {
|
|
76
|
+
* schema: userSchema
|
|
77
|
+
* }
|
|
78
|
+
* }
|
|
79
|
+
* },
|
|
80
|
+
* 400: {
|
|
81
|
+
* description: 'Bad request',
|
|
82
|
+
* content: {
|
|
83
|
+
* 'application/json': {
|
|
84
|
+
* schema: errorSchema
|
|
85
|
+
* }
|
|
86
|
+
* }
|
|
87
|
+
* }
|
|
88
|
+
* }
|
|
89
|
+
* });
|
|
90
|
+
*
|
|
91
|
+
* class UserController {
|
|
92
|
+
* @Post('/users')
|
|
93
|
+
* async createUser(@Body() userData: CreateUserDto) {
|
|
94
|
+
* const createdUser = await userService.create(userData);
|
|
95
|
+
* return route.reply(201, createdUser); // Type-safe!
|
|
96
|
+
* }
|
|
97
|
+
* }
|
|
98
|
+
* ```
|
|
99
|
+
*
|
|
100
|
+
* @see ResponsesSpec for response specification format
|
|
101
|
+
* @see defineRoute for creating route definitions
|
|
102
|
+
*/
|
|
15
103
|
export declare function makeReply<const R extends ResponsesSpec>(_responses: R): {
|
|
16
104
|
/**
|
|
105
|
+
* Creates a typed response with body content.
|
|
106
|
+
*
|
|
17
107
|
* Only allowed for statuses that have a body schema in `responses`.
|
|
18
|
-
* Body is type-checked against that schema.
|
|
108
|
+
* Body is type-checked against that schema for complete type safety.
|
|
109
|
+
*
|
|
110
|
+
* @template S - Status code that must be in responses and allow body
|
|
111
|
+
* @param status - HTTP status code
|
|
112
|
+
* @param body - Response body (type-checked against schema)
|
|
113
|
+
* @param init - Optional initialization options
|
|
114
|
+
* @returns Typed Reply object
|
|
115
|
+
*
|
|
116
|
+
* @example
|
|
117
|
+
* ```typescript
|
|
118
|
+
* // With route definition
|
|
119
|
+
* const reply = makeReply({
|
|
120
|
+
* 200: {
|
|
121
|
+
* content: {
|
|
122
|
+
* 'application/json': {
|
|
123
|
+
* schema: Schema.Object({ name: Schema.String() })
|
|
124
|
+
* }
|
|
125
|
+
* }
|
|
126
|
+
* }
|
|
127
|
+
* });
|
|
128
|
+
*
|
|
129
|
+
* reply.reply(200, { name: 'John' }); // ✅ Valid
|
|
130
|
+
* reply.reply(200, { age: 30 }); // ❌ Type error - missing name, wrong property
|
|
131
|
+
* ```
|
|
19
132
|
*/
|
|
20
133
|
reply<const S extends AllowedStatus<R> & StatusesWithBody<R>>(status: S, body: Infer<BodySchemaFor<R, S>>, init?: InitFor<R, S>): Reply<Infer<BodySchemaFor<R, S>>, S>;
|
|
21
134
|
/**
|
|
135
|
+
* Creates a typed response without body content.
|
|
136
|
+
*
|
|
22
137
|
* For no-content responses (204 etc) or when you want an empty body.
|
|
138
|
+
* Only allowed for status codes that don't require a body in the responses spec.
|
|
139
|
+
*
|
|
140
|
+
* @template S - Status code that must be in responses and not require body
|
|
141
|
+
* @param status - Optional HTTP status code (uses default from responses if omitted)
|
|
142
|
+
* @param init - Optional initialization options
|
|
143
|
+
* @returns Typed Reply object without body
|
|
144
|
+
*
|
|
145
|
+
* @example
|
|
146
|
+
* ```typescript
|
|
147
|
+
* // With route definition
|
|
148
|
+
* const reply = makeReply({
|
|
149
|
+
* 204: { description: 'No content' },
|
|
150
|
+
* 202: { description: 'Accepted' }
|
|
151
|
+
* });
|
|
152
|
+
*
|
|
153
|
+
* reply.noContent(); // ✅ Uses 204 by default
|
|
154
|
+
* reply.noContent(202); // ✅ Explicit 202 status
|
|
155
|
+
* reply.noContent(200); // ❌ Type error - 200 not in no-content responses
|
|
156
|
+
* ```
|
|
23
157
|
*/
|
|
24
158
|
noContent<const S extends AllowedStatus<R> & (StatusesNoBody<R> | number)>(status?: S, init?: InitFor<R, S>): Reply<undefined, S>;
|
|
25
159
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typed.d.ts","sourceRoot":"","sources":["../../../src/core/reply/typed.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACxE,OAAO,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,mCAAmC,CAAC;AACvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,OAAO,KAAK,EACV,aAAa,EACb,aAAa,EACb,aAAa,EACb,cAAc,EACd,gBAAgB,EACjB,MAAM,mCAAmC,CAAC;AAE3C,KAAK,mBAAmB,CAAC,CAAC,IACxB,CAAC,SAAS;IAAE,MAAM,EAAE,MAAM,CAAC,SAAS,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"typed.d.ts","sourceRoot":"","sources":["../../../src/core/reply/typed.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACxE,OAAO,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,mCAAmC,CAAC;AACvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,OAAO,KAAK,EACV,aAAa,EACb,aAAa,EACb,aAAa,EACb,cAAc,EACd,gBAAgB,EACjB,MAAM,mCAAmC,CAAC;AAE3C,KAAK,mBAAmB,CAAC,CAAC,IACxB,CAAC,SAAS;IAAE,MAAM,EAAE,MAAM,CAAC,SAAS,MAAM,CAAC,OAAO,CAAC,CAAA;CAAE,GACjD,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,SAAS,gBAAgB,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,GAAG,gBAAgB,CAAC,GACzG,gBAAgB,CAAC;AAEvB,KAAK,YAAY,CAAC,CAAC,IACjB,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,MAAM,SAAS,MAAM,CAAC,GACpB,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAC9C;KAAG,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAAE,GAChD,KAAK,CAAC;AAEZ,KAAK,OAAO,CAAC,CAAC,SAAS,aAAa,EAAE,CAAC,SAAS,MAAM,IACpD,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,GAAG;IAAE,OAAO,CAAC,EAAE,YAAY,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;CAAE,CAAC;AAE/E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuFG;AACH,wBAAgB,SAAS,CAAC,KAAK,CAAC,CAAC,SAAS,aAAa,EAAE,UAAU,EAAE,CAAC;IAElE;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;gBACS,CAAC,SAAS,aAAa,CAAC,CAAC,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAAC,UAClD,CAAC,QACH,KAAK,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SACzB,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,GACnB,KAAK,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAIvC;;;;;;;;;;;;;;;;;;;;;;;OAuBG;oBACa,CAAC,SAAS,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,WAC9D,CAAC,SACH,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,GACnB,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC;EAKzB"}
|
package/dist/core/reply/typed.js
CHANGED
|
@@ -1,18 +1,153 @@
|
|
|
1
1
|
import { reply as baseReply, noContent as baseNoContent } from './reply.js';
|
|
2
|
+
/**
|
|
3
|
+
* Creates a typed reply builder function based on route responses specification.
|
|
4
|
+
*
|
|
5
|
+
* This function generates a reply builder that is type-safe based on the
|
|
6
|
+
* ResponsesSpec provided. It ensures that only valid status codes and
|
|
7
|
+
* body types can be used, providing excellent TypeScript support.
|
|
8
|
+
*
|
|
9
|
+
* @template R - Responses specification for the route
|
|
10
|
+
* @param _responses - Responses specification object
|
|
11
|
+
* @returns Typed reply builder with `reply` and `noContent` methods
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* // Define route with responses
|
|
16
|
+
* const userRoute = defineRoute('/users/:id', {
|
|
17
|
+
* responses: {
|
|
18
|
+
* 200: {
|
|
19
|
+
* description: 'User found',
|
|
20
|
+
* content: {
|
|
21
|
+
* 'application/json': {
|
|
22
|
+
* schema: Schema.Object({
|
|
23
|
+
* id: Schema.String().format('uuid'),
|
|
24
|
+
* name: Schema.String(),
|
|
25
|
+
* email: Schema.String().format('email')
|
|
26
|
+
* })
|
|
27
|
+
* }
|
|
28
|
+
* }
|
|
29
|
+
* },
|
|
30
|
+
* 404: {
|
|
31
|
+
* description: 'User not found',
|
|
32
|
+
* content: {
|
|
33
|
+
* 'application/json': {
|
|
34
|
+
* schema: Schema.Object({
|
|
35
|
+
* error: Schema.String(),
|
|
36
|
+
* code: Schema.String()
|
|
37
|
+
* })
|
|
38
|
+
* }
|
|
39
|
+
* }
|
|
40
|
+
* }
|
|
41
|
+
* }
|
|
42
|
+
* });
|
|
43
|
+
*
|
|
44
|
+
* // Use the typed reply function
|
|
45
|
+
* const reply = userRoute.reply;
|
|
46
|
+
*
|
|
47
|
+
* // Type-safe responses
|
|
48
|
+
* reply(200, { id: '123', name: 'John', email: 'john@example.com' }); // ✅ Valid
|
|
49
|
+
* reply(404, { error: 'Not found', code: 'USER_NOT_FOUND' }); // ✅ Valid
|
|
50
|
+
* reply(200, { error: 'Wrong' }); // ❌ Type error - wrong body type
|
|
51
|
+
* reply(500, { error: 'Server error' }); // ❌ Type error - 500 not in responses
|
|
52
|
+
* ```
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```typescript
|
|
56
|
+
* // In a controller with route definition
|
|
57
|
+
* const route = routeFor('/users')({
|
|
58
|
+
* responses: {
|
|
59
|
+
* 201: {
|
|
60
|
+
* description: 'User created',
|
|
61
|
+
* content: {
|
|
62
|
+
* 'application/json': {
|
|
63
|
+
* schema: userSchema
|
|
64
|
+
* }
|
|
65
|
+
* }
|
|
66
|
+
* },
|
|
67
|
+
* 400: {
|
|
68
|
+
* description: 'Bad request',
|
|
69
|
+
* content: {
|
|
70
|
+
* 'application/json': {
|
|
71
|
+
* schema: errorSchema
|
|
72
|
+
* }
|
|
73
|
+
* }
|
|
74
|
+
* }
|
|
75
|
+
* }
|
|
76
|
+
* });
|
|
77
|
+
*
|
|
78
|
+
* class UserController {
|
|
79
|
+
* @Post('/users')
|
|
80
|
+
* async createUser(@Body() userData: CreateUserDto) {
|
|
81
|
+
* const createdUser = await userService.create(userData);
|
|
82
|
+
* return route.reply(201, createdUser); // Type-safe!
|
|
83
|
+
* }
|
|
84
|
+
* }
|
|
85
|
+
* ```
|
|
86
|
+
*
|
|
87
|
+
* @see ResponsesSpec for response specification format
|
|
88
|
+
* @see defineRoute for creating route definitions
|
|
89
|
+
*/
|
|
2
90
|
export function makeReply(_responses) {
|
|
3
91
|
return {
|
|
4
92
|
/**
|
|
93
|
+
* Creates a typed response with body content.
|
|
94
|
+
*
|
|
5
95
|
* Only allowed for statuses that have a body schema in `responses`.
|
|
6
|
-
* Body is type-checked against that schema.
|
|
96
|
+
* Body is type-checked against that schema for complete type safety.
|
|
97
|
+
*
|
|
98
|
+
* @template S - Status code that must be in responses and allow body
|
|
99
|
+
* @param status - HTTP status code
|
|
100
|
+
* @param body - Response body (type-checked against schema)
|
|
101
|
+
* @param init - Optional initialization options
|
|
102
|
+
* @returns Typed Reply object
|
|
103
|
+
*
|
|
104
|
+
* @example
|
|
105
|
+
* ```typescript
|
|
106
|
+
* // With route definition
|
|
107
|
+
* const reply = makeReply({
|
|
108
|
+
* 200: {
|
|
109
|
+
* content: {
|
|
110
|
+
* 'application/json': {
|
|
111
|
+
* schema: Schema.Object({ name: Schema.String() })
|
|
112
|
+
* }
|
|
113
|
+
* }
|
|
114
|
+
* }
|
|
115
|
+
* });
|
|
116
|
+
*
|
|
117
|
+
* reply.reply(200, { name: 'John' }); // ✅ Valid
|
|
118
|
+
* reply.reply(200, { age: 30 }); // ❌ Type error - missing name, wrong property
|
|
119
|
+
* ```
|
|
7
120
|
*/
|
|
8
121
|
reply(status, body, init) {
|
|
9
122
|
return baseReply(status, body, init);
|
|
10
123
|
},
|
|
11
124
|
/**
|
|
125
|
+
* Creates a typed response without body content.
|
|
126
|
+
*
|
|
12
127
|
* For no-content responses (204 etc) or when you want an empty body.
|
|
128
|
+
* Only allowed for status codes that don't require a body in the responses spec.
|
|
129
|
+
*
|
|
130
|
+
* @template S - Status code that must be in responses and not require body
|
|
131
|
+
* @param status - Optional HTTP status code (uses default from responses if omitted)
|
|
132
|
+
* @param init - Optional initialization options
|
|
133
|
+
* @returns Typed Reply object without body
|
|
134
|
+
*
|
|
135
|
+
* @example
|
|
136
|
+
* ```typescript
|
|
137
|
+
* // With route definition
|
|
138
|
+
* const reply = makeReply({
|
|
139
|
+
* 204: { description: 'No content' },
|
|
140
|
+
* 202: { description: 'Accepted' }
|
|
141
|
+
* });
|
|
142
|
+
*
|
|
143
|
+
* reply.noContent(); // ✅ Uses 204 by default
|
|
144
|
+
* reply.noContent(202); // ✅ Explicit 202 status
|
|
145
|
+
* reply.noContent(200); // ❌ Type error - 200 not in no-content responses
|
|
146
|
+
* ```
|
|
13
147
|
*/
|
|
14
148
|
noContent(status, init) {
|
|
15
|
-
|
|
149
|
+
const replyInit = (init ?? {});
|
|
150
|
+
return baseNoContent(status, replyInit);
|
|
16
151
|
},
|
|
17
152
|
};
|
|
18
153
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typed.js","sourceRoot":"","sources":["../../../src/core/reply/typed.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,SAAS,IAAI,aAAa,EAAE,MAAM,YAAY,CAAC;AAwB5E,MAAM,UAAU,SAAS,CAAgC,UAAa;IACpE,OAAO;QACL
|
|
1
|
+
{"version":3,"file":"typed.js","sourceRoot":"","sources":["../../../src/core/reply/typed.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,SAAS,IAAI,aAAa,EAAE,MAAM,YAAY,CAAC;AAwB5E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuFG;AACH,MAAM,UAAU,SAAS,CAAgC,UAAa;IACpE,OAAO;QACL;;;;;;;;;;;;;;;;;;;;;;;;;;;;WA4BG;QACH,KAAK,CACH,MAAS,EACT,IAAgC,EAChC,IAAoB;YAEpB,OAAO,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QACvC,CAAC;QAED;;;;;;;;;;;;;;;;;;;;;;;WAuBG;QACH,SAAS,CACP,MAAU,EACV,IAAoB;YAEpB,MAAM,SAAS,GAAG,CAAC,IAAI,IAAI,EAAE,CAAc,CAAC;YAC5C,OAAO,aAAa,CAAC,MAAM,EAAE,SAAS,CAAwB,CAAC;QACjE,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Schema } from '../../validation/native/schema.js';
|
|
2
|
-
export declare function header<S extends Schema<
|
|
2
|
+
export declare function header<S extends Schema<unknown>>(schema: S, opts?: {
|
|
3
3
|
required?: boolean;
|
|
4
4
|
description?: string;
|
|
5
5
|
}): {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/core/responses/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mCAAmC,CAAC;AAEhE,wBAAgB,MAAM,CAAC,CAAC,SAAS,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/core/responses/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mCAAmC,CAAC;AAEhE,wBAAgB,MAAM,CAAC,CAAC,SAAS,MAAM,CAAC,OAAO,CAAC,EAC9C,MAAM,EAAE,CAAC,EACT,IAAI,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GAClD;IAAE,MAAM,EAAE,CAAC,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,CAMzD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../../src/core/responses/normalize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../../src/core/responses/normalize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAQhF,wBAAgB,kBAAkB,CAAC,KAAK,CAAC,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CA+BtF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normalize.js","sourceRoot":"","sources":["../../../src/core/responses/normalize.ts"],"names":[],"mappings":"AAGA,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,
|
|
1
|
+
{"version":3,"file":"normalize.js","sourceRoot":"","sources":["../../../src/core/responses/normalize.ts"],"names":[],"mappings":"AAGA,SAAS,QAAQ,CAAC,KAAc;IAC9B,MAAM,SAAS,GAAG,KAAwB,CAAC;IAC3C,OAAO,OAAO,SAAS,EAAE,KAAK,KAAK,UAAU,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,KAAqB;IACtD,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC;IAEtB,MAAM,GAAG,GAAiC,EAAE,CAAC;IAE7C,KAAK,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACnD,IAAI,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACnB,GAAG,CAAC,MAAM,CAAC,GAAG;gBACZ,OAAO,EAAE;oBACP,kBAAkB,EAAE;wBAClB,MAAM,EAAE,IAAI;qBACb;iBACF;aACF,CAAC;YACF,SAAS;QACX,CAAC;QAED,MAAM,UAAU,GAAiB,EAAE,GAAG,IAAI,EAAE,CAAC;QAC7C,IAAI,UAAU,CAAC,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;YAC7C,UAAU,CAAC,OAAO,GAAG;gBACnB,kBAAkB,EAAE;oBAClB,MAAM,EAAE,UAAU,CAAC,MAAM;iBAC1B;aACF,CAAC;YACF,OAAO,UAAU,CAAC,MAAM,CAAC;QAC3B,CAAC;QAED,GAAG,CAAC,MAAM,CAAC,GAAG,UAAU,CAAC;IAC3B,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -6,20 +6,67 @@ import { makeReply } from '../reply/typed.js';
|
|
|
6
6
|
* - path: use in decorator
|
|
7
7
|
* - options: use in decorator
|
|
8
8
|
* - reply: typed reply/noContent bound to responses
|
|
9
|
+
*
|
|
10
|
+
* @template Path - The route path as a string literal
|
|
11
|
+
* @template R - The responses specification for this route
|
|
9
12
|
*/
|
|
10
13
|
export type RouteDef<Path extends string, R extends ResponsesSpec> = {
|
|
14
|
+
/** The route path */
|
|
11
15
|
path: Path;
|
|
16
|
+
/** Route configuration and responses */
|
|
12
17
|
options: RouteOptions<Path> & {
|
|
13
18
|
responses: R;
|
|
14
19
|
};
|
|
20
|
+
/** Typed reply function bound to the route's responses */
|
|
15
21
|
reply: ReturnType<typeof makeReply<R>>;
|
|
16
22
|
};
|
|
23
|
+
/**
|
|
24
|
+
* Creates a route definition with typed responses and reply functions.
|
|
25
|
+
*
|
|
26
|
+
* @template Path - The route path as a string literal
|
|
27
|
+
* @template R - The responses specification for this route
|
|
28
|
+
* @param path - The route path (e.g., '/users', '/users/:id')
|
|
29
|
+
* @param options - Route configuration including responses specification
|
|
30
|
+
* @returns Route definition with typed reply function
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```typescript
|
|
34
|
+
* const userRoute = defineRoute('/users', {
|
|
35
|
+
* responses: {
|
|
36
|
+
* 200: { content: { 'application/json': { schema: userSchema } } },
|
|
37
|
+
* 404: { description: 'User not found' }
|
|
38
|
+
* }
|
|
39
|
+
* });
|
|
40
|
+
*
|
|
41
|
+
* // Use the typed reply function
|
|
42
|
+
* const reply = userRoute.reply(200, userData);
|
|
43
|
+
* ```
|
|
44
|
+
*
|
|
45
|
+
* @see RouteOptions for available configuration options
|
|
46
|
+
* @see ResponsesSpec for response specification format
|
|
47
|
+
*/
|
|
17
48
|
export declare function defineRoute<Path extends string, const R extends ResponsesSpec>(path: Path, options: RouteOptions<Path> & {
|
|
18
49
|
responses: R;
|
|
19
50
|
}): RouteDef<Path, R>;
|
|
20
51
|
/**
|
|
21
|
-
* Nice builder style:
|
|
52
|
+
* Nice builder style for route definitions:
|
|
22
53
|
* const getUser = routeFor('/{id}')({ ... })
|
|
54
|
+
*
|
|
55
|
+
* @template Path - The route path as a string literal
|
|
56
|
+
* @param path - The route path
|
|
57
|
+
* @returns A function that takes route options and returns a RouteDef
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```typescript
|
|
61
|
+
* const getUserRoute = routeFor('/users/:id')({
|
|
62
|
+
* responses: {
|
|
63
|
+
* 200: { content: { 'application/json': { schema: userSchema } } },
|
|
64
|
+
* 404: { description: 'User not found' }
|
|
65
|
+
* }
|
|
66
|
+
* });
|
|
67
|
+
* ```
|
|
68
|
+
*
|
|
69
|
+
* @see defineRoute for the underlying implementation
|
|
23
70
|
*/
|
|
24
71
|
export declare function routeFor<Path extends string>(path: Path): <const R extends ResponsesSpec>(options: RouteOptions<Path> & {
|
|
25
72
|
responses: R;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"defineRoute.d.ts","sourceRoot":"","sources":["../../../src/core/route/defineRoute.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAE9C
|
|
1
|
+
{"version":3,"file":"defineRoute.d.ts","sourceRoot":"","sources":["../../../src/core/route/defineRoute.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAE9C;;;;;;;;GAQG;AACH,MAAM,MAAM,QAAQ,CAAC,IAAI,SAAS,MAAM,EAAE,CAAC,SAAS,aAAa,IAAI;IACnE,qBAAqB;IACrB,IAAI,EAAE,IAAI,CAAC;IACX,wCAAwC;IACxC,OAAO,EAAE,YAAY,CAAC,IAAI,CAAC,GAAG;QAAE,SAAS,EAAE,CAAC,CAAA;KAAE,CAAC;IAC/C,0DAA0D;IAC1D,KAAK,EAAE,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;CACxC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,WAAW,CAAC,IAAI,SAAS,MAAM,EAAE,KAAK,CAAC,CAAC,SAAS,aAAa,EAC5E,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,YAAY,CAAC,IAAI,CAAC,GAAG;IAAE,SAAS,EAAE,CAAC,CAAA;CAAE,GAC7C,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAMnB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,QAAQ,CAAC,IAAI,SAAS,MAAM,EAAE,IAAI,EAAE,IAAI,IACrC,KAAK,CAAC,CAAC,SAAS,aAAa,EAC5C,SAAS,YAAY,CAAC,IAAI,CAAC,GAAG;IAAE,SAAS,EAAE,CAAC,CAAA;CAAE,KAC7C,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAGrB"}
|
|
@@ -1,4 +1,29 @@
|
|
|
1
1
|
import { makeReply } from '../reply/typed.js';
|
|
2
|
+
/**
|
|
3
|
+
* Creates a route definition with typed responses and reply functions.
|
|
4
|
+
*
|
|
5
|
+
* @template Path - The route path as a string literal
|
|
6
|
+
* @template R - The responses specification for this route
|
|
7
|
+
* @param path - The route path (e.g., '/users', '/users/:id')
|
|
8
|
+
* @param options - Route configuration including responses specification
|
|
9
|
+
* @returns Route definition with typed reply function
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* const userRoute = defineRoute('/users', {
|
|
14
|
+
* responses: {
|
|
15
|
+
* 200: { content: { 'application/json': { schema: userSchema } } },
|
|
16
|
+
* 404: { description: 'User not found' }
|
|
17
|
+
* }
|
|
18
|
+
* });
|
|
19
|
+
*
|
|
20
|
+
* // Use the typed reply function
|
|
21
|
+
* const reply = userRoute.reply(200, userData);
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* @see RouteOptions for available configuration options
|
|
25
|
+
* @see ResponsesSpec for response specification format
|
|
26
|
+
*/
|
|
2
27
|
export function defineRoute(path, options) {
|
|
3
28
|
return {
|
|
4
29
|
path,
|
|
@@ -7,8 +32,24 @@ export function defineRoute(path, options) {
|
|
|
7
32
|
};
|
|
8
33
|
}
|
|
9
34
|
/**
|
|
10
|
-
* Nice builder style:
|
|
35
|
+
* Nice builder style for route definitions:
|
|
11
36
|
* const getUser = routeFor('/{id}')({ ... })
|
|
37
|
+
*
|
|
38
|
+
* @template Path - The route path as a string literal
|
|
39
|
+
* @param path - The route path
|
|
40
|
+
* @returns A function that takes route options and returns a RouteDef
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```typescript
|
|
44
|
+
* const getUserRoute = routeFor('/users/:id')({
|
|
45
|
+
* responses: {
|
|
46
|
+
* 200: { content: { 'application/json': { schema: userSchema } } },
|
|
47
|
+
* 404: { description: 'User not found' }
|
|
48
|
+
* }
|
|
49
|
+
* });
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
52
|
+
* @see defineRoute for the underlying implementation
|
|
12
53
|
*/
|
|
13
54
|
export function routeFor(path) {
|
|
14
55
|
return function (options) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"defineRoute.js","sourceRoot":"","sources":["../../../src/core/route/defineRoute.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"defineRoute.js","sourceRoot":"","sources":["../../../src/core/route/defineRoute.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAoB9C;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,WAAW,CACzB,IAAU,EACV,OAA8C;IAE9C,OAAO;QACL,IAAI;QACJ,OAAO;QACP,KAAK,EAAE,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC;KACpC,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,QAAQ,CAAsB,IAAU;IACtD,OAAO,UACL,OAA8C;QAE9C,OAAO,WAAW,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACpC,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -5,5 +5,5 @@ export type BindingsOptions = {
|
|
|
5
5
|
*/
|
|
6
6
|
path?: Record<string, 'string' | 'int' | 'number' | 'boolean' | 'uuid'>;
|
|
7
7
|
};
|
|
8
|
-
export declare function Bindings(opts: BindingsOptions): (_value:
|
|
8
|
+
export declare function Bindings(opts: BindingsOptions): (_value: unknown, context: ClassMethodDecoratorContext) => void;
|
|
9
9
|
//# sourceMappingURL=binding.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"binding.d.ts","sourceRoot":"","sources":["../../src/decorators/binding.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,eAAe,GAAG;IAC5B;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,GAAG,KAAK,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC,CAAC;CACzE,CAAC;AAEF,wBAAgB,QAAQ,CAAC,IAAI,EAAE,eAAe,IAC3B,QAAQ,
|
|
1
|
+
{"version":3,"file":"binding.d.ts","sourceRoot":"","sources":["../../src/decorators/binding.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,eAAe,GAAG;IAC5B;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,GAAG,KAAK,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC,CAAC;CACzE,CAAC;AAEF,wBAAgB,QAAQ,CAAC,IAAI,EAAE,eAAe,IAC3B,QAAQ,OAAO,EAAE,SAAS,2BAA2B,UAevE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"binding.js","sourceRoot":"","sources":["../../src/decorators/binding.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAqB,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAUrE,MAAM,UAAU,QAAQ,CAAC,IAAqB;IAC5C,OAAO,UAAU,
|
|
1
|
+
{"version":3,"file":"binding.js","sourceRoot":"","sources":["../../src/decorators/binding.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAqB,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAUrE,MAAM,UAAU,QAAQ,CAAC,IAAqB;IAC5C,OAAO,UAAU,MAAe,EAAE,OAAoC;QACpE,MAAM,GAAG,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;QACpC,MAAM,IAAI,GAAG,eAAe,CAAe,GAAG,EAAE,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAE3E,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,CAAC,QAAQ,KAAK,EAAE,CAAC;QACrB,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAE7B,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,GAAG;gBAC3B,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;gBACrC,GAAG,IAAI,CAAC,IAAI;aACb,CAAC;QACJ,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
* Stage-3 class decorator.
|
|
3
3
|
* Usage: @Controller('/users')
|
|
4
4
|
*/
|
|
5
|
-
export declare function Controller(basePath: string): (_value:
|
|
5
|
+
export declare function Controller(basePath: string): (_value: unknown, context: ClassDecoratorContext) => void;
|
|
6
6
|
//# sourceMappingURL=controller.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../src/decorators/controller.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,IACxB,QAAQ,
|
|
1
|
+
{"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../src/decorators/controller.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,IACxB,QAAQ,OAAO,EAAE,SAAS,qBAAqB,UASjE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"controller.js","sourceRoot":"","sources":["../../src/decorators/controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAuB,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5D;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,QAAgB;IACzC,OAAO,UAAU,
|
|
1
|
+
{"version":3,"file":"controller.js","sourceRoot":"","sources":["../../src/decorators/controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAuB,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5D;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,QAAgB;IACzC,OAAO,UAAU,MAAe,EAAE,OAA8B;QAC9D,MAAM,GAAG,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;QAEpC,MAAM,IAAI,GAAmB;YAC3B,QAAQ,EAAE,iBAAiB,CAAC,QAAQ,CAAC;SACtC,CAAC;QAEF,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;IACrC,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,iBAAiB,CAAC,CAAS;IAClC,IAAI,CAAC,CAAC;QAAE,OAAO,EAAE,CAAC;IAClB,IAAI,GAAG,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IACnB,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,GAAG,GAAG,IAAI,GAAG,EAAE,CAAC;IAC1C,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC7D,OAAO,GAAG,CAAC;AACb,CAAC"}
|