@nestia/core 14.0.0 → 14.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 (192) hide show
  1. package/MIGRATION.md +20 -0
  2. package/README.md +1 -1
  3. package/lib/adaptors/McpAdaptor.d.ts +29 -3
  4. package/lib/adaptors/McpAdaptor.js +150 -24
  5. package/lib/adaptors/McpAdaptor.js.map +1 -1
  6. package/lib/adaptors/WebSocketAdaptor.d.ts +37 -0
  7. package/lib/adaptors/WebSocketAdaptor.js +184 -48
  8. package/lib/adaptors/WebSocketAdaptor.js.map +1 -1
  9. package/lib/adaptors/internal/RoutePathMatcher.d.ts +1 -0
  10. package/lib/adaptors/internal/RoutePathMatcher.js +88 -0
  11. package/lib/adaptors/internal/RoutePathMatcher.js.map +1 -0
  12. package/lib/adaptors/internal/external_context.d.ts +1 -0
  13. package/lib/adaptors/internal/external_context.js +56 -0
  14. package/lib/adaptors/internal/external_context.js.map +1 -0
  15. package/lib/decorators/DynamicModule.d.ts +12 -0
  16. package/lib/decorators/DynamicModule.js +12 -0
  17. package/lib/decorators/DynamicModule.js.map +1 -1
  18. package/lib/decorators/EncryptedBody.d.ts +14 -6
  19. package/lib/decorators/EncryptedBody.js +39 -16
  20. package/lib/decorators/EncryptedBody.js.map +1 -1
  21. package/lib/decorators/EncryptedController.d.ts +6 -1
  22. package/lib/decorators/EncryptedController.js +7 -2
  23. package/lib/decorators/EncryptedController.js.map +1 -1
  24. package/lib/decorators/EncryptedModule.d.ts +25 -6
  25. package/lib/decorators/EncryptedModule.js +87 -18
  26. package/lib/decorators/EncryptedModule.js.map +1 -1
  27. package/lib/decorators/EncryptedRoute.d.ts +20 -11
  28. package/lib/decorators/EncryptedRoute.js +27 -13
  29. package/lib/decorators/EncryptedRoute.js.map +1 -1
  30. package/lib/decorators/HumanRoute.d.ts +5 -0
  31. package/lib/decorators/HumanRoute.js +5 -0
  32. package/lib/decorators/HumanRoute.js.map +1 -1
  33. package/lib/decorators/McpRoute.d.ts +31 -19
  34. package/lib/decorators/McpRoute.js +12 -1
  35. package/lib/decorators/McpRoute.js.map +1 -1
  36. package/lib/decorators/PlainBody.d.ts +7 -1
  37. package/lib/decorators/PlainBody.js +16 -8
  38. package/lib/decorators/PlainBody.js.map +1 -1
  39. package/lib/decorators/SwaggerCustomizer.d.ts +15 -0
  40. package/lib/decorators/SwaggerCustomizer.js +5 -0
  41. package/lib/decorators/SwaggerCustomizer.js.map +1 -1
  42. package/lib/decorators/SwaggerExample.d.ts +51 -22
  43. package/lib/decorators/SwaggerExample.js +35 -22
  44. package/lib/decorators/SwaggerExample.js.map +1 -1
  45. package/lib/decorators/TypedBody.d.ts +10 -3
  46. package/lib/decorators/TypedBody.js +20 -10
  47. package/lib/decorators/TypedBody.js.map +1 -1
  48. package/lib/decorators/TypedException.d.ts +10 -0
  49. package/lib/decorators/TypedFormData.d.ts +81 -9
  50. package/lib/decorators/TypedFormData.js +121 -31
  51. package/lib/decorators/TypedFormData.js.map +1 -1
  52. package/lib/decorators/TypedHeaders.d.ts +5 -0
  53. package/lib/decorators/TypedHeaders.js +5 -0
  54. package/lib/decorators/TypedHeaders.js.map +1 -1
  55. package/lib/decorators/TypedParam.d.ts +12 -3
  56. package/lib/decorators/TypedParam.js +12 -3
  57. package/lib/decorators/TypedParam.js.map +1 -1
  58. package/lib/decorators/TypedQuery.d.ts +17 -1
  59. package/lib/decorators/TypedQuery.js +25 -4
  60. package/lib/decorators/TypedQuery.js.map +1 -1
  61. package/lib/decorators/TypedRoute.d.ts +25 -10
  62. package/lib/decorators/TypedRoute.js +19 -10
  63. package/lib/decorators/TypedRoute.js.map +1 -1
  64. package/lib/decorators/WebSocketRoute.d.ts +18 -1
  65. package/lib/decorators/WebSocketRoute.js +18 -1
  66. package/lib/decorators/WebSocketRoute.js.map +1 -1
  67. package/lib/decorators/doNotThrowTransformError.d.ts +14 -0
  68. package/lib/decorators/doNotThrowTransformError.js +14 -0
  69. package/lib/decorators/doNotThrowTransformError.js.map +1 -1
  70. package/lib/decorators/internal/EncryptedConstant.js +13 -2
  71. package/lib/decorators/internal/EncryptedConstant.js.map +1 -1
  72. package/lib/decorators/internal/IRequestBodyValidation.d.ts +66 -0
  73. package/lib/decorators/internal/IRequestBodyValidation.js +3 -0
  74. package/lib/decorators/internal/IRequestBodyValidation.js.map +1 -0
  75. package/lib/decorators/internal/IWebSocketRouteReflect.d.ts +93 -1
  76. package/lib/decorators/internal/get_encryption_password.d.ts +1 -0
  77. package/lib/decorators/internal/get_encryption_password.js +14 -0
  78. package/lib/decorators/internal/get_encryption_password.js.map +1 -0
  79. package/lib/decorators/internal/get_path_and_querify.js +23 -9
  80. package/lib/decorators/internal/get_path_and_querify.js.map +1 -1
  81. package/lib/decorators/internal/get_path_and_stringify.js +3 -7
  82. package/lib/decorators/internal/get_path_and_stringify.js.map +1 -1
  83. package/lib/decorators/internal/get_text_body.js +9 -3
  84. package/lib/decorators/internal/get_text_body.js.map +1 -1
  85. package/lib/decorators/internal/group_entries.d.ts +1 -0
  86. package/lib/decorators/internal/group_entries.js +19 -0
  87. package/lib/decorators/internal/group_entries.js.map +1 -0
  88. package/lib/decorators/internal/load_controller.d.ts +14 -0
  89. package/lib/decorators/internal/load_controller.js +14 -0
  90. package/lib/decorators/internal/load_controller.js.map +1 -1
  91. package/lib/decorators/internal/split_route_arguments.d.ts +1 -0
  92. package/lib/decorators/internal/split_route_arguments.js +22 -0
  93. package/lib/decorators/internal/split_route_arguments.js.map +1 -0
  94. package/lib/decorators/internal/validate_request_body.js +68 -25
  95. package/lib/decorators/internal/validate_request_body.js.map +1 -1
  96. package/lib/decorators/internal/validate_request_form_data.js +3 -1
  97. package/lib/decorators/internal/validate_request_form_data.js.map +1 -1
  98. package/lib/decorators/internal/validate_request_headers.js +2 -1
  99. package/lib/decorators/internal/validate_request_headers.js.map +1 -1
  100. package/lib/decorators/internal/validate_request_query.js +3 -1
  101. package/lib/decorators/internal/validate_request_query.js.map +1 -1
  102. package/lib/options/IRequestBodyValidator.d.ts +71 -0
  103. package/lib/options/IRequestFormDataProps.d.ts +80 -0
  104. package/lib/options/IRequestHeadersValidator.d.ts +67 -0
  105. package/lib/options/IRequestQueryValidator.d.ts +68 -0
  106. package/lib/options/IResponseBodyQuerifier.d.ts +125 -1
  107. package/lib/options/IResponseBodyStringifier.d.ts +107 -0
  108. package/lib/typings/Creator.d.ts +10 -0
  109. package/lib/utils/ArrayUtil.d.ts +21 -0
  110. package/lib/utils/ArrayUtil.js +22 -1
  111. package/lib/utils/ArrayUtil.js.map +1 -1
  112. package/lib/utils/ExceptionManager.d.ts +43 -4
  113. package/lib/utils/ExceptionManager.js +44 -6
  114. package/lib/utils/ExceptionManager.js.map +1 -1
  115. package/lib/utils/SourceFinder.d.ts +22 -0
  116. package/lib/utils/SourceFinder.js +60 -10
  117. package/lib/utils/SourceFinder.js.map +1 -1
  118. package/lib/utils/VersioningStrategy.d.ts +45 -2
  119. package/lib/utils/VersioningStrategy.js +40 -7
  120. package/lib/utils/VersioningStrategy.js.map +1 -1
  121. package/native/go.mod +1 -1
  122. package/native/go.sum +2 -2
  123. package/native/plugin/plan.go +68 -2
  124. package/native/transform/ast.go +23 -3
  125. package/native/transform/build.go +51 -57
  126. package/native/transform/buildoutput/output.go +147 -0
  127. package/native/transform/contributor.go +9 -0
  128. package/native/transform/core_querify.go +63 -9
  129. package/native/transform/core_transform.go +180 -98
  130. package/native/transform/core_websocket.go +111 -14
  131. package/native/transform/node_transform.go +17 -8
  132. package/native/transform/package.go +55 -0
  133. package/native/transform/printer.go +1 -3
  134. package/native/transform/run.go +18 -0
  135. package/native/transform/schemaprojection/project.go +213 -0
  136. package/native/transform/transform.go +29 -18
  137. package/native/transform/typia_fast.go +6 -0
  138. package/native/transform.cjs +49 -0
  139. package/package.json +13 -15
  140. package/src/adaptors/McpAdaptor.ts +215 -33
  141. package/src/adaptors/WebSocketAdaptor.ts +202 -52
  142. package/src/adaptors/internal/RoutePathMatcher.ts +91 -0
  143. package/src/adaptors/internal/external_context.ts +81 -0
  144. package/src/decorators/DynamicModule.ts +12 -0
  145. package/src/decorators/EncryptedBody.ts +39 -15
  146. package/src/decorators/EncryptedController.ts +12 -3
  147. package/src/decorators/EncryptedModule.ts +89 -18
  148. package/src/decorators/EncryptedRoute.ts +27 -16
  149. package/src/decorators/HumanRoute.ts +5 -0
  150. package/src/decorators/McpRoute.ts +31 -19
  151. package/src/decorators/PlainBody.ts +20 -10
  152. package/src/decorators/SwaggerCustomizer.ts +15 -0
  153. package/src/decorators/SwaggerExample.ts +51 -22
  154. package/src/decorators/TypedBody.ts +18 -9
  155. package/src/decorators/TypedException.ts +10 -0
  156. package/src/decorators/TypedFormData.ts +207 -45
  157. package/src/decorators/TypedHeaders.ts +5 -0
  158. package/src/decorators/TypedParam.ts +12 -3
  159. package/src/decorators/TypedQuery.ts +35 -7
  160. package/src/decorators/TypedRoute.ts +25 -10
  161. package/src/decorators/WebSocketRoute.ts +18 -1
  162. package/src/decorators/doNotThrowTransformError.ts +14 -0
  163. package/src/decorators/internal/EncryptedConstant.ts +14 -1
  164. package/src/decorators/internal/IMcpRouteReflect.ts +7 -1
  165. package/src/decorators/internal/IRequestBodyValidation.ts +65 -0
  166. package/src/decorators/internal/IWebSocketRouteReflect.ts +95 -1
  167. package/src/decorators/internal/get_encryption_password.ts +19 -0
  168. package/src/decorators/internal/get_path_and_querify.ts +31 -10
  169. package/src/decorators/internal/get_path_and_stringify.ts +3 -9
  170. package/src/decorators/internal/get_text_body.ts +8 -4
  171. package/src/decorators/internal/group_entries.ts +17 -0
  172. package/src/decorators/internal/load_controller.ts +14 -0
  173. package/src/decorators/internal/split_route_arguments.ts +20 -0
  174. package/src/decorators/internal/validate_request_body.ts +87 -34
  175. package/src/decorators/internal/validate_request_form_data.ts +3 -1
  176. package/src/decorators/internal/validate_request_headers.ts +2 -2
  177. package/src/decorators/internal/validate_request_query.ts +3 -2
  178. package/src/options/IRequestBodyValidator.ts +71 -0
  179. package/src/options/IRequestFormDataProps.ts +80 -0
  180. package/src/options/IRequestHeadersValidator.ts +67 -0
  181. package/src/options/IRequestQueryValidator.ts +68 -0
  182. package/src/options/IResponseBodyQuerifier.ts +126 -1
  183. package/src/options/IResponseBodyStringifier.ts +107 -0
  184. package/src/typings/Creator.ts +10 -0
  185. package/src/utils/ArrayUtil.ts +22 -3
  186. package/src/utils/ExceptionManager.ts +50 -6
  187. package/src/utils/SourceFinder.ts +62 -10
  188. package/src/utils/VersioningStrategy.ts +55 -11
  189. package/lib/transform.d.ts +0 -10
  190. package/lib/transform.js +0 -25
  191. package/lib/transform.js.map +0 -1
  192. package/src/transform.ts +0 -26
