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.
Files changed (139) hide show
  1. package/README.md +4 -1
  2. package/dist/adapters/express/createApp.d.ts +149 -11
  3. package/dist/adapters/express/createApp.d.ts.map +1 -1
  4. package/dist/adapters/express/createApp.js +112 -6
  5. package/dist/adapters/express/createApp.js.map +1 -1
  6. package/dist/adapters/express/middleware/errorHandler.d.ts +193 -2
  7. package/dist/adapters/express/middleware/errorHandler.d.ts.map +1 -1
  8. package/dist/adapters/express/middleware/errorHandler.js +164 -3
  9. package/dist/adapters/express/middleware/errorHandler.js.map +1 -1
  10. package/dist/adapters/express/router.d.ts +1 -1
  11. package/dist/adapters/express/router.d.ts.map +1 -1
  12. package/dist/adapters/express/router.js +6 -4
  13. package/dist/adapters/express/router.js.map +1 -1
  14. package/dist/adapters/express/transport/request.js.map +1 -1
  15. package/dist/adapters/express/transport/response.d.ts +1 -1
  16. package/dist/adapters/express/transport/response.d.ts.map +1 -1
  17. package/dist/adapters/express/transport/response.js.map +1 -1
  18. package/dist/contracts/openapi-v3.d.ts +461 -0
  19. package/dist/contracts/openapi-v3.d.ts.map +1 -1
  20. package/dist/contracts/reply.d.ts +109 -1
  21. package/dist/contracts/reply.d.ts.map +1 -1
  22. package/dist/contracts/reply.js +40 -1
  23. package/dist/contracts/reply.js.map +1 -1
  24. package/dist/contracts/response-types.d.ts +5 -5
  25. package/dist/contracts/response-types.d.ts.map +1 -1
  26. package/dist/contracts/responses.d.ts +84 -4
  27. package/dist/contracts/responses.d.ts.map +1 -1
  28. package/dist/contracts/route-options.d.ts +134 -3
  29. package/dist/contracts/route-options.d.ts.map +1 -1
  30. package/dist/contracts/validator.d.ts +121 -0
  31. package/dist/contracts/validator.d.ts.map +1 -1
  32. package/dist/core/binding/binder.d.ts +56 -1
  33. package/dist/core/binding/binder.d.ts.map +1 -1
  34. package/dist/core/binding/binder.js +33 -0
  35. package/dist/core/binding/binder.js.map +1 -1
  36. package/dist/core/binding/coerce/primitives.d.ts +68 -1
  37. package/dist/core/binding/coerce/primitives.d.ts.map +1 -1
  38. package/dist/core/binding/coerce/primitives.js +82 -12
  39. package/dist/core/binding/coerce/primitives.js.map +1 -1
  40. package/dist/core/errors/http-error.d.ts +54 -0
  41. package/dist/core/errors/http-error.d.ts.map +1 -1
  42. package/dist/core/errors/http-error.js +54 -0
  43. package/dist/core/errors/http-error.js.map +1 -1
  44. package/dist/core/errors/validation-error.d.ts +65 -0
  45. package/dist/core/errors/validation-error.d.ts.map +1 -1
  46. package/dist/core/errors/validation-error.js +65 -0
  47. package/dist/core/errors/validation-error.js.map +1 -1
  48. package/dist/core/openapi/buildOpenApi.d.ts +65 -0
  49. package/dist/core/openapi/buildOpenApi.d.ts.map +1 -1
  50. package/dist/core/openapi/buildOpenApi.js +66 -4
  51. package/dist/core/openapi/buildOpenApi.js.map +1 -1
  52. package/dist/core/openapi/schema/registry.d.ts +1 -1
  53. package/dist/core/openapi/schema/registry.d.ts.map +1 -1
  54. package/dist/core/openapi/schema/registry.js.map +1 -1
  55. package/dist/core/registry/buildRegistry.d.ts.map +1 -1
  56. package/dist/core/registry/buildRegistry.js +49 -5
  57. package/dist/core/registry/buildRegistry.js.map +1 -1
  58. package/dist/core/registry/types.d.ts +194 -1
  59. package/dist/core/registry/types.d.ts.map +1 -1
  60. package/dist/core/reply/reply.d.ts +94 -0
  61. package/dist/core/reply/reply.d.ts.map +1 -1
  62. package/dist/core/reply/reply.js +87 -0
  63. package/dist/core/reply/reply.js.map +1 -1
  64. package/dist/core/reply/typed.d.ts +137 -3
  65. package/dist/core/reply/typed.d.ts.map +1 -1
  66. package/dist/core/reply/typed.js +137 -2
  67. package/dist/core/reply/typed.js.map +1 -1
  68. package/dist/core/responses/helpers.d.ts +1 -1
  69. package/dist/core/responses/helpers.d.ts.map +1 -1
  70. package/dist/core/responses/normalize.d.ts.map +1 -1
  71. package/dist/core/responses/normalize.js +2 -1
  72. package/dist/core/responses/normalize.js.map +1 -1
  73. package/dist/core/route/defineRoute.d.ts +48 -1
  74. package/dist/core/route/defineRoute.d.ts.map +1 -1
  75. package/dist/core/route/defineRoute.js +42 -1
  76. package/dist/core/route/defineRoute.js.map +1 -1
  77. package/dist/decorators/binding.d.ts +1 -1
  78. package/dist/decorators/binding.d.ts.map +1 -1
  79. package/dist/decorators/binding.js.map +1 -1
  80. package/dist/decorators/controller.d.ts +1 -1
  81. package/dist/decorators/controller.d.ts.map +1 -1
  82. package/dist/decorators/controller.js.map +1 -1
  83. package/dist/decorators/docs.d.ts +6 -0
  84. package/dist/decorators/docs.d.ts.map +1 -1
  85. package/dist/decorators/docs.js +45 -2
  86. package/dist/decorators/docs.js.map +1 -1
  87. package/dist/decorators/index.d.ts +3 -0
  88. package/dist/decorators/index.d.ts.map +1 -1
  89. package/dist/decorators/index.js +3 -0
  90. package/dist/decorators/index.js.map +1 -1
  91. package/dist/decorators/methods.d.ts +128 -6
  92. package/dist/decorators/methods.d.ts.map +1 -1
  93. package/dist/decorators/methods.js +124 -0
  94. package/dist/decorators/methods.js.map +1 -1
  95. package/dist/decorators/responses.d.ts +5 -0
  96. package/dist/decorators/responses.d.ts.map +1 -1
  97. package/dist/decorators/responses.js +43 -2
  98. package/dist/decorators/responses.js.map +1 -1
  99. package/dist/decorators/security.d.ts +6 -0
  100. package/dist/decorators/security.d.ts.map +1 -1
  101. package/dist/decorators/security.js +38 -2
  102. package/dist/decorators/security.js.map +1 -1
  103. package/dist/index.d.ts +1 -0
  104. package/dist/index.d.ts.map +1 -1
  105. package/dist/index.js +1 -0
  106. package/dist/index.js.map +1 -1
  107. package/dist/integrations/metal-orm/schema/column-map.d.ts +91 -0
  108. package/dist/integrations/metal-orm/schema/column-map.d.ts.map +1 -1
  109. package/dist/integrations/metal-orm/schema/column-map.js +129 -2
  110. package/dist/integrations/metal-orm/schema/column-map.js.map +1 -1
  111. package/dist/integrations/metal-orm/schema/dto.d.ts +2 -2
  112. package/dist/integrations/metal-orm/schema/dto.d.ts.map +1 -1
  113. package/dist/integrations/metal-orm/schema/dto.js.map +1 -1
  114. package/dist/integrations/metal-orm/schema/entity.d.ts +90 -8
  115. package/dist/integrations/metal-orm/schema/entity.d.ts.map +1 -1
  116. package/dist/integrations/metal-orm/schema/entity.js +78 -6
  117. package/dist/integrations/metal-orm/schema/entity.js.map +1 -1
  118. package/dist/integrations/metal-orm/schema/filters.d.ts +1 -1
  119. package/dist/integrations/metal-orm/schema/filters.d.ts.map +1 -1
  120. package/dist/integrations/metal-orm/schema/filters.js +2 -1
  121. package/dist/integrations/metal-orm/schema/filters.js.map +1 -1
  122. package/dist/integrations/metal-orm/schema/tabledef.d.ts +1 -1
  123. package/dist/integrations/metal-orm/schema/tabledef.d.ts.map +1 -1
  124. package/dist/metadata/bag.d.ts +2 -1
  125. package/dist/metadata/bag.d.ts.map +1 -1
  126. package/dist/metadata/bag.js +2 -1
  127. package/dist/metadata/bag.js.map +1 -1
  128. package/dist/metadata/keys.d.ts +203 -1
  129. package/dist/metadata/keys.d.ts.map +1 -1
  130. package/dist/metadata/keys.js +3 -9
  131. package/dist/metadata/keys.js.map +1 -1
  132. package/dist/metadata/merge.d.ts.map +1 -1
  133. package/dist/metadata/merge.js +4 -1
  134. package/dist/metadata/merge.js.map +1 -1
  135. package/dist/validation/native/schema.d.ts +2 -2
  136. package/dist/validation/native/schema.d.ts.map +1 -1
  137. package/dist/validation/native/validator.d.ts +1 -1
  138. package/dist/validation/native/validator.d.ts.map +1 -1
  139. package/package.json +6 -2
