@ddd-ts-kit/http 0.8.0 → 0.10.0

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 (100) hide show
  1. package/README.md +65 -2
  2. package/dist/controller/controller-request.d.ts +7 -1
  3. package/dist/controller/controller-request.d.ts.map +1 -1
  4. package/dist/controller/controller-routes.js +1 -0
  5. package/dist/controller/controller-routes.js.map +1 -1
  6. package/dist/controller/controller-spec.d.ts +7 -0
  7. package/dist/controller/controller-spec.d.ts.map +1 -1
  8. package/dist/controller/http-request.d.ts +9 -3
  9. package/dist/controller/http-request.d.ts.map +1 -1
  10. package/dist/error/default-error-mapping.d.ts.map +1 -1
  11. package/dist/error/default-error-mapping.js +3 -0
  12. package/dist/error/default-error-mapping.js.map +1 -1
  13. package/dist/express/mount-express.d.ts +2 -0
  14. package/dist/express/mount-express.d.ts.map +1 -1
  15. package/dist/express/mount-express.js +9 -1
  16. package/dist/express/mount-express.js.map +1 -1
  17. package/dist/fastify/mount-fastify.d.ts +5 -1
  18. package/dist/fastify/mount-fastify.d.ts.map +1 -1
  19. package/dist/fastify/mount-fastify.js +26 -3
  20. package/dist/fastify/mount-fastify.js.map +1 -1
  21. package/dist/files/signed-file-routes-options.d.ts +5 -0
  22. package/dist/files/signed-file-routes-options.d.ts.map +1 -0
  23. package/dist/files/signed-file-routes-options.js +2 -0
  24. package/dist/files/signed-file-routes-options.js.map +1 -0
  25. package/dist/files/signed-file-routes.d.ts +14 -0
  26. package/dist/files/signed-file-routes.d.ts.map +1 -0
  27. package/dist/files/signed-file-routes.js +69 -0
  28. package/dist/files/signed-file-routes.js.map +1 -0
  29. package/dist/index.d.ts +6 -0
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +1 -0
  32. package/dist/index.js.map +1 -1
  33. package/dist/openapi/path-items.d.ts.map +1 -1
  34. package/dist/openapi/path-items.js +6 -8
  35. package/dist/openapi/path-items.js.map +1 -1
  36. package/dist/openapi/request-body.d.ts +6 -0
  37. package/dist/openapi/request-body.d.ts.map +1 -0
  38. package/dist/openapi/request-body.js +36 -0
  39. package/dist/openapi/request-body.js.map +1 -0
  40. package/dist/openapi/responses.d.ts.map +1 -1
  41. package/dist/openapi/responses.js +4 -1
  42. package/dist/openapi/responses.js.map +1 -1
  43. package/dist/pipeline/execute-options.d.ts +3 -0
  44. package/dist/pipeline/execute-options.d.ts.map +1 -1
  45. package/dist/pipeline/execute-route.d.ts.map +1 -1
  46. package/dist/pipeline/execute-route.js +9 -3
  47. package/dist/pipeline/execute-route.js.map +1 -1
  48. package/dist/pipeline/raw-request.d.ts +3 -0
  49. package/dist/pipeline/raw-request.d.ts.map +1 -1
  50. package/dist/pipeline/receive-upload.d.ts +12 -0
  51. package/dist/pipeline/receive-upload.d.ts.map +1 -0
  52. package/dist/pipeline/receive-upload.js +12 -0
  53. package/dist/pipeline/receive-upload.js.map +1 -0
  54. package/dist/pipeline/received-upload.d.ts +7 -0
  55. package/dist/pipeline/received-upload.d.ts.map +1 -0
  56. package/dist/pipeline/received-upload.js +2 -0
  57. package/dist/pipeline/received-upload.js.map +1 -0
  58. package/dist/pipeline/upload-reader.d.ts +9 -0
  59. package/dist/pipeline/upload-reader.d.ts.map +1 -0
  60. package/dist/pipeline/upload-reader.js +2 -0
  61. package/dist/pipeline/upload-reader.js.map +1 -0
  62. package/dist/route/header-of.d.ts +4 -0
  63. package/dist/route/header-of.d.ts.map +1 -0
  64. package/dist/route/header-of.js +6 -0
  65. package/dist/route/header-of.js.map +1 -0
  66. package/dist/route/incoming-file.d.ts +7 -0
  67. package/dist/route/incoming-file.d.ts.map +1 -0
  68. package/dist/route/incoming-file.js +2 -0
  69. package/dist/route/incoming-file.js.map +1 -0
  70. package/dist/route/request-context.d.ts +3 -0
  71. package/dist/route/request-context.d.ts.map +1 -1
  72. package/dist/route/route-input.d.ts +3 -0
  73. package/dist/route/route-input.d.ts.map +1 -1
  74. package/dist/route/route-spec.d.ts +5 -0
  75. package/dist/route/route-spec.d.ts.map +1 -1
  76. package/dist/route/upload-spec.d.ts +12 -0
  77. package/dist/route/upload-spec.d.ts.map +1 -0
  78. package/dist/route/upload-spec.js +2 -0
  79. package/dist/route/upload-spec.js.map +1 -0
  80. package/dist/uploads/missing-file.d.ts +4 -0
  81. package/dist/uploads/missing-file.d.ts.map +1 -0
  82. package/dist/uploads/missing-file.js +6 -0
  83. package/dist/uploads/missing-file.js.map +1 -0
  84. package/dist/uploads/multipart-limits.d.ts +7 -0
  85. package/dist/uploads/multipart-limits.d.ts.map +1 -0
  86. package/dist/uploads/multipart-limits.js +2 -0
  87. package/dist/uploads/multipart-limits.js.map +1 -0
  88. package/dist/uploads/multipart-uploads.d.ts +8 -0
  89. package/dist/uploads/multipart-uploads.d.ts.map +1 -0
  90. package/dist/uploads/multipart-uploads.js +9 -0
  91. package/dist/uploads/multipart-uploads.js.map +1 -0
  92. package/dist/uploads/read-multipart.d.ts +13 -0
  93. package/dist/uploads/read-multipart.d.ts.map +1 -0
  94. package/dist/uploads/read-multipart.js +65 -0
  95. package/dist/uploads/read-multipart.js.map +1 -0
  96. package/dist/uploads.d.ts +3 -0
  97. package/dist/uploads.d.ts.map +1 -0
  98. package/dist/uploads.js +2 -0
  99. package/dist/uploads.js.map +1 -0
  100. package/package.json +14 -4