@@ -11,21 +11,25 @@ import { Creator } from "../typings/Creator";
11
11
  * {@link EncryptedRoute} instead of the basic router decorator functions like
12
12
  * {@link nest.Get} or {@link nest.Post} and the API function throws a custom
13
13
  * error whose class has been {@link ExceptionManager.insert inserted} in this
14
- * `EntityManager`, the error would be automatically converted to the regular
14
+ * `ExceptionManager`, the error would be automatically converted to the regular
15
15
  * {@link nest.HttpException} instance by the {@link ExceptionManager.Closure}
16
16
  * function.
17
17
  *
18
18
  * Therefore, with this `ExceptionManager` and {@link TypedRoute} or
19
19
  * {@link EncryptedRoute}, you can manage your custom error classes much
20
- * systemtically. You can avoid 500 internal server error or hard coding
20
+ * systematically. You can avoid 500 internal server error or hard coding
21
21
  * implementation about the custom error classes.
22
22
  *
23
- * Below error classes are defaultly configured in this `ExceptionManager`
23
+ * Below error class is configured in this `ExceptionManager` by default.
24
24
  *
25
- * - `typia.TypeGuardError`
26
25
  * - `@nestia/fetcher.HttpError`
27
26
  *
28
27
  * @author Jeongho Nam - https://github.com/samchon
