@decohere/http 0.0.1-dev.126 → 0.0.1-dev.5

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 (293) hide show
  1. package/README.md +2 -2
  2. package/package.json +4 -13
  3. package/src/app/app.ts +147 -0
  4. package/src/app/module.ts +19 -0
  5. package/src/auth/ability.ts +56 -0
  6. package/src/auth/auth.config.ts +34 -0
  7. package/src/auth/auth.extensions.ts +115 -0
  8. package/src/auth/auth.types.ts +124 -0
  9. package/src/auth/casl-authorization.service.ts +62 -0
  10. package/{types/src/auth/principal-provider.d.ts → src/auth/principal-provider.ts} +13 -5
  11. package/src/auth/safe-outbound-url.ts +117 -0
  12. package/src/auth/token-service.ts +192 -0
  13. package/src/builder/builder.ts +118 -0
  14. package/{es6/src/const.js → src/const.ts} +25 -17
  15. package/src/health/health.controller.ts +34 -0
  16. package/src/health/health.extensions.ts +53 -0
  17. package/src/health/readiness.service.ts +33 -0
  18. package/{types/src/health/readiness.types.d.ts → src/health/readiness.types.ts} +4 -8
  19. package/src/hosting/hosted-service-host.ts +102 -0
  20. package/src/hosting/hosted-service.ts +31 -0
  21. package/src/http/http.compression.ts +38 -0
  22. package/src/http/http.extensions.ts +244 -0
  23. package/{types/src/http/http.options.store.d.ts → src/http/http.options.store.ts} +11 -1
  24. package/src/http/http.options.ts +41 -0
  25. package/{types/src/http/http.security.d.ts → src/http/http.security.ts} +16 -10
  26. package/src/http/http.static.ts +359 -0
  27. package/{es6/src/index.js → src/index.ts} +1 -0
  28. package/src/openapi/index.ts +22 -0
  29. package/src/openapi/openapi.generator.ts +78 -0
  30. package/src/openapi/openapi.types.ts +60 -0
  31. package/src/openapi/request-schema.ts +155 -0
  32. package/src/openapi/request-validator.ts +95 -0
  33. package/src/providers/fastify.provider.ts +454 -0
  34. package/src/routing/anvil.types.ts +150 -0
  35. package/src/routing/decorators/argument.decorator.ts +33 -0
  36. package/src/routing/decorators/auth.decorator.ts +79 -0
  37. package/src/routing/decorators/controller.decorator.ts +9 -0
  38. package/src/routing/decorators/field.decorator.ts +15 -0
  39. package/src/routing/decorators/request.decorator.ts +34 -0
  40. package/src/routing/decorators/response.decorator.ts +18 -0
  41. package/src/routing/decorators/route.decorator.ts +52 -0
  42. package/src/routing/filters/exception-filter-host.ts +90 -0
  43. package/src/routing/filters/exception-filter.ts +29 -0
  44. package/src/routing/middleware/http-access-log.middleware.ts +36 -0
  45. package/src/routing/middleware/middleware.ts +26 -0
  46. package/src/routing/middleware/request-id.ts +18 -0
  47. package/src/routing/path.util.ts +38 -0
  48. package/src/routing/pipes/pipes.ts +132 -0
  49. package/src/routing/services/route-argument-resolver.ts +92 -0
  50. package/src/routing/services/route-registry.ts +229 -0
  51. package/src/routing/services/router.ts +166 -0
  52. package/src/sse/sse.decorator.ts +41 -0
  53. package/src/sse/sse.encoder.ts +86 -0
  54. package/src/sse/sse.types.ts +47 -0
  55. package/src/sse/sse.wire.ts +34 -0
  56. package/src/testing/boot-module.ts +63 -0
  57. package/src/testing/sse-reader.ts +120 -0
  58. package/tests/app.hosted-services.spec.ts +292 -0
  59. package/tests/app.shutdown.integration.spec.ts +160 -0
  60. package/tests/app.spec.ts +132 -0
  61. package/tests/auth.ability.spec.ts +48 -0
  62. package/tests/auth.decorators.spec.ts +20 -0
  63. package/tests/auth.fail-closed.pentest.spec.ts +77 -0
  64. package/tests/auth.integration.spec.ts +234 -0
  65. package/tests/auth.jwks-cache.spec.ts +52 -0
  66. package/tests/auth.missing-auth.pentest.spec.ts +56 -0
  67. package/tests/auth.oidc-ssrf.pentest.spec.ts +72 -0
  68. package/tests/auth.oidc.integration.spec.ts +161 -0
  69. package/tests/auth.token-service.spec.ts +251 -0
  70. package/tests/builder.spec.ts +12 -0
  71. package/tests/health.integration.spec.ts +111 -0
  72. package/tests/helpers/listen-ephemeral.ts +13 -0
  73. package/tests/helpers/local-oidc-server.ts +100 -0
  74. package/tests/http.access-log.integration.spec.ts +111 -0
  75. package/tests/http.boolean-query.integration.spec.ts +59 -0
  76. package/tests/http.compression.integration.spec.ts +604 -0
  77. package/tests/http.date-query.integration.spec.ts +71 -0
  78. package/tests/http.global-prefix.integration.spec.ts +284 -0
  79. package/tests/http.number-query.integration.spec.ts +65 -0
  80. package/tests/http.pino-roll-hmr.integration.spec.ts +79 -0
  81. package/tests/http.pipeline-order.integration.spec.ts +95 -0
  82. package/tests/http.request-cleanup.integration.spec.ts +57 -0
  83. package/tests/http.request-id-scope.pentest.spec.ts +50 -0
  84. package/tests/http.security.integration.spec.ts +106 -0
  85. package/tests/http.static.integration.spec.ts +847 -0
  86. package/tests/http.static.spec.ts +111 -0
  87. package/tests/http.surface.integration.spec.ts +167 -0
  88. package/tests/openapi.integration.spec.ts +193 -0
  89. package/tests/openapi.validator-cache.integration.spec.ts +55 -0
  90. package/tests/routing.decorators.spec.ts +15 -0
  91. package/tests/routing.registry.spec.ts +44 -0
  92. package/tests/routing.resolver.spec.ts +92 -0
  93. package/tests/sse.integration.spec.ts +421 -0
  94. package/tests/sse.wire.spec.ts +33 -0
  95. package/LICENSE +0 -15
  96. package/commonjs/src/app/app.js +0 -166
  97. package/commonjs/src/app/index.js +0 -19
  98. package/commonjs/src/app/module.js +0 -17
  99. package/commonjs/src/auth/ability.js +0 -54
  100. package/commonjs/src/auth/auth.config.js +0 -23
  101. package/commonjs/src/auth/auth.extensions.js +0 -106
  102. package/commonjs/src/auth/auth.types.js +0 -65
  103. package/commonjs/src/auth/casl-authorization.service.js +0 -36
  104. package/commonjs/src/auth/index.js +0 -23
  105. package/commonjs/src/auth/principal-provider.js +0 -19
  106. package/commonjs/src/auth/safe-outbound-url.js +0 -102
  107. package/commonjs/src/auth/token-service.js +0 -151
  108. package/commonjs/src/builder/builder.js +0 -95
  109. package/commonjs/src/builder/index.js +0 -18
  110. package/commonjs/src/const.js +0 -87
  111. package/commonjs/src/health/health.controller.js +0 -75
  112. package/commonjs/src/health/health.extensions.js +0 -50
  113. package/commonjs/src/health/index.js +0 -21
  114. package/commonjs/src/health/readiness.service.js +0 -67
  115. package/commonjs/src/health/readiness.types.js +0 -7
  116. package/commonjs/src/hosting/hosted-service-host.js +0 -88
  117. package/commonjs/src/hosting/hosted-service.js +0 -11
  118. package/commonjs/src/hosting/index.js +0 -19
  119. package/commonjs/src/http/http.compression.js +0 -27
  120. package/commonjs/src/http/http.extensions.js +0 -269
  121. package/commonjs/src/http/http.options.js +0 -26
  122. package/commonjs/src/http/http.options.store.js +0 -20
  123. package/commonjs/src/http/http.security.js +0 -27
  124. package/commonjs/src/http/http.static.js +0 -248
  125. package/commonjs/src/http/index.js +0 -22
  126. package/commonjs/src/index.js +0 -27
  127. package/commonjs/src/openapi/index.js +0 -45
  128. package/commonjs/src/openapi/openapi.generator.js +0 -103
  129. package/commonjs/src/openapi/openapi.types.js +0 -4
  130. package/commonjs/src/openapi/request-schema.js +0 -187
  131. package/commonjs/src/openapi/request-validator.js +0 -85
  132. package/commonjs/src/providers/fastify.provider.js +0 -391
  133. package/commonjs/src/providers/index.js +0 -18
  134. package/commonjs/src/routing/anvil.types.js +0 -99
  135. package/commonjs/src/routing/decorators/argument.decorator.js +0 -49
  136. package/commonjs/src/routing/decorators/auth.decorator.js +0 -70
  137. package/commonjs/src/routing/decorators/controller.decorator.js +0 -16
  138. package/commonjs/src/routing/decorators/field.decorator.js +0 -25
  139. package/commonjs/src/routing/decorators/index.js +0 -24
  140. package/commonjs/src/routing/decorators/request.decorator.js +0 -30
  141. package/commonjs/src/routing/decorators/response.decorator.js +0 -34
  142. package/commonjs/src/routing/decorators/route.decorator.js +0 -67
  143. package/commonjs/src/routing/filters/exception-filter-host.js +0 -145
  144. package/commonjs/src/routing/filters/exception-filter.js +0 -28
  145. package/commonjs/src/routing/index.js +0 -25
  146. package/commonjs/src/routing/middleware/http-access-log.middleware.js +0 -47
  147. package/commonjs/src/routing/middleware/middleware.js +0 -20
  148. package/commonjs/src/routing/middleware/request-id.js +0 -30
  149. package/commonjs/src/routing/path.util.js +0 -51
  150. package/commonjs/src/routing/pipes/index.js +0 -18
  151. package/commonjs/src/routing/pipes/pipes.js +0 -145
  152. package/commonjs/src/routing/services/index.js +0 -18
  153. package/commonjs/src/routing/services/route-argument-resolver.js +0 -77
  154. package/commonjs/src/routing/services/route-registry.js +0 -194
  155. package/commonjs/src/routing/services/router.js +0 -158
  156. package/commonjs/src/sse/index.js +0 -26
  157. package/commonjs/src/sse/sse.decorator.js +0 -42
  158. package/commonjs/src/sse/sse.encoder.js +0 -73
  159. package/commonjs/src/sse/sse.types.js +0 -36
  160. package/commonjs/src/sse/sse.wire.js +0 -40
  161. package/commonjs/src/testing/boot-module.js +0 -38
  162. package/commonjs/src/testing/index.js +0 -20
  163. package/commonjs/src/testing/sse-reader.js +0 -98
  164. package/es6/src/app/app.js +0 -148
  165. package/es6/src/app/index.js +0 -2
  166. package/es6/src/app/module.js +0 -7
  167. package/es6/src/auth/ability.js +0 -45
  168. package/es6/src/auth/auth.config.js +0 -19
  169. package/es6/src/auth/auth.extensions.js +0 -83
  170. package/es6/src/auth/auth.types.js +0 -35
  171. package/es6/src/auth/casl-authorization.service.js +0 -40
  172. package/es6/src/auth/index.js +0 -6
  173. package/es6/src/auth/principal-provider.js +0 -14
  174. package/es6/src/auth/safe-outbound-url.js +0 -99
  175. package/es6/src/auth/token-service.js +0 -141
  176. package/es6/src/builder/builder.js +0 -85
  177. package/es6/src/builder/index.js +0 -1
  178. package/es6/src/health/health.controller.js +0 -65
  179. package/es6/src/health/health.extensions.js +0 -40
  180. package/es6/src/health/index.js +0 -4
  181. package/es6/src/health/readiness.service.js +0 -57
  182. package/es6/src/health/readiness.types.js +0 -4
  183. package/es6/src/hosting/hosted-service-host.js +0 -81
  184. package/es6/src/hosting/hosted-service.js +0 -8
  185. package/es6/src/hosting/index.js +0 -2
  186. package/es6/src/http/http.compression.js +0 -9
  187. package/es6/src/http/http.extensions.js +0 -259
  188. package/es6/src/http/http.options.js +0 -16
  189. package/es6/src/http/http.options.store.js +0 -13
  190. package/es6/src/http/http.security.js +0 -9
  191. package/es6/src/http/http.static.js +0 -224
  192. package/es6/src/http/index.js +0 -5
  193. package/es6/src/openapi/index.js +0 -3
  194. package/es6/src/openapi/openapi.generator.js +0 -82
  195. package/es6/src/openapi/openapi.types.js +0 -1
  196. package/es6/src/openapi/request-schema.js +0 -160
  197. package/es6/src/openapi/request-validator.js +0 -71
  198. package/es6/src/providers/fastify.provider.js +0 -376
  199. package/es6/src/providers/index.js +0 -1
  200. package/es6/src/routing/anvil.types.js +0 -57
  201. package/es6/src/routing/decorators/argument.decorator.js +0 -28
  202. package/es6/src/routing/decorators/auth.decorator.js +0 -58
  203. package/es6/src/routing/decorators/controller.decorator.js +0 -6
  204. package/es6/src/routing/decorators/field.decorator.js +0 -15
  205. package/es6/src/routing/decorators/index.js +0 -7
  206. package/es6/src/routing/decorators/request.decorator.js +0 -24
  207. package/es6/src/routing/decorators/response.decorator.js +0 -16
  208. package/es6/src/routing/decorators/route.decorator.js +0 -37
  209. package/es6/src/routing/filters/exception-filter-host.js +0 -127
  210. package/es6/src/routing/filters/exception-filter.js +0 -10
  211. package/es6/src/routing/index.js +0 -8
  212. package/es6/src/routing/middleware/http-access-log.middleware.js +0 -37
  213. package/es6/src/routing/middleware/middleware.js +0 -10
  214. package/es6/src/routing/middleware/request-id.js +0 -14
  215. package/es6/src/routing/path.util.js +0 -33
  216. package/es6/src/routing/pipes/index.js +0 -1
  217. package/es6/src/routing/pipes/pipes.js +0 -118
  218. package/es6/src/routing/services/index.js +0 -1
  219. package/es6/src/routing/services/route-argument-resolver.js +0 -67
  220. package/es6/src/routing/services/route-registry.js +0 -184
  221. package/es6/src/routing/services/router.js +0 -148
  222. package/es6/src/sse/index.js +0 -2
  223. package/es6/src/sse/sse.decorator.js +0 -31
  224. package/es6/src/sse/sse.encoder.js +0 -67
  225. package/es6/src/sse/sse.types.js +0 -22
  226. package/es6/src/sse/sse.wire.js +0 -30
  227. package/es6/src/testing/boot-module.js +0 -35
  228. package/es6/src/testing/index.js +0 -2
  229. package/es6/src/testing/sse-reader.js +0 -91
  230. package/types/src/app/app.d.ts +0 -41
  231. package/types/src/app/module.d.ts +0 -15
  232. package/types/src/auth/ability.d.ts +0 -19
  233. package/types/src/auth/auth.config.d.ts +0 -28
  234. package/types/src/auth/auth.extensions.d.ts +0 -53
  235. package/types/src/auth/auth.types.d.ts +0 -73
  236. package/types/src/auth/casl-authorization.service.d.ts +0 -28
  237. package/types/src/auth/safe-outbound-url.d.ts +0 -9
  238. package/types/src/auth/token-service.d.ts +0 -31
  239. package/types/src/builder/builder.d.ts +0 -36
  240. package/types/src/const.d.ts +0 -32
  241. package/types/src/health/health.controller.d.ts +0 -16
  242. package/types/src/health/health.extensions.d.ts +0 -31
  243. package/types/src/health/readiness.service.d.ts +0 -9
  244. package/types/src/hosting/hosted-service-host.d.ts +0 -37
  245. package/types/src/hosting/hosted-service.d.ts +0 -31
  246. package/types/src/http/http.compression.d.ts +0 -32
  247. package/types/src/http/http.extensions.d.ts +0 -79
  248. package/types/src/http/http.options.d.ts +0 -39
  249. package/types/src/http/http.static.d.ts +0 -160
  250. package/types/src/index.d.ts +0 -10
  251. package/types/src/openapi/index.d.ts +0 -6
  252. package/types/src/openapi/openapi.generator.d.ts +0 -6
  253. package/types/src/openapi/openapi.types.d.ts +0 -58
  254. package/types/src/openapi/request-schema.d.ts +0 -21
  255. package/types/src/openapi/request-validator.d.ts +0 -9
  256. package/types/src/providers/fastify.provider.d.ts +0 -56
  257. package/types/src/routing/anvil.types.d.ts +0 -119
  258. package/types/src/routing/decorators/argument.decorator.d.ts +0 -11
  259. package/types/src/routing/decorators/auth.decorator.d.ts +0 -30
  260. package/types/src/routing/decorators/controller.decorator.d.ts +0 -3
  261. package/types/src/routing/decorators/field.decorator.d.ts +0 -2
  262. package/types/src/routing/decorators/request.decorator.d.ts +0 -8
  263. package/types/src/routing/decorators/response.decorator.d.ts +0 -4
  264. package/types/src/routing/decorators/route.decorator.d.ts +0 -7
  265. package/types/src/routing/filters/exception-filter-host.d.ts +0 -19
  266. package/types/src/routing/filters/exception-filter.d.ts +0 -16
  267. package/types/src/routing/middleware/http-access-log.middleware.d.ts +0 -8
  268. package/types/src/routing/middleware/middleware.d.ts +0 -10
  269. package/types/src/routing/middleware/request-id.d.ts +0 -6
  270. package/types/src/routing/path.util.d.ts +0 -9
  271. package/types/src/routing/pipes/pipes.d.ts +0 -21
  272. package/types/src/routing/services/route-argument-resolver.d.ts +0 -10
  273. package/types/src/routing/services/route-registry.d.ts +0 -20
  274. package/types/src/routing/services/router.d.ts +0 -22
  275. package/types/src/sse/sse.decorator.d.ts +0 -17
  276. package/types/src/sse/sse.encoder.d.ts +0 -16
  277. package/types/src/sse/sse.types.d.ts +0 -37
  278. package/types/src/sse/sse.wire.d.ts +0 -9
  279. package/types/src/testing/boot-module.d.ts +0 -34
  280. package/types/src/testing/sse-reader.d.ts +0 -29
  281. /package/{types/src/app/index.d.ts → src/app/index.ts} +0 -0
  282. /package/{types/src/auth/index.d.ts → src/auth/index.ts} +0 -0
  283. /package/{types/src/builder/index.d.ts → src/builder/index.ts} +0 -0
  284. /package/{types/src/health/index.d.ts → src/health/index.ts} +0 -0
  285. /package/{types/src/hosting/index.d.ts → src/hosting/index.ts} +0 -0
  286. /package/{types/src/http/index.d.ts → src/http/index.ts} +0 -0
  287. /package/{types/src/providers/index.d.ts → src/providers/index.ts} +0 -0
  288. /package/{types/src/routing/decorators/index.d.ts → src/routing/decorators/index.ts} +0 -0
  289. /package/{types/src/routing/index.d.ts → src/routing/index.ts} +0 -0
  290. /package/{types/src/routing/pipes/index.d.ts → src/routing/pipes/index.ts} +0 -0
  291. /package/{types/src/routing/services/index.d.ts → src/routing/services/index.ts} +0 -0
  292. /package/{types/src/sse/index.d.ts → src/sse/index.ts} +0 -0
  293. /package/{types/src/testing/index.d.ts → src/testing/index.ts} +0 -0