@@ -0,0 +1,6 @@
1
+ import type { JsonSchema } from '@ddd-ts-kit/validation';
2
+ import type { Route } from '../route/route.js';
3
+ import type { Definitions } from './definitions.js';
4
+ /** The request body of an operation: JSON, or for an upload the multipart form with its file, its size and its media types. */
5
+ export declare function requestBody(route: Route, definitions: Definitions): JsonSchema | undefined;
6
+ //# sourceMappingURL=request-body.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-body.d.ts","sourceRoot":"","sources":["../../src/openapi/request-body.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD,+HAA+H;AAC/H,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,WAAW,GAAG,UAAU,GAAG,SAAS,CAS1F"}
@@ -0,0 +1,36 @@
1
+ /** The request body of an operation: JSON, or for an upload the multipart form with its file, its size and its media types. */
2
+ export function requestBody(route, definitions) {
3
+ const body = route.request?.body;
4
+ const fields = body === undefined ? undefined : definitions.embed(body);
5
+ if (route.upload !== undefined) {
6
+ return multipartBody(route.upload, fields);
7
+ }
8
+ return fields === undefined ? undefined : { required: true, content: { 'application/json': { schema: fields } } };
9
+ }
10
+ function multipartBody(upload, fields) {
11
+ const types = upload.mediaTypes.join(', ');
12
+ const file = {
13
+ type: 'object',
14
+ properties: {
15
+ [upload.field]: {
16
+ type: 'string',
17
+ contentMediaType: 'application/octet-stream',
18
+ description: `The file: ${types}, at most ${String(upload.maxBytes)} bytes, its type checked on its content.`,
19
+ 'x-max-bytes': upload.maxBytes,
20
+ 'x-media-types': [...upload.mediaTypes],
21
+ },
22
+ },
23
+ required: [upload.field],
24
+ };
25
+ return {
26
+ required: true,
27
+ description: 'Text fields first, then the file: a field sent after the file is not read.',
28
+ content: {
29
+ 'multipart/form-data': {
30
+ schema: fields === undefined ? file : { allOf: [fields, file] },
31
+ encoding: { [upload.field]: { contentType: types } },
32
+ },
33
+ },
34
+ };
35
+ }
36
+ //# sourceMappingURL=request-body.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-body.js","sourceRoot":"","sources":["../../src/openapi/request-body.ts"],"names":[],"mappings":"AAKA,+HAA+H;AAC/H,MAAM,UAAU,WAAW,CAAC,KAAY,EAAE,WAAwB;IAChE,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC;IACjC,MAAM,MAAM,GAAG,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAExE,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC/B,OAAO,aAAa,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7C,CAAC;IAED,OAAO,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,kBAAkB,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;AACpH,CAAC;AAED,SAAS,aAAa,CAAC,MAAkB,EAAE,MAA8B;IACvE,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAE3C,MAAM,IAAI,GAAG;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;gBACd,IAAI,EAAE,QAAQ;gBACd,gBAAgB,EAAE,0BAA0B;gBAC5C,WAAW,EAAE,aAAa,KAAK,aAAa,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,0CAA0C;gBAC7G,aAAa,EAAE,MAAM,CAAC,QAAQ;gBAC9B,eAAe,EAAE,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC;aACxC;SACF;QACD,QAAQ,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC;KACzB,CAAC;IAEF,OAAO;QACL,QAAQ,EAAE,IAAI;QACd,WAAW,EAAE,4EAA4E;QACzF,OAAO,EAAE;YACP,qBAAqB,EAAE;gBACrB,MAAM,EAAE,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE;gBAC/D,QAAQ,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,EAAE;aACrD;SACF;KACF,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"responses.d.ts","sourceRoot":"","sources":["../../src/openapi/responses.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAG5D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAG/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAKpD,gGAAgG;AAChG,wBAAgB,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,GAAG,UAAU,CAUjG"}
1
+ {"version":3,"file":"responses.d.ts","sourceRoot":"","sources":["../../src/openapi/responses.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAG5D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAG/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAOpD,gGAAgG;AAChG,wBAAgB,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,GAAG,UAAU,CAUjG"}
@@ -2,6 +2,8 @@ import { statusTitle } from '../error/status-title.js';
2
2
  import { isRecord } from '../support/is-record.js';
3
3
  import { compare } from './compare.js';
4
4
  const VALIDATION_FAILED = 'VALIDATION_FAILED';
5
+ /** What a route that declares an upload may answer besides its own codes: a file too large, of another type, or missing. */
6
+ const UPLOAD_REFUSALS = ['FILE_TOO_LARGE', 'UNSUPPORTED_MEDIA_TYPE', VALIDATION_FAILED];
5
7
  const PROBLEM_REF = { $ref: '#/components/schemas/Problem' };
6
8
  /** The declared responses, plus one problem response per status of the declared error codes. */
7
9
  export function responses(route, mapper, definitions) {
@@ -28,7 +30,8 @@ function declaredResponses(route, definitions) {
28
30
  }
29
31
  function errorCodesByStatus(route, mapper) {
30
32
  const validatesInput = Object.values(route.request ?? {}).some((schema) => schema !== undefined);
31
- const codes = new Set([...(route.errors ?? []), ...(validatesInput ? [VALIDATION_FAILED] : [])]);
33
+ const uploads = route.upload === undefined ? [] : UPLOAD_REFUSALS;
34
+ const codes = new Set([...(route.errors ?? []), ...(validatesInput ? [VALIDATION_FAILED] : []), ...uploads]);
32
35
  const codesByStatus = new Map();
33
36
  for (const code of codes) {
34
37
  const status = mapper.statusOf(code);
@@ -1 +1 @@
1
- {"version":3,"file":"responses.js","sourceRoot":"","sources":["../../src/openapi/responses.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"responses.js","sourceRoot":"","sources":["../../src/openapi/responses.ts"],"names":[],"mappings":"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"}
@@ -5,6 +5,7 @@ import type { ErrorContext } from './error-context.js';
5
5
  import type { GuardRefusal } from './guard-refusal.js';
6
6
  import type { RawRequest } from './raw-request.js';
7
7
  import type { RouteAround } from './route-around.js';
8
+ import type { UploadReader } from './upload-reader.js';
8
9
  export interface ExecuteOptions {
9
10
  readonly errorMapper?: ErrorMapper;
10
11
  /** Authenticates the request; throw `UnauthorizedError` to refuse it. */
@@ -52,5 +53,7 @@ export interface ExecuteOptions {
52
53
  * `@ddd-ts-kit/tracing` fits as it is.
53
54
  */
54
55
  readonly around?: RouteAround;
56
+ /** Reads the file of the routes that declare an upload: `multipartUploads()` of `@ddd-ts-kit/http/uploads`. */
57
+ readonly uploads?: UploadReader;
55
58
  }
56
59
  //# sourceMappingURL=execute-options.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"execute-options.d.ts","sourceRoot":"","sources":["../../src/pipeline/execute-options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,CAAC;IACnC,yEAAyE;IACzE,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC;IACtD;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;IACvF,wFAAwF;IACxF,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,KAAK,IAAI,CAAC;IACnE;;;;;OAKG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1E,2EAA2E;IAC3E,QAAQ,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IACrC,0FAA0F;IAC1F,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,UAAU,KAAK,MAAM,CAAC;IACrD;;;OAGG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,cAAc,CAAC;IACzC;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,cAAc,CAAC;IACxC;;;OAGG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,8FAA8F;IAC9F,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;IACvB;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;CAC/B"}
1
+ {"version":3,"file":"execute-options.d.ts","sourceRoot":"","sources":["../../src/pipeline/execute-options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,CAAC;IACnC,yEAAyE;IACzE,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC;IACtD;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;IACvF,wFAAwF;IACxF,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,KAAK,IAAI,CAAC;IACnE;;;;;OAKG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1E,2EAA2E;IAC3E,QAAQ,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IACrC,0FAA0F;IAC1F,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,UAAU,KAAK,MAAM,CAAC;IACrD;;;OAGG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,cAAc,CAAC;IACzC;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,cAAc,CAAC;IACxC;;;OAGG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,8FAA8F;IAC9F,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;IACvB;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B,+GAA+G;IAC/G,QAAQ,CAAC,OAAO,CAAC,EAAE,YAAY,CAAC;CACjC"}
@@ -1 +1 @@
1
- {"version":3,"file":"execute-route.d.ts","sourceRoot":"","sources":["../../src/pipeline/execute-route.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAK/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAoBzD,wBAAsB,YAAY,CAChC,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,UAAU,EACnB,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,aAAa,CAAC,CAOxB"}
1
+ {"version":3,"file":"execute-route.d.ts","sourceRoot":"","sources":["../../src/pipeline/execute-route.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAK/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAoBzD,wBAAsB,YAAY,CAChC,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,UAAU,EACnB,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,aAAa,CAAC,CAOxB"}
@@ -1,9 +1,11 @@
1
+ import { Readable } from 'node:stream';
1
2
  import { createErrorMapper } from '../error/create-error-mapper.js';
2
3
  import { toProblem } from '../error/to-problem.js';
3
4
  import { assertDeclaredResponse } from './assert-declared-response.js';
4
5
  import { CORRELATION_HEADER } from './correlation-header.js';
5
6
  import { correlationIdOf } from './correlation-id-of.js';
6
7
  import { executionOfRequest } from './execution-of-request.js';
8
+ import { receiveUpload } from './receive-upload.js';
7
9
  import { resolvedTenant } from '../tenancy/resolved-tenant.js';
8
10
  import { guardRefusals } from '../controller/guard-refusals.js';
9
11
  import { validateRequest } from './validate-request.js';
@@ -34,7 +36,8 @@ function defaultRequestId(request) {
34
36
  async function handled(call) {
35
37
  const { route, request, options, requestId } = call;
36
38
  const principal = await options.resolvePrincipal?.(request.raw);
37
- const input = validateRequest(route, request);
39
+ const received = await receiveUpload(route, request, options);
40
+ const input = validateRequest(route, received.request);
38
41
  const { headers } = request;
39
42
  const execution = executionOf(call, principal, input.params);
40
43
  const context = {
@@ -43,8 +46,10 @@ async function handled(call) {
43
46
  raw: request.raw,
44
47
  rawHeaders: headers,
45
48
  ...(principal === undefined ? {} : { principal }),
49
+ ...(route.rawBody === true && request.stream !== undefined ? { stream: request.stream } : {}),
46
50
  };
47
- const handle = async () => route.handle({ ...input, context });
51
+ const upload = received.upload === undefined ? {} : { upload: received.upload };
52
+ const handle = async () => route.handle({ ...input, ...upload, context });
48
53
  const asPrincipal = () => options.withPrincipal?.(principal, handle) ?? handle();
49
54
  const result = await (options.executionScope?.run(execution, asPrincipal) ?? asPrincipal());
50
55
  if (options.validateResponses === true) {
@@ -86,7 +91,8 @@ function defaultContentType(body) {
86
91
  if (body === undefined) {
87
92
  return {};
88
93
  }
89
- return { 'content-type': body instanceof Uint8Array ? 'application/octet-stream' : JSON_CONTENT_TYPE };
94
+ const binary = body instanceof Uint8Array || body instanceof Readable;
95
+ return { 'content-type': binary ? 'application/octet-stream' : JSON_CONTENT_TYPE };
90
96
  }
91
97
  function lowerCaseKeys(headers) {
92
98
  return Object.fromEntries(Object.entries(headers).map(([name, value]) => [name.toLowerCase(), value]));
@@ -1 +1 @@
1
- {"version":3,"file":"execute-route.js","sourceRoot":"","sources":["../../src/pipeline/execute-route.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"execute-route.js","sourceRoot":"","sources":["../../src/pipeline/execute-route.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import type { Readable } from 'node:stream';
1
2
  import type { RawHeaders } from '../route/raw-headers.js';
2
3
  /** What an adapter extracts from its framework before handing over to `executeRoute`. */
3
4
  export interface RawRequest {
@@ -6,5 +7,7 @@ export interface RawRequest {
6
7
  readonly headers: RawHeaders;
7
8
  readonly body: unknown;
8
9
  readonly raw: unknown;
10
+ /** The body as it arrives, which an upload and a raw body are read from. */
11
+ readonly stream?: Readable;
9
12
  }
10
13
  //# sourceMappingURL=raw-request.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"raw-request.d.ts","sourceRoot":"","sources":["../../src/pipeline/raw-request.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAE1D,yFAAyF;AACzF,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;CACvB"}
1
+ {"version":3,"file":"raw-request.d.ts","sourceRoot":"","sources":["../../src/pipeline/raw-request.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAE1D,yFAAyF;AACzF,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACtB,4EAA4E;IAC5E,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC;CAC5B"}
@@ -0,0 +1,12 @@
1
+ import type { IncomingFile } from '../route/incoming-file.js';
2
+ import type { Route } from '../route/route.js';
3
+ import type { ExecuteOptions } from './execute-options.js';
4
+ import type { RawRequest } from './raw-request.js';
5
+ interface Received {
6
+ readonly request: RawRequest;
7
+ readonly upload?: IncomingFile;
8
+ }
9
+ /** For a route that declares an upload: its text fields become the body, its file the `upload` of the input. */
10
+ export declare function receiveUpload(route: Route, request: RawRequest, options: ExecuteOptions): Promise<Received>;
11
+ export {};
12
+ //# sourceMappingURL=receive-upload.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"receive-upload.d.ts","sourceRoot":"","sources":["../../src/pipeline/receive-upload.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,UAAU,QAAQ;IAChB,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;IAC7B,QAAQ,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC;CAChC;AAED,gHAAgH;AAChH,wBAAsB,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,QAAQ,CAAC,CAcjH"}
@@ -0,0 +1,12 @@
1
+ /** For a route that declares an upload: its text fields become the body, its file the `upload` of the input. */
2
+ export async function receiveUpload(route, request, options) {
3
+ if (route.upload === undefined) {
4
+ return { request };
5
+ }
6
+ if (options.uploads === undefined) {
7
+ throw new Error(`Route "${route.operationId}" declares an upload: mount the routes with \`uploads: multipartUploads()\` of @ddd-ts-kit/http/uploads.`);
8
+ }
9
+ const { fields, file } = await options.uploads(route.upload, request);
10
+ return { request: { ...request, body: fields }, upload: file };
11
+ }
12
+ //# sourceMappingURL=receive-upload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"receive-upload.js","sourceRoot":"","sources":["../../src/pipeline/receive-upload.ts"],"names":[],"mappings":"AAUA,gHAAgH;AAChH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,KAAY,EAAE,OAAmB,EAAE,OAAuB;IAC5F,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC/B,OAAO,EAAE,OAAO,EAAE,CAAC;IACrB,CAAC;IAED,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CACb,UAAU,KAAK,CAAC,WAAW,0GAA0G,CACtI,CAAC;IACJ,CAAC;IAED,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAEtE,OAAO,EAAE,OAAO,EAAE,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;AACjE,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { IncomingFile } from '../route/incoming-file.js';
2
+ /** What an upload reader found in a request: the text fields sent before the file, and the file. */
3
+ export interface ReceivedUpload {
4
+ readonly fields: Readonly<Record<string, string>>;
5
+ readonly file: IncomingFile;
6
+ }
7
+ //# sourceMappingURL=received-upload.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"received-upload.d.ts","sourceRoot":"","sources":["../../src/pipeline/received-upload.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAE9D,oGAAoG;AACpG,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAClD,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;CAC7B"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=received-upload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"received-upload.js","sourceRoot":"","sources":["../../src/pipeline/received-upload.ts"],"names":[],"mappings":""}
@@ -0,0 +1,9 @@
1
+ import type { UploadSpec } from '../route/upload-spec.js';
2
+ import type { RawRequest } from './raw-request.js';
3
+ import type { ReceivedUpload } from './received-upload.js';
4
+ /**
5
+ * Reads the upload a route declares out of its request, as soon as the file starts to arrive.
6
+ * `multipartUploads()` of `@ddd-ts-kit/http/uploads` is the one of the kit.
7
+ */
8
+ export type UploadReader = (spec: UploadSpec, request: RawRequest) => Promise<ReceivedUpload>;
9
+ //# sourceMappingURL=upload-reader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload-reader.d.ts","sourceRoot":"","sources":["../../src/pipeline/upload-reader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=upload-reader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload-reader.js","sourceRoot":"","sources":["../../src/pipeline/upload-reader.ts"],"names":[],"mappings":""}
@@ -0,0 +1,4 @@
1
+ import type { RawHeaders } from './raw-headers.js';
2
+ /** One header as a string, the first of a repeated one, `''` when absent. */
3
+ export declare function headerOf(headers: RawHeaders, name: string): string;
4
+ //# sourceMappingURL=header-of.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"header-of.d.ts","sourceRoot":"","sources":["../../src/route/header-of.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,6EAA6E;AAC7E,wBAAgB,QAAQ,CAAC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAIlE"}
@@ -0,0 +1,6 @@
1
+ /** One header as a string, the first of a repeated one, `''` when absent. */
2
+ export function headerOf(headers, name) {
3
+ const value = headers[name];
4
+ return (Array.isArray(value) ? value[0] : value) ?? '';
5
+ }
6
+ //# sourceMappingURL=header-of.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"header-of.js","sourceRoot":"","sources":["../../src/route/header-of.ts"],"names":[],"mappings":"AAEA,6EAA6E;AAC7E,MAAM,UAAU,QAAQ,CAAC,OAAmB,EAAE,IAAY;IACxD,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5B,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;AACzD,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { ReceivedFile } from '@ddd-ts-kit/kernel';
2
+ /**
3
+ * The file of an upload as a handler receives it: still streaming, checked on its way, the
4
+ * `ReceivedFile` of the kernel that a controller hands to its command as it is.
5
+ */
6
+ export type IncomingFile = ReceivedFile;
7
+ //# sourceMappingURL=incoming-file.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"incoming-file.d.ts","sourceRoot":"","sources":["../../src/route/incoming-file.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,YAAY,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=incoming-file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"incoming-file.js","sourceRoot":"","sources":["../../src/route/incoming-file.ts"],"names":[],"mappings":""}
@@ -1,3 +1,4 @@
1
+ import type { Readable } from 'node:stream';
1
2
  import type { ExecutionContext } from '@ddd-ts-kit/kernel';
2
3
  import type { RawHeaders } from './raw-headers.js';
3
4
  export interface RequestContext {
@@ -12,5 +13,7 @@ export interface RequestContext {
12
13
  readonly rawHeaders?: RawHeaders;
13
14
  /** The framework's own request object, for the rare case the neutral input is not enough. */
14
15
  readonly raw: unknown;
16
+ /** The body as it arrives, unparsed, for a route declared with `rawBody`. */
17
+ readonly stream?: Readable;
15
18
  }
16
19
  //# sourceMappingURL=request-context.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"request-context.d.ts","sourceRoot":"","sources":["../../src/route/request-context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;;;OAGG;IACH,QAAQ,CAAC,SAAS,EAAE,gBAAgB,CAAC;IACrC,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAC7B,yHAAyH;IACzH,QAAQ,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC;IACjC,6FAA6F;IAC7F,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;CACvB"}
1
+ {"version":3,"file":"request-context.d.ts","sourceRoot":"","sources":["../../src/route/request-context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;;;OAGG;IACH,QAAQ,CAAC,SAAS,EAAE,gBAAgB,CAAC;IACrC,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAC7B,yHAAyH;IACzH,QAAQ,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC;IACjC,6FAA6F;IAC7F,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACtB,6EAA6E;IAC7E,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC;CAC5B"}
@@ -1,3 +1,4 @@
1
+ import type { IncomingFile } from './incoming-file.js';
1
2
  import type { RequestContext } from './request-context.js';
2
3
  /** The handler input once the schema types are erased, as the pipeline sees it. */
3
4
  export interface RouteInput {
@@ -5,6 +6,8 @@ export interface RouteInput {
5
6
  readonly query: unknown;
6
7
  readonly headers: unknown;
7
8
  readonly body: unknown;
9
+ /** The file of a route that declares an upload. */
10
+ readonly upload?: IncomingFile;
8
11
  readonly context: RequestContext;
9
12
  }
10
13
  //# sourceMappingURL=route-input.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"route-input.d.ts","sourceRoot":"","sources":["../../src/route/route-input.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,mFAAmF;AACnF,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;CAClC"}
1
+ {"version":3,"file":"route-input.d.ts","sourceRoot":"","sources":["../../src/route/route-input.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,mFAAmF;AACnF,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,mDAAmD;IACnD,QAAQ,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC;IAC/B,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;CAClC"}
@@ -1,6 +1,7 @@
1
1
  import type { HttpMethod } from './http-method.js';
2
2
  import type { RequestSchemas } from './request-schemas.js';
3
3
  import type { ResponsesSpec } from './responses-spec.js';
4
+ import type { UploadSpec } from './upload-spec.js';
4
5
  export interface RouteSpec<Request extends RequestSchemas = RequestSchemas, Responses extends ResponsesSpec = ResponsesSpec> {
5
6
  readonly method: HttpMethod;
6
7
  /** Express-style path: literal segments and `:name` parameters, for example `/orders/:orderId`. */
@@ -10,6 +11,10 @@ export interface RouteSpec<Request extends RequestSchemas = RequestSchemas, Resp
10
11
  readonly description?: string;
11
12
  readonly tags?: readonly string[];
12
13
  readonly request?: Request;
14
+ /** A file received as `multipart/form-data`: the text fields are the body, the file streams to the handler. */
15
+ readonly upload?: UploadSpec;
16
+ /** The body is not parsed: the handler reads `context.stream`. For a route that receives a file as it is, such as `signedFileRoutes`. */
17
+ readonly rawBody?: boolean;
13
18
  readonly responses: Responses;
14
19
  /** Domain error codes this route may answer; they are documented in the contract. */
15
20
  readonly errors?: readonly string[];
@@ -1 +1 @@
1
- {"version":3,"file":"route-spec.d.ts","sourceRoot":"","sources":["../../src/route/route-spec.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,MAAM,WAAW,SAAS,CACxB,OAAO,SAAS,cAAc,GAAG,cAAc,EAC/C,SAAS,SAAS,aAAa,GAAG,aAAa;IAE/C,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,mGAAmG;IACnG,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,qFAAqF;IACrF,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,KAAK,CAAC;IAC7C,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;CAC/B"}
1
+ {"version":3,"file":"route-spec.d.ts","sourceRoot":"","sources":["../../src/route/route-spec.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,MAAM,WAAW,SAAS,CACxB,OAAO,SAAS,cAAc,GAAG,cAAc,EAC/C,SAAS,SAAS,aAAa,GAAG,aAAa;IAE/C,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,mGAAmG;IACnG,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,+GAA+G;IAC/G,QAAQ,CAAC,MAAM,CAAC,EAAE,UAAU,CAAC;IAC7B,yIAAyI;IACzI,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,qFAAqF;IACrF,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,KAAK,CAAC;IAC7C,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;CAC/B"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * The file a route receives, in a `multipart/form-data` request: the field that carries it, the
3
+ * most it may weigh and the media types it may be. All three are part of the contract (the
4
+ * OpenAPI document states them) and are enforced while the content streams.
5
+ */
6
+ export interface UploadSpec {
7
+ readonly field: string;
8
+ readonly maxBytes: number;
9
+ /** Exact types or families (`image/*`), verified on the first bytes of the content, never on the file name. */
10
+ readonly mediaTypes: readonly string[];
11
+ }
12
+ //# sourceMappingURL=upload-spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload-spec.d.ts","sourceRoot":"","sources":["../../src/route/upload-spec.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,+GAA+G;IAC/G,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;CACxC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=upload-spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload-spec.js","sourceRoot":"","sources":["../../src/route/upload-spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,4 @@
1
+ import { ValidationError } from '@ddd-ts-kit/validation';
2
+ /** The refusal of a multipart request without the file its route declares. */
3
+ export declare function missingFile(field: string): ValidationError;
4
+ //# sourceMappingURL=missing-file.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"missing-file.d.ts","sourceRoot":"","sources":["../../src/uploads/missing-file.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,8EAA8E;AAC9E,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAK1D"}
@@ -0,0 +1,6 @@
1
+ import { ValidationError } from '@ddd-ts-kit/validation';
2
+ /** The refusal of a multipart request without the file its route declares. */
3
+ export function missingFile(field) {
4
+ return new ValidationError([{ path: `body.${field}`, code: 'required', message: `A file is expected in the field "${field}".` }], 'The request is not valid.');
5
+ }
6
+ //# sourceMappingURL=missing-file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"missing-file.js","sourceRoot":"","sources":["../../src/uploads/missing-file.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,8EAA8E;AAC9E,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,OAAO,IAAI,eAAe,CACxB,CAAC,EAAE,IAAI,EAAE,QAAQ,KAAK,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,oCAAoC,KAAK,IAAI,EAAE,CAAC,EACrG,2BAA2B,CAC5B,CAAC;AACJ,CAAC"}
@@ -0,0 +1,7 @@
1
+ export interface MultipartLimits {
2
+ /** Text fields at most. Default 20. */
3
+ readonly fields?: number;
4
+ /** Bytes of one text field at most. Default 64 KiB. */
5
+ readonly fieldBytes?: number;
6
+ }
7
+ //# sourceMappingURL=multipart-limits.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"multipart-limits.d.ts","sourceRoot":"","sources":["../../src/uploads/multipart-limits.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,uCAAuC;IACvC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,uDAAuD;IACvD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=multipart-limits.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"multipart-limits.js","sourceRoot":"","sources":["../../src/uploads/multipart-limits.ts"],"names":[],"mappings":""}
@@ -0,0 +1,8 @@
1
+ import type { UploadReader } from '../pipeline/upload-reader.js';
2
+ import type { MultipartLimits } from './multipart-limits.js';
3
+ /**
4
+ * The upload reader of the kit, on busboy: pass it as `uploads` to the mount options. The file
5
+ * streams to the handler while the request arrives, never held whole.
6
+ */
7
+ export declare function multipartUploads(limits?: MultipartLimits): UploadReader;
8
+ //# sourceMappingURL=multipart-uploads.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"multipart-uploads.d.ts","sourceRoot":"","sources":["../../src/uploads/multipart-uploads.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAG7D;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,GAAE,eAAoB,GAAG,YAAY,CAE3E"}
@@ -0,0 +1,9 @@
1
+ import { readMultipart } from './read-multipart.js';
2
+ /**
3
+ * The upload reader of the kit, on busboy: pass it as `uploads` to the mount options. The file
4
+ * streams to the handler while the request arrives, never held whole.
5
+ */
6
+ export function multipartUploads(limits = {}) {
7
+ return (spec, request) => readMultipart(spec, request, limits);
8
+ }
9
+ //# sourceMappingURL=multipart-uploads.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"multipart-uploads.js","sourceRoot":"","sources":["../../src/uploads/multipart-uploads.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAM,GAAoB,EAAE;IAC3D,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;AACjE,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { RawRequest } from '../pipeline/raw-request.js';
2
+ import type { ReceivedUpload } from '../pipeline/received-upload.js';
3
+ import type { UploadSpec } from '../route/upload-spec.js';
4
+ import type { MultipartLimits } from './multipart-limits.js';
5
+ /**
6
+ * Parses a `multipart/form-data` request as it streams and resolves as soon as the declared file
7
+ * begins: the text fields read so far, and the file wrapped in a `FileInspection` that refuses it
8
+ * beyond `maxBytes` or when its first bytes are not one of the accepted media types. A request
9
+ * that announces a larger body is refused before any byte is read. A request that closes before
10
+ * its end fails the file stream, so whatever consumes it rejects instead of waiting forever.
11
+ */
12
+ export declare function readMultipart(spec: UploadSpec, request: RawRequest, limits: MultipartLimits): Promise<ReceivedUpload>;
13
+ //# sourceMappingURL=read-multipart.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-multipart.d.ts","sourceRoot":"","sources":["../../src/uploads/read-multipart.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAG1D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAK7D;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CA4CrH"}
@@ -0,0 +1,65 @@
1
+ import { pipeline } from 'node:stream/promises';
2
+ import busboy, {} from 'busboy';
3
+ import { FileError, FileInspection, mediaTypeOf } from '@ddd-ts-kit/kernel';
4
+ import { headerOf } from '../route/header-of.js';
5
+ import { missingFile } from './missing-file.js';
6
+ /** Room for the boundaries, the part headers and the text fields over the declared size of the file. */
7
+ const ENVELOPE_BYTES = 1_048_576;
8
+ /**
9
+ * Parses a `multipart/form-data` request as it streams and resolves as soon as the declared file
10
+ * begins: the text fields read so far, and the file wrapped in a `FileInspection` that refuses it
11
+ * beyond `maxBytes` or when its first bytes are not one of the accepted media types. A request
12
+ * that announces a larger body is refused before any byte is read. A request that closes before
13
+ * its end fails the file stream, so whatever consumes it rejects instead of waiting forever.
14
+ */
15
+ export function readMultipart(spec, request, limits) {
16
+ const contentType = headerOf(request.headers, 'content-type');
17
+ if (mediaTypeOf(contentType) !== 'multipart/form-data') {
18
+ return Promise.reject(FileError.unsupportedMediaType(mediaTypeOf(contentType), ['multipart/form-data']));
19
+ }
20
+ if (Number(headerOf(request.headers, 'content-length')) > spec.maxBytes + ENVELOPE_BYTES) {
21
+ return Promise.reject(FileError.tooLarge(spec.maxBytes));
22
+ }
23
+ const { stream } = request;
24
+ if (stream === undefined) {
25
+ return Promise.reject(new Error('The adapter handed no request stream: an upload cannot be read.'));
26
+ }
27
+ return new Promise((resolve, reject) => {
28
+ const parser = busboy({ headers: { 'content-type': contentType }, limits: limitsOf(spec, limits) });
29
+ const fields = {};
30
+ parser.on('field', (name, value) => {
31
+ fields[name] = value;
32
+ });
33
+ parser.on('file', (name, file, info) => {
34
+ if (name !== spec.field) {
35
+ file.resume();
36
+ return;
37
+ }
38
+ resolve({ fields: { ...fields }, file: inspected(spec, file, info) });
39
+ });
40
+ parser.on('error', reject);
41
+ parser.on('close', () => {
42
+ reject(missingFile(spec.field));
43
+ });
44
+ // A client that drops the connection part-way destroys the parser, which fails the file with it.
45
+ pipeline(stream, parser).catch(reject);
46
+ });
47
+ }
48
+ function limitsOf(spec, limits) {
49
+ return {
50
+ files: 1,
51
+ fileSize: spec.maxBytes + 1,
52
+ fields: limits.fields ?? 20,
53
+ fieldSize: limits.fieldBytes ?? 65_536,
54
+ };
55
+ }
56
+ function inspected(spec, file, info) {
57
+ const mediaType = mediaTypeOf(info.mimeType);
58
+ const inspection = new FileInspection({
59
+ maxBytes: spec.maxBytes,
60
+ expected: { mediaType, accepted: spec.mediaTypes },
61
+ });
62
+ void pipeline(file, inspection).catch(() => undefined);
63
+ return { fileName: info.filename ?? '', mediaType, stream: inspection };
64
+ }
65
+ //# sourceMappingURL=read-multipart.js.map