@@ -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":"AAOA,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,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"}
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<any>;
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, any> ? string extends keyof H ? Record<string, HeaderValueFromSpec<H[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,GAAG,CAAC,CAAA;CAAE,GAC7C,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,GAAG,CAAC,GACzB,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,wBAAgB,SAAS,CAAC,KAAK,CAAC,CAAC,SAAS,aAAa,EAAE,UAAU,EAAE,CAAC;IAElE;;;OAGG;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;;OAEG;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;EAIzB"}
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"}
@@ -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
- return baseNoContent(status, init);
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;;;WAGG;QACH,KAAK,CACH,MAAS,EACT,IAAgC,EAChC,IAAoB;YAEpB,OAAO,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QACvC,CAAC;QAED;;WAEG;QACH,SAAS,CACP,MAAU,EACV,IAAoB;YAEpB,OAAO,aAAa,CAAC,MAAa,EAAE,IAAW,CAAQ,CAAC;QAC1D,CAAC;KACF,CAAC;AACJ,CAAC"}
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<any>>(schema: S, opts?: {
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,GAAG,CAAC,EAC1C,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
+ {"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;AAOhF,wBAAgB,kBAAkB,CAAC,KAAK,CAAC,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CA+BtF"}
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,5 +1,6 @@
1
1
  function isSchema(value) {
2
- return typeof value?.parse === 'function';
2
+ const candidate = value;
3
+ return typeof candidate?.parse === 'function';
3
4
  }
4
5
  export function normalizeResponses(input) {
5
6
  if (!input)
@@ -1 +1 @@
1
- {"version":3,"file":"normalize.js","sourceRoot":"","sources":["../../../src/core/responses/normalize.ts"],"names":[],"mappings":"AAGA,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAQ,KAAqB,EAAE,KAAK,KAAK,UAAU,CAAC;AAC7D,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"}
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;;;;;GAKG;AACH,MAAM,MAAM,QAAQ,CAAC,IAAI,SAAS,MAAM,EAAE,CAAC,SAAS,aAAa,IAAI;IACnE,IAAI,EAAE,IAAI,CAAC;IACX,OAAO,EAAE,YAAY,CAAC,IAAI,CAAC,GAAG;QAAE,SAAS,EAAE,CAAC,CAAA;KAAE,CAAC;IAC/C,KAAK,EAAE,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;CACxC,CAAC;AAEF,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;;;GAGG;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
+ {"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;AAc9C,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;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAsB,IAAU;IACtD,OAAO,UACL,OAA8C;QAE9C,OAAO,WAAW,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACpC,CAAC,CAAC;AACJ,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: Function, context: ClassMethodDecoratorContext) => void;
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,QAAQ,EAAE,SAAS,2BAA2B,UAexE"}
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,MAAgB,EAAE,OAAoC;QACrE,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"}
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: Function, context: ClassDecoratorContext) => void;
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,QAAQ,EAAE,SAAS,qBAAqB,UASlE"}
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,MAAgB,EAAE,OAA8B;QAC/D,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"}
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"}