@@ -1,45 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", {
3
- value: true
4
- });
5
- function _export(target, all) {
6
- for(var name in all)Object.defineProperty(target, name, {
7
- enumerable: true,
8
- get: Object.getOwnPropertyDescriptor(all, name).get
9
- });
10
- }
11
- _export(exports, {
12
- get ValidationError () {
13
- return _requestvalidator.ValidationError;
14
- },
15
- get buildRouteRequestSchemas () {
16
- return _requestschema.buildRouteRequestSchemas;
17
- },
18
- get generateOpenApiDocument () {
19
- return _openapigenerator.generateOpenApiDocument;
20
- },
21
- get mergeObjectSchemas () {
22
- return _requestschema.mergeObjectSchemas;
23
- },
24
- get objectArgToParts () {
25
- return _requestschema.objectArgToParts;
26
- },
27
- get pathParamsToSchema () {
28
- return _requestschema.pathParamsToSchema;
29
- },
30
- get resolveOpenApiPath () {
31
- return _openapigenerator.resolveOpenApiPath;
32
- },
33
- get toOpenApiPath () {
34
- return _openapigenerator.toOpenApiPath;
35
- },
36
- get typeToSchema () {
37
- return _requestschema.typeToSchema;
38
- },
39
- get validateRequest () {
40
- return _requestvalidator.validateRequest;
41
- }
42
- });
43
- const _openapigenerator = require("./openapi.generator.js");
44
- const _requestschema = require("./request-schema.js");
45
- const _requestvalidator = require("./request-validator.js");
@@ -1,103 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", {
3
- value: true
4
- });
5
- function _export(target, all) {
6
- for(var name in all)Object.defineProperty(target, name, {
7
- enumerable: true,
8
- get: Object.getOwnPropertyDescriptor(all, name).get
9
- });
10
- }
11
- _export(exports, {
12
- get generateOpenApiDocument () {
13
- return generateOpenApiDocument;
14
- },
15
- get resolveOpenApiPath () {
16
- return resolveOpenApiPath;
17
- },
18
- get toOpenApiPath () {
19
- return toOpenApiPath;
20
- }
21
- });
22
- const _requestschema = require("./request-schema.js");
23
- const DEFAULT_SPEC_PATH = "/openapi.json";
24
- function resolveOpenApiPath(options) {
25
- const path = options.path?.trim() || DEFAULT_SPEC_PATH;
26
- return path.startsWith("/") ? path : `/${path}`;
27
- }
28
- function toOpenApiPath(fastifyPath) {
29
- return fastifyPath.replace(/:([A-Za-z_][\w]*)/g, "{$1}");
30
- }
31
- function generateOpenApiDocument(registry, options) {
32
- const paths = {};
33
- for (const route of registry.routes){
34
- const path = toOpenApiPath(route.path);
35
- const method = route.method.toLowerCase();
36
- let pathItem = paths[path];
37
- if (pathItem == null) {
38
- pathItem = {};
39
- paths[path] = pathItem;
40
- }
41
- pathItem[method] = buildOperation(route);
42
- }
43
- const document = {
44
- openapi: "3.0.3",
45
- info: options.info,
46
- paths
47
- };
48
- if (options.servers?.length) {
49
- document.servers = options.servers;
50
- }
51
- return document;
52
- }
53
- function buildOperation(route) {
54
- const { queryParams, pathParams, body: bodySchema } = (0, _requestschema.buildRouteRequestSchemas)(route);
55
- const parameters = [
56
- ...queryParams,
57
- ...pathParams
58
- ];
59
- const status = String(route.httpCode ?? 200);
60
- const operation = {
61
- operationId: `${route.controller.name}.${route.handler}`,
62
- tags: [
63
- route.controller.name
64
- ],
65
- responses: {
66
- [status]: route.sse ? {
67
- description: "Server-sent event stream",
68
- content: {
69
- "text/event-stream": {
70
- schema: {
71
- type: "string"
72
- }
73
- }
74
- }
75
- } : {
76
- description: "Successful response"
77
- }
78
- }
79
- };
80
- if (route.routeArgs?.some((arg)=>arg.argumentLocation === "lastEventId")) {
81
- parameters.push({
82
- name: "Last-Event-ID",
83
- in: "header",
84
- schema: {
85
- type: "string"
86
- }
87
- });
88
- }
89
- if (parameters.length > 0) {
90
- operation.parameters = parameters;
91
- }
92
- if (bodySchema != null) {
93
- operation.requestBody = {
94
- required: true,
95
- content: {
96
- "application/json": {
97
- schema: bodySchema
98
- }
99
- }
100
- };
101
- }
102
- return operation;
103
- }
@@ -1,4 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", {
3
- value: true
4
- });
@@ -1,187 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", {
3
- value: true
4
- });
5
- function _export(target, all) {
6
- for(var name in all)Object.defineProperty(target, name, {
7
- enumerable: true,
8
- get: Object.getOwnPropertyDescriptor(all, name).get
9
- });
10
- }
11
- _export(exports, {
12
- get buildRouteRequestSchemas () {
13
- return buildRouteRequestSchemas;
14
- },
15
- get mergeObjectSchemas () {
16
- return mergeObjectSchemas;
17
- },
18
- get objectArgToParts () {
19
- return objectArgToParts;
20
- },
21
- get pathParamsToSchema () {
22
- return pathParamsToSchema;
23
- },
24
- get typeToSchema () {
25
- return typeToSchema;
26
- }
27
- });
28
- const _reflection = require("@decohere/core/reflection");
29
- const _anviltypes = require("../routing/anvil.types.js");
30
- function buildRouteRequestSchemas(route) {
31
- const queryParams = [];
32
- const pathParams = [];
33
- let bodySchema;
34
- for (const routeArg of route.routeArgs ?? []){
35
- if (routeArg.argumentLocation != null && _anviltypes.InjectedParts.includes(routeArg.argumentLocation)) {
36
- continue;
37
- }
38
- if ((0, _reflection.isPrimitiveOrDateType)(routeArg.argumentType)) {
39
- const location = routeArg.argumentLocation;
40
- if (location === "query" || location === "params") {
41
- const param = {
42
- name: routeArg.mappingKey ?? "value",
43
- in: location === "params" ? "path" : "query",
44
- required: location === "params",
45
- schema: typeToSchema(routeArg.argumentType.name)
46
- };
47
- if (location === "params") {
48
- pathParams.push(param);
49
- } else {
50
- queryParams.push(param);
51
- }
52
- }
53
- continue;
54
- }
55
- const parts = objectArgToParts(routeArg);
56
- queryParams.push(...parts.queryParams);
57
- pathParams.push(...parts.pathParams);
58
- if (parts.body != null) {
59
- bodySchema = mergeObjectSchemas(bodySchema, parts.body);
60
- }
61
- }
62
- return {
63
- queryParams,
64
- pathParams,
65
- body: bodySchema
66
- };
67
- }
68
- function objectArgToParts(routeArg) {
69
- const queryParams = [];
70
- const pathParams = [];
71
- const bodyProperties = {};
72
- const bodyRequired = [];
73
- const argLocation = routeArg.argumentLocation;
74
- for (const [, meta] of routeArg.fieldMap?.entries() ?? []){
75
- const location = meta.fieldLocation ?? argLocation;
76
- const name = meta.mappingKey || meta.fieldKey;
77
- const schema = typeToSchema(meta.fieldType?.name);
78
- if (location === "query") {
79
- queryParams.push({
80
- name,
81
- in: "query",
82
- required: false,
83
- schema
84
- });
85
- } else if (location === "params") {
86
- pathParams.push({
87
- name,
88
- in: "path",
89
- required: true,
90
- schema
91
- });
92
- } else if (location === "body" || location == null && argLocation === "body") {
93
- bodyProperties[name] = schema;
94
- bodyRequired.push(name);
95
- } else if (location == null && argLocation == null) {
96
- // Unlocated object fields default to body for OpenAPI (common DTO pattern).
97
- bodyProperties[name] = schema;
98
- bodyRequired.push(name);
99
- }
100
- }
101
- // Whole-object body argument with no fields still advertises an object body.
102
- if (argLocation === "body" && Object.keys(bodyProperties).length === 0) {
103
- return {
104
- queryParams,
105
- pathParams,
106
- body: {
107
- type: "object",
108
- additionalProperties: true
109
- }
110
- };
111
- }
112
- const body = Object.keys(bodyProperties).length > 0 ? {
113
- type: "object",
114
- properties: bodyProperties,
115
- required: bodyRequired,
116
- additionalProperties: false
117
- } : undefined;
118
- return {
119
- queryParams,
120
- pathParams,
121
- body
122
- };
123
- }
124
- function mergeObjectSchemas(a, b) {
125
- if (a == null) {
126
- return b;
127
- }
128
- return {
129
- type: "object",
130
- properties: {
131
- ...a.properties,
132
- ...b.properties
133
- },
134
- required: [
135
- ...new Set([
136
- ...a.required ?? [],
137
- ...b.required ?? []
138
- ])
139
- ],
140
- additionalProperties: false
141
- };
142
- }
143
- function typeToSchema(typeName) {
144
- switch(typeName){
145
- case "Number":
146
- return {
147
- type: "number"
148
- };
149
- case "Boolean":
150
- return {
151
- type: "boolean"
152
- };
153
- case "Date":
154
- return {
155
- type: "string",
156
- format: "date-time"
157
- };
158
- case "String":
159
- return {
160
- type: "string"
161
- };
162
- default:
163
- return {};
164
- }
165
- }
166
- function pathParamsToSchema(params) {
167
- if (params.length === 0) {
168
- return undefined;
169
- }
170
- const properties = {};
171
- const required = [];
172
- for (const param of params){
173
- properties[param.name] = {
174
- type: "string",
175
- minLength: 1
176
- };
177
- if (param.required !== false) {
178
- required.push(param.name);
179
- }
180
- }
181
- return {
182
- type: "object",
183
- properties,
184
- required,
185
- additionalProperties: true
186
- };
187
- }
@@ -1,85 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", {
3
- value: true
4
- });
5
- function _export(target, all) {
6
- for(var name in all)Object.defineProperty(target, name, {
7
- enumerable: true,
8
- get: Object.getOwnPropertyDescriptor(all, name).get
9
- });
10
- }
11
- _export(exports, {
12
- get ValidationError () {
13
- return _anviltypes.ValidationError;
14
- },
15
- get validateRequest () {
16
- return validateRequest;
17
- }
18
- });
19
- const _ajv = require("ajv");
20
- const _anviltypes = require("../routing/anvil.types.js");
21
- const _requestschema = require("./request-schema.js");
22
- function validateRequest(route, request) {
23
- const { params, body } = getValidators(route);
24
- const issues = [];
25
- if (params != null) {
26
- collectIssues(params, request.params ?? {}, "/params", issues);
27
- }
28
- if (body != null) {
29
- collectIssues(body, request.body, "/body", issues);
30
- }
31
- if (issues.length > 0) {
32
- throw new _anviltypes.ValidationError("Validation failed", issues);
33
- }
34
- }
35
- const ajv = new _ajv.Ajv({
36
- allErrors: true,
37
- coerceTypes: false,
38
- removeAdditional: false,
39
- useDefaults: false,
40
- strict: false
41
- });
42
- /**
43
- * Compiled once per route and reused. Compiling per request was slow, and AJV keeps every
44
- * schema it compiles, so memory grew with traffic.
45
- */ const validatorsByRoute = new WeakMap();
46
- function getValidators(route) {
47
- let validators = validatorsByRoute.get(route);
48
- if (validators == null) {
49
- const schemas = (0, _requestschema.buildRouteRequestSchemas)(route);
50
- const paramsSchema = (0, _requestschema.pathParamsToSchema)(schemas.pathParams);
51
- validators = {
52
- params: paramsSchema != null ? ajv.compile(paramsSchema) : undefined,
53
- body: schemas.body != null ? ajv.compile(schemas.body) : undefined
54
- };
55
- validatorsByRoute.set(route, validators);
56
- }
57
- return validators;
58
- }
59
- function collectIssues(validate, data, rootPath, issues) {
60
- if (validate(data)) {
61
- return;
62
- }
63
- for (const err of validate.errors ?? []){
64
- issues.push(toIssue(err, rootPath));
65
- }
66
- }
67
- function toIssue(err, rootPath) {
68
- const instance = err.instancePath ?? "";
69
- const path = instance.length > 0 ? `${rootPath}${instance}` : rootPath;
70
- const message = err.message ?? "is invalid";
71
- return {
72
- path,
73
- message: formatAjvMessage(err, message),
74
- keyword: err.keyword
75
- };
76
- }
77
- function formatAjvMessage(err, fallback) {
78
- if (err.keyword === "required" && typeof err.params?.missingProperty === "string") {
79
- return `must have required property '${err.params.missingProperty}'`;
80
- }
81
- if (err.keyword === "additionalProperties" && typeof err.params?.additionalProperty === "string") {
82
- return `must NOT have additional property '${err.params.additionalProperty}'`;
83
- }
84
- return fallback;
85
- }