28
+ * @evidence contracts/common.md#principled-implementation Converters are kept as an ordered list of class and closure, and an error is converted by the first class it is an instance of; the insertion keeps every subclass before its superclasses so the most specific converter wins, and `HttpError` from the fetcher is registered by default.
29
+ * @evidence contracts/common.md#clear-and-simple-design One namespace with the two collections and four operations; the listener set and the tuple list are the only state.
30
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts The registration is public and explicit; no error class is special-cased except the default `HttpError` conversion.
31
+ * @evidence contracts/common.md#meaningful-documentation The comment documents the converter and listener concepts with an example.
32
+ * @evidenceExclude contracts/portability.md#os-neutral-implementation Converter ordering and listener registration operate on JavaScript class and function identity, not native path or process identity.
29
33
  */
30
34
  export declare namespace ExceptionManager {
31
35
  /**
@@ -36,6 +40,11 @@ export declare namespace ExceptionManager {
36
40
  *
37
41
  * @param creator Target error class
38
42
  * @param closure A closure function converting to the `HttpException` class
43
+ * @evidence contracts/common.md#principled-implementation An existing entry for the same class is removed first, then the new entry is placed before the first registered class that it extends, so specificity order holds however the calls are ordered.
44
+ * @evidence contracts/common.md#clear-and-simple-design One function over one list.
45
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts The order rule is derived from the prototype chain, not from a list of known classes.
46
+ * @evidence contracts/common.md#meaningful-documentation The comment states the replacement and ordering rules.
47
+ * @evidenceExclude contracts/portability.md#os-neutral-implementation Converter ordering and listener registration operate on JavaScript class and function identity, not native path or process identity.
39
48
  */
40
49
  function insert<T extends Error>(creator: Creator<T>, closure: Closure<T>): void;
41
50
  /**
@@ -43,9 +52,33 @@ export declare namespace ExceptionManager {
43
52
  *
44
53
  * @param creator Target error class
45
54
  * @returns Whether be erased or not
55
+ * @evidence contracts/common.md#principled-implementation The entry for the class is found by identity and removed, and the result says whether anything was removed.
56
+ * @evidence contracts/common.md#clear-and-simple-design One search and one removal.
57
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts It removes only the named class's entry.
58
+ * @evidence contracts/common.md#meaningful-documentation The comment states the parameter and the boolean result.
59
+ * @evidenceExclude contracts/portability.md#os-neutral-implementation Converter ordering and listener registration operate on JavaScript class and function identity, not native path or process identity.
46
60
  */
47
61
  function erase<T extends Error>(creator: Creator<T>): boolean;
62
+ /**
63
+ * Registers a listener called with every error thrown by a typed route, after
64
+ * the response conversion.
65
+ *
66
+ * @evidence contracts/common.md#principled-implementation The listener is added to a set, so the same function registered twice is called once.
67
+ * @evidence contracts/common.md#clear-and-simple-design One set insertion.
68
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts The listener only observes; the route notifies it after the current turn and ignores its errors.
69
+ * @evidence contracts/common.md#meaningful-documentation The comment states when listeners are called.
70
+ * @evidenceExclude contracts/portability.md#os-neutral-implementation Converter ordering and listener registration operate on JavaScript class and function identity, not native path or process identity.
71
+ */
48
72
  function on(closure: (error: any) => any): void;
73
+ /**
74
+ * Unregisters a listener added with {@link on}.
75
+ *
76
+ * @evidence contracts/common.md#principled-implementation The listener is removed from the set by identity.
77
+ * @evidence contracts/common.md#clear-and-simple-design One set deletion.
78
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts It removes only the named listener.
79
+ * @evidence contracts/common.md#meaningful-documentation The comment names the counterpart operation.
80
+ * @evidenceExclude contracts/portability.md#os-neutral-implementation Converter ordering and listener registration operate on JavaScript class and function identity, not native path or process identity.
81
+ */
49
82
  function off(closure: (error: any) => any): void;
50
83
  /**
51
84
  * Type of a closure function converting to the regular
@@ -55,6 +88,12 @@ export declare namespace ExceptionManager {
55
88
  * from custom error to the regular {@link nest.HttpException} instance. It
56
89
  * would be used in the {@link ExceptionManager} with {@link TypedRoute} or
57
90
  * {@link EncryptedRoute}.
91
+ *
92
+ * @evidence contracts/common.md#principled-implementation A converter is a function from the caught error to an `HttpException`, whose status and body become the response.
93
+ * @evidence contracts/common.md#clear-and-simple-design One call signature.
94
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts It is a type and adds no runtime behavior.
95
+ * @evidence contracts/common.md#meaningful-documentation The comment documents the parameter and the return value.
96
+ * @evidenceExclude contracts/portability.md#os-neutral-implementation Converter ordering and listener registration operate on JavaScript class and function identity, not native path or process identity.
58
97
  */
59
98
  interface Closure<T extends Error> {
60
99
  /**
@@ -14,21 +14,25 @@ const common_1 = require("@nestjs/common");
14
14
  * {@link EncryptedRoute} instead of the basic router decorator functions like
15
15
  * {@link nest.Get} or {@link nest.Post} and the API function throws a custom
16
16
  * error whose class has been {@link ExceptionManager.insert inserted} in this
17
- * `EntityManager`, the error would be automatically converted to the regular
17
+ * `ExceptionManager`, the error would be automatically converted to the regular
18
18
  * {@link nest.HttpException} instance by the {@link ExceptionManager.Closure}
19
19
  * function.
20
20
  *
21
21
  * Therefore, with this `ExceptionManager` and {@link TypedRoute} or
22
22
  * {@link EncryptedRoute}, you can manage your custom error classes much
23
- * systemtically. You can avoid 500 internal server error or hard coding
23
+ * systematically. You can avoid 500 internal server error or hard coding
24
24
  * implementation about the custom error classes.
25
25
  *
26
- * Below error classes are defaultly configured in this `ExceptionManager`
26
+ * Below error class is configured in this `ExceptionManager` by default.
27
27
  *
28
- * - `typia.TypeGuardError`
29
28
  * - `@nestia/fetcher.HttpError`
30
29
  *
31
30
  * @author Jeongho Nam - https://github.com/samchon
31
+ * @evidence contracts/common.md#principled-implementation Converters are kept as an ordered list of class and closure, and an error is converted by the first class it is an instance of; the insertion keeps every subclass before its superclasses so the most specific converter wins, and `HttpError` from the fetcher is registered by default.
32
+ * @evidence contracts/common.md#clear-and-simple-design One namespace with the two collections and four operations; the listener set and the tuple list are the only state.
33
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts The registration is public and explicit; no error class is special-cased except the default `HttpError` conversion.
34
+ * @evidence contracts/common.md#meaningful-documentation The comment documents the converter and listener concepts with an example.
35
+ * @evidenceExclude contracts/portability.md#os-neutral-implementation Converter ordering and listener registration operate on JavaScript class and function identity, not native path or process identity.
32
36
  */
33
37
  var ExceptionManager;
34
38
  (function (ExceptionManager) {
@@ -40,13 +44,23 @@ var ExceptionManager;
40
44
  *
41
45
  * @param creator Target error class
42
46
  * @param closure A closure function converting to the `HttpException` class
47
+ * @evidence contracts/common.md#principled-implementation An existing entry for the same class is removed first, then the new entry is placed before the first registered class that it extends, so specificity order holds however the calls are ordered.
48
+ * @evidence contracts/common.md#clear-and-simple-design One function over one list.
49
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts The order rule is derived from the prototype chain, not from a list of known classes.
50
+ * @evidence contracts/common.md#meaningful-documentation The comment states the replacement and ordering rules.
51
+ * @evidenceExclude contracts/portability.md#os-neutral-implementation Converter ordering and listener registration operate on JavaScript class and function identity, not native path or process identity.
43
52
  */
44
53
  function insert(creator, closure) {
45
54
  const index = ExceptionManager.tuples.findIndex((tuple) => tuple[0] === creator);
46
55
  if (index !== -1)
47
56
  ExceptionManager.tuples.splice(index, 1);
48
- ExceptionManager.tuples.push([creator, closure]);
49
- ExceptionManager.tuples.sort(([x], [y]) => (x.prototype instanceof y ? -1 : 1));
57
+ // an error converts by the first class it is an instance of, so a class
58
+ // must precede every superclass of it: insert before the first one
59
+ const ancestor = ExceptionManager.tuples.findIndex(([registered]) => creator.prototype instanceof registered);
60
+ if (ancestor === -1)
61
+ ExceptionManager.tuples.push([creator, closure]);
62
+ else
63
+ ExceptionManager.tuples.splice(ancestor, 0, [creator, closure]);
50
64
  }
51
65
  ExceptionManager.insert = insert;
52
66
  /**
@@ -54,6 +68,11 @@ var ExceptionManager;
54
68
  *
55
69
  * @param creator Target error class
56
70
  * @returns Whether be erased or not
71
+ * @evidence contracts/common.md#principled-implementation The entry for the class is found by identity and removed, and the result says whether anything was removed.
72
+ * @evidence contracts/common.md#clear-and-simple-design One search and one removal.
73
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts It removes only the named class's entry.
74
+ * @evidence contracts/common.md#meaningful-documentation The comment states the parameter and the boolean result.
75
+ * @evidenceExclude contracts/portability.md#os-neutral-implementation Converter ordering and listener registration operate on JavaScript class and function identity, not native path or process identity.
57
76
  */
58
77
  function erase(creator) {
59
78
  const index = ExceptionManager.tuples.findIndex((tuple) => tuple[0] === creator);
@@ -63,10 +82,29 @@ var ExceptionManager;
63
82
  return true;
64
83
  }
65
84
  ExceptionManager.erase = erase;
85
+ /**
86
+ * Registers a listener called with every error thrown by a typed route, after
87
+ * the response conversion.
88
+ *
89
+ * @evidence contracts/common.md#principled-implementation The listener is added to a set, so the same function registered twice is called once.
90
+ * @evidence contracts/common.md#clear-and-simple-design One set insertion.
91
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts The listener only observes; the route notifies it after the current turn and ignores its errors.
92
+ * @evidence contracts/common.md#meaningful-documentation The comment states when listeners are called.
93
+ * @evidenceExclude contracts/portability.md#os-neutral-implementation Converter ordering and listener registration operate on JavaScript class and function identity, not native path or process identity.
94
+ */
66
95
  function on(closure) {
67
96
  ExceptionManager.listeners.add(closure);
68
97
  }
69
98
  ExceptionManager.on = on;
99
+ /**
100
+ * Unregisters a listener added with {@link on}.
101
+ *
102
+ * @evidence contracts/common.md#principled-implementation The listener is removed from the set by identity.
103
+ * @evidence contracts/common.md#clear-and-simple-design One set deletion.
104
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts It removes only the named listener.
105
+ * @evidence contracts/common.md#meaningful-documentation The comment names the counterpart operation.
106
+ * @evidenceExclude contracts/portability.md#os-neutral-implementation Converter ordering and listener registration operate on JavaScript class and function identity, not native path or process identity.
107
+ */
70
108
  function off(closure) {
71
109
  ExceptionManager.listeners.delete(closure);
72
110
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ExceptionManager.js","sourceRoot":"","sources":["../../src/utils/ExceptionManager.ts"],"names":[],"mappings":";;;AAAA,6CAA4C;AAC5C,2CAA+C;AAI/C;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,IAAiB,gBAAgB,CAsEhC;AAtED,WAAiB,gBAAgB;IAC/B;;;;;;;;OAQG;IACH,SAAgB,MAAM,CACpB,OAAmB,EACnB,OAAmB;QAEnB,MAAM,KAAK,GAAW,uBAAM,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC;QACxE,IAAI,KAAK,KAAK,CAAC,CAAC;YAAE,uBAAM,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAE1C,uBAAM,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;QAChC,uBAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACjE,CAAC;IATe,iBAAA,MAAM,SASrB,CAAA;IAED;;;;;OAKG;IACH,SAAgB,KAAK,CAAkB,OAAmB;QACxD,MAAM,KAAK,GAAW,uBAAM,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC;QACxE,IAAI,KAAK,KAAK,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;QAE/B,uBAAM,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QACxB,OAAO,IAAI,CAAC;IACd,CAAC;IANe,iBAAA,KAAK,QAMpB,CAAA;IAED,SAAgB,EAAE,CAAC,OAA4B;QAC7C,0BAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACzB,CAAC;IAFe,iBAAA,EAAE,KAEjB,CAAA;IAED,SAAgB,GAAG,CAAC,OAA4B;QAC9C,0BAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC5B,CAAC;IAFe,iBAAA,GAAG,MAElB,CAAA;IAwBD,gBAAgB;IACH,uBAAM,GAAwC,EAAE,CAAC;IAE9D,gBAAgB;IACH,0BAAS,GAA6B,IAAI,GAAG,EAAE,CAAC;AAC/D,CAAC,EAtEgB,gBAAgB,aAAhB,gBAAgB,GAAhB,gBAAgB,QAsEhC;AAED,gBAAgB,CAAC,MAAM,CACrB,mBAAS,EACT,CAAC,KAAK,EAAE,EAAE,CACR,IAAI,sBAAa,CACf;IACE,IAAI,EAAE,KAAK,CAAC,IAAI;IAChB,OAAO,EAAE,KAAK,CAAC,OAAO;CACvB,EACD,KAAK,CAAC,MAAM,CACb,CACJ,CAAC"}
1
+ {"version":3,"file":"ExceptionManager.js","sourceRoot":"","sources":["../../src/utils/ExceptionManager.ts"],"names":[],"mappings":";;;AAAA,6CAA4C;AAC5C,2CAA+C;AAI/C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,IAAiB,gBAAgB,CA8GhC;AA9GD,WAAiB,gBAAgB;IAC/B;;;;;;;;;;;;;OAaG;IACH,SAAgB,MAAM,CACpB,OAAmB,EACnB,OAAmB;QAEnB,MAAM,KAAK,GAAW,uBAAM,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC;QACxE,IAAI,KAAK,KAAK,CAAC,CAAC;YAAE,uBAAM,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAE1C,wEAAwE;QACxE,mEAAmE;QACnE,MAAM,QAAQ,GAAW,uBAAM,CAAC,SAAS,CACvC,CAAC,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,SAAS,YAAY,UAAU,CAC1D,CAAC;QACF,IAAI,QAAQ,KAAK,CAAC,CAAC;YAAE,uBAAM,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;;YAChD,uBAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;IACtD,CAAC;IAde,iBAAA,MAAM,SAcrB,CAAA;IAED;;;;;;;;;;OAUG;IACH,SAAgB,KAAK,CAAkB,OAAmB;QACxD,MAAM,KAAK,GAAW,uBAAM,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC;QACxE,IAAI,KAAK,KAAK,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;QAE/B,uBAAM,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QACxB,OAAO,IAAI,CAAC;IACd,CAAC;IANe,iBAAA,KAAK,QAMpB,CAAA;IAED;;;;;;;;;OASG;IACH,SAAgB,EAAE,CAAC,OAA4B;QAC7C,0BAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACzB,CAAC;IAFe,iBAAA,EAAE,KAEjB,CAAA;IAED;;;;;;;;OAQG;IACH,SAAgB,GAAG,CAAC,OAA4B;QAC9C,0BAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC5B,CAAC;IAFe,iBAAA,GAAG,MAElB,CAAA;IA8BD,gBAAgB;IACH,uBAAM,GAAwC,EAAE,CAAC;IAE9D,gBAAgB;IACH,0BAAS,GAA6B,IAAI,GAAG,EAAE,CAAC;AAC/D,CAAC,EA9GgB,gBAAgB,aAAhB,gBAAgB,GAAhB,gBAAgB,QA8GhC;AAED,gBAAgB,CAAC,MAAM,CACrB,mBAAS,EACT,CAAC,KAAK,EAAE,EAAE,CACR,IAAI,sBAAa,CACf;IACE,IAAI,EAAE,KAAK,CAAC,IAAI;IAChB,OAAO,EAAE,KAAK,CAAC,OAAO;CACvB,EACD,KAAK,CAAC,MAAM,CACb,CACJ,CAAC"}
@@ -1,4 +1,26 @@
1
+ /**
2
+ * Finds source files by path, directory, or glob.
3
+ *
4
+ * @evidence contracts/common.md#principled-implementation The finder resolves each pattern to existing files or directories, walks directories, applies the caller's filter to files only, and subtracts the excluded set, so the result is the included files minus the excluded ones.
5
+ * @evidence contracts/common.md#clear-and-simple-design One public function and private walkers; the caller supplies the filter.
6
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts It contains no file names; extensions come from the caller's filter.
7
+ * @evidence contracts/common.md#meaningful-documentation The comment states its purpose.
8
+ * @evidence contracts/portability.md#os-neutral-implementation The finder turns each pattern into an absolute native path with `path.resolve` and asks the filesystem itself, through `existsSync`, `stat` and `readdir`, whether a path exists and what it is, so the volume's own case policy and links apply. Only the part of a pattern below its longest existing ancestor is globbed, rewritten from the native separator to `/` because glob reads a Windows backslash as an escape. Remaining assumptions: the case policy of wildcard matching is glob's own platform default and not a probe of the volume, accepted files are keyed by filesystem real path while returned locations retain their discovered spelling, and directory links are followed once per real path in each include or exclude collection, so aliases and cycles do not repeat a traversal.
9
+ */
1
10
  export declare namespace SourceFinder {
11
+ /**
12
+ * Returns the files matched by the include patterns and not by the exclude
13
+ * patterns.
14
+ *
15
+ * A pattern may name a file, a directory that is walked recursively, or a
16
+ * glob. Only files accepted by the filter are returned.
17
+ *
18
+ * @evidence contracts/common.md#principled-implementation A pattern that exists on disk is used as a path; otherwise its longest existing ancestor becomes the base of a glob search, so a pattern with wildcards is matched below the part of the path that exists, and a base that does not exist matches nothing; accepted file identities use filesystem real paths, so includes and exclusions agree across links and case aliases while output retains a discovered native spelling.
19
+ * @evidence contracts/common.md#clear-and-simple-design One function that runs the same collection twice, once adding and once removing.
20
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts The result follows the patterns and the filter, with no fixed directory.
21
+ * @evidence contracts/common.md#meaningful-documentation The comment states the pattern forms and the filtering.
22
+ * @evidence contracts/portability.md#os-neutral-implementation An existing path is used literally, so no character glob reads specially is interpreted. Otherwise the nearest existing ancestor, found with `existsSync` and `dirname` until the filesystem root, is the glob's working directory and the matches are resolved against it, so a drive letter or a UNC root never enters the pattern.
23
+ */
2
24
  const find: (props: IProps) => Promise<string[]>;
3
25
  }
4
26
  interface IProps {
@@ -16,41 +16,91 @@ exports.SourceFinder = void 0;
16
16
  const fs_1 = __importDefault(require("fs"));
17
17
  const glob_1 = require("glob");
18
18
  const path_1 = __importDefault(require("path"));
19
+ /**
20
+ * Finds source files by path, directory, or glob.
21
+ *
22
+ * @evidence contracts/common.md#principled-implementation The finder resolves each pattern to existing files or directories, walks directories, applies the caller's filter to files only, and subtracts the excluded set, so the result is the included files minus the excluded ones.
23
+ * @evidence contracts/common.md#clear-and-simple-design One public function and private walkers; the caller supplies the filter.
24
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts It contains no file names; extensions come from the caller's filter.
25
+ * @evidence contracts/common.md#meaningful-documentation The comment states its purpose.
26
+ * @evidence contracts/portability.md#os-neutral-implementation The finder turns each pattern into an absolute native path with `path.resolve` and asks the filesystem itself, through `existsSync`, `stat` and `readdir`, whether a path exists and what it is, so the volume's own case policy and links apply. Only the part of a pattern below its longest existing ancestor is globbed, rewritten from the native separator to `/` because glob reads a Windows backslash as an escape. Remaining assumptions: the case policy of wildcard matching is glob's own platform default and not a probe of the volume, accepted files are keyed by filesystem real path while returned locations retain their discovered spelling, and directory links are followed once per real path in each include or exclude collection, so aliases and cycles do not repeat a traversal.
27
+ */
19
28
  var SourceFinder;
20
29
  (function (SourceFinder) {
30
+ /**
31
+ * Returns the files matched by the include patterns and not by the exclude
32
+ * patterns.
33
+ *
34
+ * A pattern may name a file, a directory that is walked recursively, or a
35
+ * glob. Only files accepted by the filter are returned.
36
+ *
37
+ * @evidence contracts/common.md#principled-implementation A pattern that exists on disk is used as a path; otherwise its longest existing ancestor becomes the base of a glob search, so a pattern with wildcards is matched below the part of the path that exists, and a base that does not exist matches nothing; accepted file identities use filesystem real paths, so includes and exclusions agree across links and case aliases while output retains a discovered native spelling.
38
+ * @evidence contracts/common.md#clear-and-simple-design One function that runs the same collection twice, once adding and once removing.
39
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts The result follows the patterns and the filter, with no fixed directory.
40
+ * @evidence contracts/common.md#meaningful-documentation The comment states the pattern forms and the filtering.
41
+ * @evidence contracts/portability.md#os-neutral-implementation An existing path is used literally, so no character glob reads specially is interpreted. Otherwise the nearest existing ancestor, found with `existsSync` and `dirname` until the filesystem root, is the glob's working directory and the matches are resolved against it, so a drive letter or a UNC root never enters the pattern.
42
+ */
21
43
  SourceFinder.find = (props) => __awaiter(this, void 0, void 0, function* () {
22
44
  var _a;
23
- const dict = new Set();
24
- yield emplace(props.filter)(props.include)((str) => dict.add(str));
45
+ const dict = new Map();
46
+ yield emplace(props.filter)(props.include)((str) => dict.set(fs_1.default.realpathSync.native(str), str));
25
47
  if ((_a = props.exclude) === null || _a === void 0 ? void 0 : _a.length)
26
- yield emplace(props.filter)(props.exclude)((str) => dict.delete(str));
27
- return [...dict];
48
+ yield emplace(props.filter)(props.exclude)((str) => dict.delete(fs_1.default.realpathSync.native(str)));
49
+ return [...dict.values()];
28
50
  });
29
51
  const emplace = (filter) => (input) => (closure) => __awaiter(this, void 0, void 0, function* () {
52
+ const visited = new Set();
30
53
  for (const pattern of input) {
31
- for (const file of yield _Glob(path_1.default.resolve(pattern))) {
54
+ for (const file of yield _Glob(pattern)) {
32
55
  const stats = yield fs_1.default.promises.stat(file);
33
56
  if (stats.isDirectory() === true)
34
- yield iterate(filter)(closure)(file);
57
+ yield iterate(filter)(closure)(file, visited);
35
58
  else if (stats.isFile() && filter(file))
36
59
  closure(file);
37
60
  }
38
61
  }
39
62
  });
40
- const iterate = (filter) => (closure) => (location) => __awaiter(this, void 0, void 0, function* () {
63
+ const iterate = (filter) => (closure) => (location, visited) => __awaiter(this, void 0, void 0, function* () {
64
+ const identity = yield fs_1.default.promises.realpath(location);
65
+ if (visited.has(identity))
66
+ return;
67
+ visited.add(identity);
41
68
  const directory = yield fs_1.default.promises.readdir(location);
42
69
  for (const file of directory) {
43
70
  const next = path_1.default.resolve(`${location}/${file}`);
44
71
  const stats = yield fs_1.default.promises.stat(next);
45
72
  if (stats.isDirectory() === true)
46
- yield iterate(filter)(closure)(next);
73
+ yield iterate(filter)(closure)(next, visited);
47
74
  else if (stats.isFile() && filter(next))
48
75
  closure(next);
49
76
  }
50
77
  });
78
+ /**
79
+ * Files and directories a path or glob pattern names.
80
+ *
81
+ * An existing path is taken literally, whatever characters it holds, as a
82
+ * directory such as `app [v2]` would otherwise read as a character class. For
83
+ * a pattern, the longest existing ancestor is the literal base and only the
84
+ * rest is globbed, with `/` separators, since glob reads a Windows backslash
85
+ * as an escape.
86
+ */
51
87
  const _Glob = (pattern) => __awaiter(this, void 0, void 0, function* () {
52
- const matches = yield (0, glob_1.glob)(pattern);
53
- return matches.map((str) => path_1.default.resolve(str));
88
+ const absolute = path_1.default.resolve(pattern);
89
+ if (fs_1.default.existsSync(absolute))
90
+ return [absolute];
91
+ let base = absolute;
92
+ while (fs_1.default.existsSync(base) === false) {
93
+ const parent = path_1.default.dirname(base);
94
+ if (parent === base)
95
+ return [];
96
+ base = parent;
97
+ }
98
+ const rest = path_1.default
99
+ .relative(base, absolute)
100
+ .split(path_1.default.sep)
101
+ .join("/");
102
+ const matches = yield (0, glob_1.glob)(rest, { cwd: base });
103
+ return matches.map((str) => path_1.default.resolve(base, str));
54
104
  });
55
105
  })(SourceFinder || (exports.SourceFinder = SourceFinder = {}));
56
106
  //# sourceMappingURL=SourceFinder.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SourceFinder.js","sourceRoot":"","sources":["../../src/utils/SourceFinder.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,4CAAoB;AACpB,+BAA4B;AAC5B,gDAAwB;AAExB,IAAiB,YAAY,CA2C5B;AA3CD,WAAiB,YAAY;IACd,iBAAI,GAAG,CAAO,KAAa,EAAqB,EAAE;;QAC7D,MAAM,IAAI,GAAgB,IAAI,GAAG,EAAE,CAAC;QAEpC,MAAM,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;QACnE,IAAI,MAAA,KAAK,CAAC,OAAO,0CAAE,MAAM;YACvB,MAAM,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QAExE,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;IACnB,CAAC,CAAA,CAAC;IAEF,MAAM,OAAO,GACX,CAAC,MAAiC,EAAE,EAAE,CACtC,CAAC,KAAe,EAAE,EAAE,CACpB,CAAO,OAAmC,EAAiB,EAAE;QAC3D,KAAK,MAAM,OAAO,IAAI,KAAK,EAAE,CAAC;YAC5B,KAAK,MAAM,IAAI,IAAI,MAAM,KAAK,CAAC,cAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;gBACtD,MAAM,KAAK,GAAa,MAAM,YAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACrD,IAAI,KAAK,CAAC,WAAW,EAAE,KAAK,IAAI;oBAC9B,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC;qBAClC,IAAI,KAAK,CAAC,MAAM,EAAE,IAAI,MAAM,CAAC,IAAI,CAAC;oBAAE,OAAO,CAAC,IAAI,CAAC,CAAC;YACzD,CAAC;QACH,CAAC;IACH,CAAC,CAAA,CAAC;IAEJ,MAAM,OAAO,GACX,CAAC,MAAqC,EAAE,EAAE,CAC1C,CAAC,OAAmC,EAAE,EAAE,CACxC,CAAO,QAAgB,EAAiB,EAAE;QACxC,MAAM,SAAS,GAAa,MAAM,YAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAChE,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;YAC7B,MAAM,IAAI,GAAW,cAAI,CAAC,OAAO,CAAC,GAAG,QAAQ,IAAI,IAAI,EAAE,CAAC,CAAC;YACzD,MAAM,KAAK,GAAa,MAAM,YAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAErD,IAAI,KAAK,CAAC,WAAW,EAAE,KAAK,IAAI;gBAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC;iBAClE,IAAI,KAAK,CAAC,MAAM,EAAE,IAAI,MAAM,CAAC,IAAI,CAAC;gBAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QACzD,CAAC;IACH,CAAC,CAAA,CAAC;IAEJ,MAAM,KAAK,GAAG,CAAO,OAAe,EAAqB,EAAE;QACzD,MAAM,OAAO,GAAG,MAAM,IAAA,WAAI,EAAC,OAAO,CAAC,CAAC;QACpC,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,cAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;IACjD,CAAC,CAAA,CAAC;AACJ,CAAC,EA3CgB,YAAY,aAAZ,YAAY,GAAZ,YAAY,QA2C5B"}
1
+ {"version":3,"file":"SourceFinder.js","sourceRoot":"","sources":["../../src/utils/SourceFinder.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,52 @@
1
1
  import { VERSION_NEUTRAL, VersionValue } from "@nestjs/common/interfaces";
2
+ /**
3
+ * Resolves the URI versions of a controller method the way NestJS does.
4
+ *
5
+ * @evidence contracts/common.md#principled-implementation The namespace turns the version metadata of a controller and a method, with the default version of the application, into the version path segments, following NestJS's precedence.
6
+ * @evidence contracts/common.md#clear-and-simple-design Two functions and one configuration type.
7
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts The precedence follows NestJS; no version string is special-cased.
8
+ * @evidence contracts/common.md#meaningful-documentation The comment states its purpose.
9
+ * @evidenceExclude contracts/portability.md#os-neutral-implementation Version precedence and prefix concatenation produce HTTP URI segments and never resolve native filesystem paths.
10
+ */
2
11
  export declare namespace VersioningStrategy {
12
+ /**
13
+ * The URI versioning options the adapter reads: the prefix and the default
14
+ * version.
15
+ *
16
+ * @evidence contracts/common.md#principled-implementation The two fields are what NestJS's URI versioning uses to build a version segment.
17
+ * @evidence contracts/common.md#clear-and-simple-design A two-field record.
18
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts It is a type and adds no runtime behavior.
19
+ * @evidence contracts/common.md#meaningful-documentation The comment names the two fields.
20
+ * @evidenceExclude contracts/portability.md#os-neutral-implementation Version precedence and prefix concatenation produce HTTP URI segments and never resolve native filesystem paths.
21
+ */
3
22
  interface IConfig {
4
23
  prefix: string;
5
24
  defaultVersion?: VersionValue;
6
25
  }
7
- const cast: (value: VersionValue | undefined) => Array<string | typeof VERSION_NEUTRAL>;
8
- const merge: (config: IConfig | undefined) => (values: Array<string | typeof VERSION_NEUTRAL>) => string[];
26
+ /**
27
+ * Casts version metadata to a list: a missing value stays absent and a single
28
+ * value is a one-element list.
29
+ *
30
+ * @evidence contracts/common.md#principled-implementation One version becomes a list while absence and an explicit empty list remain distinct, because Nest treats an empty version list as no registered paths rather than inherited versions.
31
+ * @evidence contracts/common.md#clear-and-simple-design One conditional expression.
32
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts It adds nothing to the values.
33
+ * @evidence contracts/common.md#meaningful-documentation The comment states the three cases.
34
+ * @evidenceExclude contracts/portability.md#os-neutral-implementation Version precedence and prefix concatenation produce HTTP URI segments and never resolve native filesystem paths.
35
+ */
36
+ const cast: (value: VersionValue | undefined) => Array<string | typeof VERSION_NEUTRAL> | undefined;
37
+ /**
38
+ * Version path segments of a route, resolved as NestJS resolves them: the
39
+ * method's versions, else the controller's, else the default version, and no
40
+ * version at all is the unversioned path (#1735).
41
+ *
42
+ * @evidence contracts/common.md#principled-implementation The first present method, controller or default version list wins, including an empty list that registers no paths. Duplicates are dropped, a neutral version maps to no segment, and absent metadata also maps to no segment; with versioning off the only path has no version.
43
+ * @evidence contracts/common.md#clear-and-simple-design One function returning the segments, curried on the configuration so a caller can compute the segments per method.
44
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts The precedence is NestJS's, and no version is special-cased.
45
+ * @evidence contracts/common.md#meaningful-documentation The comment states the precedence and the neutral version rule.
46
+ * @evidenceExclude contracts/portability.md#os-neutral-implementation Version precedence and prefix concatenation produce HTTP URI segments and never resolve native filesystem paths.
47
+ */
48
+ const merge: (config: IConfig | undefined) => (props: {
49
+ controller: Array<string | typeof VERSION_NEUTRAL> | undefined;
50
+ method: Array<string | typeof VERSION_NEUTRAL> | undefined;
51
+ }) => string[];
9
52
  }
@@ -1,17 +1,50 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.VersioningStrategy = void 0;
4
+ /**
5
+ * Resolves the URI versions of a controller method the way NestJS does.
6
+ *
7
+ * @evidence contracts/common.md#principled-implementation The namespace turns the version metadata of a controller and a method, with the default version of the application, into the version path segments, following NestJS's precedence.
8
+ * @evidence contracts/common.md#clear-and-simple-design Two functions and one configuration type.
9
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts The precedence follows NestJS; no version string is special-cased.
10
+ * @evidence contracts/common.md#meaningful-documentation The comment states its purpose.
11
+ * @evidenceExclude contracts/portability.md#os-neutral-implementation Version precedence and prefix concatenation produce HTTP URI segments and never resolve native filesystem paths.
12
+ */
4
13
  var VersioningStrategy;
5
14
  (function (VersioningStrategy) {
6
- VersioningStrategy.cast = (value) => value === undefined ? [] : Array.isArray(value) ? value : [value];
7
- VersioningStrategy.merge = (config) => (values) => {
15
+ /**
16
+ * Casts version metadata to a list: a missing value stays absent and a single
17
+ * value is a one-element list.
18
+ *
19
+ * @evidence contracts/common.md#principled-implementation One version becomes a list while absence and an explicit empty list remain distinct, because Nest treats an empty version list as no registered paths rather than inherited versions.
20
+ * @evidence contracts/common.md#clear-and-simple-design One conditional expression.
21
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts It adds nothing to the values.
22
+ * @evidence contracts/common.md#meaningful-documentation The comment states the three cases.
23
+ * @evidenceExclude contracts/portability.md#os-neutral-implementation Version precedence and prefix concatenation produce HTTP URI segments and never resolve native filesystem paths.
24
+ */
25
+ VersioningStrategy.cast = (value) => value === undefined ? undefined : Array.isArray(value) ? value : [value];
26
+ /**
27
+ * Version path segments of a route, resolved as NestJS resolves them: the
28
+ * method's versions, else the controller's, else the default version, and no
29
+ * version at all is the unversioned path (#1735).
30
+ *
31
+ * @evidence contracts/common.md#principled-implementation The first present method, controller or default version list wins, including an empty list that registers no paths. Duplicates are dropped, a neutral version maps to no segment, and absent metadata also maps to no segment; with versioning off the only path has no version.
32
+ * @evidence contracts/common.md#clear-and-simple-design One function returning the segments, curried on the configuration so a caller can compute the segments per method.
33
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts The precedence is NestJS's, and no version is special-cased.
34
+ * @evidence contracts/common.md#meaningful-documentation The comment states the precedence and the neutral version rule.
35
+ * @evidenceExclude contracts/portability.md#os-neutral-implementation Version precedence and prefix concatenation produce HTTP URI segments and never resolve native filesystem paths.
36
+ */
37
+ VersioningStrategy.merge = (config) => (props) => {
38
+ var _a, _b;
8
39
  if (config === undefined)
9
40
  return [""];
10
- const set = new Set(values);
11
- const array = set.size === 0 ? VersioningStrategy.cast(config.defaultVersion) : Array.from(set);
12
- return !!(array === null || array === void 0 ? void 0 : array.length)
13
- ? array.map((x) => typeof x === "symbol" ? "" : `${config.prefix}${x}`)
14
- : [];
41
+ const chosen = (_b = (_a = props.method) !== null && _a !== void 0 ? _a : props.controller) !== null && _b !== void 0 ? _b : VersioningStrategy.cast(config.defaultVersion);
42
+ if (chosen === undefined)
43
+ return [""];
44
+ const unique = [
45
+ ...new Set(chosen),
46
+ ];
47
+ return unique.map((x) => typeof x === "symbol" ? "" : `${config.prefix}${x}`);
15
48
  };
16
49
  })(VersioningStrategy || (exports.VersioningStrategy = VersioningStrategy = {}));
17
50
  //# sourceMappingURL=VersioningStrategy.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"VersioningStrategy.js","sourceRoot":"","sources":["../../src/utils/VersioningStrategy.ts"],"names":[],"mappings":";;;AAEA,IAAiB,kBAAkB,CAwBlC;AAxBD,WAAiB,kBAAkB;IAMpB,uBAAI,GAAG,CAClB,KAA+B,EACS,EAAE,CAC1C,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAEvD,wBAAK,GAChB,CAAC,MAA2B,EAAE,EAAE,CAChC,CAAC,MAA8C,EAAY,EAAE;QAC3D,IAAI,MAAM,KAAK,SAAS;YAAE,OAAO,CAAC,EAAE,CAAC,CAAC;QACtC,MAAM,GAAG,GAAyC,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;QAClE,MAAM,KAAK,GACT,GAAG,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,uBAAI,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACjE,OAAO,CAAC,EAAC,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,MAAM,CAAA;YACpB,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACd,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CACpD;YACH,CAAC,CAAC,EAAE,CAAC;IACT,CAAC,CAAC;AACN,CAAC,EAxBgB,kBAAkB,aAAlB,kBAAkB,GAAlB,kBAAkB,QAwBlC"}
1
+ {"version":3,"file":"VersioningStrategy.js","sourceRoot":"","sources":["../../src/utils/VersioningStrategy.ts"],"names":[],"mappings":";;;AAEA;;;;;;;;GAQG;AACH,IAAiB,kBAAkB,CA2DlC;AA3DD,WAAiB,kBAAkB;IAgBjC;;;;;;;;;OASG;IACU,uBAAI,GAAG,CAClB,KAA+B,EACqB,EAAE,CACtD,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAE3E;;;;;;;;;;OAUG;IACU,wBAAK,GAChB,CAAC,MAA2B,EAAE,EAAE,CAChC,CAAC,KAGA,EAAY,EAAE;;QACb,IAAI,MAAM,KAAK,SAAS;YAAE,OAAO,CAAC,EAAE,CAAC,CAAC;QACtC,MAAM,MAAM,eACV,KAAK,CAAC,MAAM,mCAAI,KAAK,CAAC,UAAU,mCAAI,uBAAI,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;QAClE,IAAI,MAAM,KAAK,SAAS;YAAE,OAAO,CAAC,EAAE,CAAC,CAAC;QACtC,MAAM,MAAM,GAA2C;YACrD,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC;SACnB,CAAC;QACF,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACtB,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CACpD,CAAC;IACJ,CAAC,CAAC;AACN,CAAC,EA3DgB,kBAAkB,aAAlB,kBAAkB,GAAlB,kBAAkB,QA2DlC"}
package/native/go.mod CHANGED
@@ -10,7 +10,7 @@ require (
10
10
  github.com/microsoft/typescript-go/shim/printer v0.0.0
11
11
  github.com/microsoft/typescript-go/shim/scanner v0.0.0
12
12
  github.com/samchon/ttsc/packages/ttsc v0.0.0
13
- github.com/samchon/typia/packages/typia/native v0.0.0-20260818045905-f692fd63a846
13
+ github.com/samchon/typia/packages/typia/native v0.0.0-20260926142025-755176823ba3
14
14
  )
15
15
 
16
16
  require (
package/native/go.sum CHANGED
@@ -38,8 +38,8 @@ github.com/samchon/ttsc/packages/ttsc/shim/vfs/cachedvfs v0.0.0-20260820075544-3
38
38
  github.com/samchon/ttsc/packages/ttsc/shim/vfs/cachedvfs v0.0.0-20260820075544-3fe6b732f888/go.mod h1:XS3LhXkn5xadyRe3tW+9+suW/7gh7dPdL43Q+s/lUDo=
39
39
  github.com/samchon/ttsc/packages/ttsc/shim/vfs/osvfs v0.0.0-20260820075544-3fe6b732f888 h1:ihiKD2OhuYc7Dngxw3uFYbVoiA/xuPwwQoUakB59E40=
40
40
  github.com/samchon/ttsc/packages/ttsc/shim/vfs/osvfs v0.0.0-20260820075544-3fe6b732f888/go.mod h1:otX+qw8aZLNCoBmCwMAn53Nw0RQTPzSoId3DxmE67So=
41
- github.com/samchon/typia/packages/typia/native v0.0.0-20260818045905-f692fd63a846 h1:x9xL0zn2AqPf19lTp8dNal+Ia3cIu0uYnyXlY4mo3QI=
42
- github.com/samchon/typia/packages/typia/native v0.0.0-20260818045905-f692fd63a846/go.mod h1:pUTSG5IZxw8Hohle//RsDXnE+8ZhAus7mPDKFqzvZnk=
41
+ github.com/samchon/typia/packages/typia/native v0.0.0-20260926142025-755176823ba3 h1:XtRIf6wvDuSHLsphMXiB3lm6p0/2sxHMfc6FMjI5LLA=
42
+ github.com/samchon/typia/packages/typia/native v0.0.0-20260926142025-755176823ba3/go.mod h1:pUTSG5IZxw8Hohle//RsDXnE+8ZhAus7mPDKFqzvZnk=
43
43
  github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ=
44
44
  github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=
45
45
  github.com/zeebo/xxh3 v1.1.0 h1:s7DLGDK45Dyfg7++yxI0khrfwq9661w9EN78eP/UZVs=