pipework 0.65.0 → 0.67.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 (55) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/REFERENCE.md +43 -2
  3. package/dist/core/errors/http.d.ts +10 -0
  4. package/dist/core/errors/http.d.ts.map +1 -1
  5. package/dist/core/errors/http.js +14 -0
  6. package/dist/core/errors/http.js.map +1 -1
  7. package/dist/core/errors/index.d.ts +1 -1
  8. package/dist/core/errors/index.d.ts.map +1 -1
  9. package/dist/core/errors/index.js +1 -1
  10. package/dist/core/errors/index.js.map +1 -1
  11. package/dist/core/errors/namespace.d.ts +5 -1
  12. package/dist/core/errors/namespace.d.ts.map +1 -1
  13. package/dist/core/errors/namespace.js +5 -1
  14. package/dist/core/errors/namespace.js.map +1 -1
  15. package/dist/index.d.ts +3 -2
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +1 -1
  18. package/dist/index.js.map +1 -1
  19. package/dist/request/di/builder.d.ts +70 -1
  20. package/dist/request/di/builder.d.ts.map +1 -1
  21. package/dist/request/di/builder.js +75 -0
  22. package/dist/request/di/builder.js.map +1 -1
  23. package/dist/request/di/index.d.ts +1 -1
  24. package/dist/request/di/index.d.ts.map +1 -1
  25. package/dist/request/di/resolve.d.ts +2 -1
  26. package/dist/request/di/resolve.d.ts.map +1 -1
  27. package/dist/request/di/resolve.js +8 -0
  28. package/dist/request/di/resolve.js.map +1 -1
  29. package/dist/request/di/types.d.ts +46 -0
  30. package/dist/request/di/types.d.ts.map +1 -1
  31. package/dist/request/di/types.js.map +1 -1
  32. package/dist/request/http/file.d.ts +62 -0
  33. package/dist/request/http/file.d.ts.map +1 -0
  34. package/dist/request/http/file.js +120 -0
  35. package/dist/request/http/file.js.map +1 -0
  36. package/dist/request/http/index.d.ts +1 -0
  37. package/dist/request/http/index.d.ts.map +1 -1
  38. package/dist/request/http/index.js.map +1 -1
  39. package/dist/request/http/namespace.d.ts +5 -2
  40. package/dist/request/http/namespace.d.ts.map +1 -1
  41. package/dist/request/http/namespace.js +3 -2
  42. package/dist/request/http/namespace.js.map +1 -1
  43. package/dist/request/http/server.d.ts.map +1 -1
  44. package/dist/request/http/server.js +111 -6
  45. package/dist/request/http/server.js.map +1 -1
  46. package/dist/request/http/types.d.ts +3 -1
  47. package/dist/request/http/types.d.ts.map +1 -1
  48. package/dist/request/http/upload.d.ts +39 -0
  49. package/dist/request/http/upload.d.ts.map +1 -0
  50. package/dist/request/http/upload.js +140 -0
  51. package/dist/request/http/upload.js.map +1 -0
  52. package/dist/request/openapi/generate.d.ts.map +1 -1
  53. package/dist/request/openapi/generate.js +30 -1
  54. package/dist/request/openapi/generate.js.map +1 -1
  55. package/package.json +2 -1
@@ -1 +1 @@
1
- {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../../src/request/di/resolve.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../../src/request/di/resolve.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import type { Schema } from '../../data/schema/types.js';
2
2
  import type { DB } from '../../data/db/index.js';
3
+ import type { Readable } from 'node:stream';
3
4
  import type { BackoffConfig } from '../../async/jobs/queue.js';
4
5
  /** The default database name constant ('default') used when pipe() is called without a name argument. */
5
6
  export declare const DEFAULT_DB: "__pipework_default__";
@@ -57,6 +58,51 @@ export interface HandlerMeta {
57
58
  readonly wantsRequest: boolean;
58
59
  readonly wantsResponse: boolean;
59
60
  readonly wantsRawBody: boolean;
61
+ readonly upload?: UploadConfig | null;
62
+ readonly file?: FileConfig | null;
63
+ }
64
+ /** A route's file response, declared by `.file()`. */
65
+ export interface FileConfig {
66
+ /** Media types the route may answer with; `type/*` wildcards allowed. */
67
+ readonly mediaTypes: readonly string[];
68
+ /** Status of the file response (default 200). */
69
+ readonly status: number;
70
+ }
71
+ /** Upload whose whole request body is the file's bytes. */
72
+ export interface BinaryUploadConfig {
73
+ readonly kind: 'binary';
74
+ /** Accepted request media types; `type/*` wildcards allowed. Others get 415. */
75
+ readonly mediaTypes: readonly string[];
76
+ /** Largest accepted body in bytes. Over it gets 413. */
77
+ readonly maxBytes: number;
78
+ }
79
+ /** Upload whose file is one part of a `multipart/form-data` body. */
80
+ export interface MultipartUploadConfig {
81
+ readonly kind: 'multipart';
82
+ /** Name of the form field carrying the file. */
83
+ readonly file: string;
84
+ /** Accepted media types of the file part; `type/*` wildcards allowed. Others get 415. */
85
+ readonly mediaTypes: readonly string[];
86
+ /** Largest accepted file in bytes. Over it gets 413. */
87
+ readonly maxBytes: number;
88
+ /** Text field names accepted ahead of the file part; any other field gets 422. */
89
+ readonly fields?: readonly string[];
90
+ }
91
+ export type UploadConfig = BinaryUploadConfig | MultipartUploadConfig;
92
+ /** The `upload` dep of a binary upload route. */
93
+ export interface BinaryUpload {
94
+ readonly stream: Readable;
95
+ readonly mediaType: string;
96
+ /** Declared Content-Length, or null for a chunked body. */
97
+ readonly length: number | null;
98
+ }
99
+ /** The `upload` dep of a multipart upload route. */
100
+ export interface MultipartUpload {
101
+ readonly stream: Readable;
102
+ readonly mediaType: string;
103
+ readonly filename: string | null;
104
+ /** Text fields that came before the file part. */
105
+ readonly fields: Readonly<Record<string, string>>;
60
106
  }
61
107
  /**
62
108
  * What a route screen is shown: the request line and headers, plus the declared
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/request/di/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/request/di/types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/request/di/types.ts"],"names":[],"mappings":"AAIA,yGAAyG;AACzG,MAAM,CAAC,MAAM,UAAU,GAAG,sBAA+B,CAAA"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/request/di/types.ts"],"names":[],"mappings":"AAKA,yGAAyG;AACzG,MAAM,CAAC,MAAM,UAAU,GAAG,sBAA+B,CAAA"}
@@ -0,0 +1,62 @@
1
+ import { Readable } from 'node:stream';
2
+ import type { FileConfig } from '../di/types.js';
3
+ declare const FILE_RESPONSE: unique symbol;
4
+ /** What `http.file()` takes. */
5
+ export interface FileResponseInit {
6
+ /** The bytes, or a stream that is read as it is sent. */
7
+ readonly body: Buffer | Uint8Array | Readable;
8
+ /** Content-Type of the response, e.g. `application/pdf`. */
9
+ readonly mediaType: string;
10
+ /** Name the browser saves the file under. Any characters; the header is escaped. */
11
+ readonly filename?: string;
12
+ /** `'attachment'` (default) downloads; `'inline'` lets the browser display it. */
13
+ readonly disposition?: 'attachment' | 'inline';
14
+ /** Byte length of a stream body, sent as Content-Length. Ignored for a Buffer, whose length is known. */
15
+ readonly length?: number;
16
+ }
17
+ /**
18
+ * A file for a route to answer with, made by `http.file()`. Return it from a
19
+ * handler declared with `.file()`; it is sent as the response body, streamed
20
+ * when `body` is a Readable.
21
+ */
22
+ export interface FileResponse {
23
+ readonly [FILE_RESPONSE]: true;
24
+ readonly body: Buffer | Readable;
25
+ readonly mediaType: string;
26
+ readonly filename: string | undefined;
27
+ readonly disposition: 'attachment' | 'inline';
28
+ readonly length: number | undefined;
29
+ }
30
+ /**
31
+ * Builds the value a handler returns to answer with a file: `body` (Buffer,
32
+ * Uint8Array or Readable), `mediaType`, and optionally `filename`,
33
+ * `disposition` (`'attachment'` default, or `'inline'`) and `length` (the byte
34
+ * length of a stream, sent as Content-Length; without it a stream is sent
35
+ * chunked).
36
+ *
37
+ * Declare the route with `.file({ mediaTypes })` so OpenAPI describes it. The
38
+ * response carries Content-Type, Content-Length (Buffer, or stream with
39
+ * `length`), Content-Disposition with an ASCII `filename=` fallback and the
40
+ * exact name in `filename*=UTF-8''...`, and `X-Content-Type-Options: nosniff`.
41
+ *
42
+ * The request transaction (auto mode) has committed before the first byte is
43
+ * sent, so a stream must not need it. A stream that fails before its first
44
+ * byte gets a 500; one that fails after destroys the connection and logs the
45
+ * error, so the client sees an aborted download, never a complete-looking
46
+ * short one. Range requests and redirects are not supported.
47
+ */
48
+ export declare function file(init: FileResponseInit): FileResponse;
49
+ /** True for a value made by `http.file()`. */
50
+ export declare function isFileResponse(value: unknown): value is FileResponse;
51
+ /** The reason a file response cannot be sent for a route declared with `declared`, or null. */
52
+ export declare function fileResponseProblem(declared: FileConfig | null, file: FileResponse): string | null;
53
+ /** Content-Disposition value per RFC 6266 / RFC 5987: ASCII fallback plus the exact name percent-encoded. */
54
+ export declare function contentDisposition(disposition: 'attachment' | 'inline', filename: string | undefined): string;
55
+ /**
56
+ * Reads a stream's first chunk before anything is sent, so a stream that fails
57
+ * at once can still become a normal error response. Returns the stream to send
58
+ * (the same bytes, replayed), which fails after `length` mismatches or on error.
59
+ */
60
+ export declare function primeStream(source: Readable, length: number | undefined): Promise<Readable>;
61
+ export {};
62
+ //# sourceMappingURL=file.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file.d.ts","sourceRoot":"","sources":["../../../src/request/http/file.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AACtC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAGhD,QAAA,MAAM,aAAa,eAAsC,CAAA;AAEzD,gCAAgC;AAChC,MAAM,WAAW,gBAAgB;IAC/B,yDAAyD;IACzD,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,QAAQ,CAAA;IAC7C,4DAA4D;IAC5D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,oFAAoF;IACpF,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;IAC1B,kFAAkF;IAClF,QAAQ,CAAC,WAAW,CAAC,EAAE,YAAY,GAAG,QAAQ,CAAA;IAC9C,yGAAyG;IACzG,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CACzB;AAED;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,CAAC,aAAa,CAAC,EAAE,IAAI,CAAA;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAAA;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAA;IACrC,QAAQ,CAAC,WAAW,EAAE,YAAY,GAAG,QAAQ,CAAA;IAC7C,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;CACpC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,IAAI,CAAC,IAAI,EAAE,gBAAgB,GAAG,YAAY,CAwBzD;AAED,8CAA8C;AAC9C,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,YAAY,CAEpE;AAED,+FAA+F;AAC/F,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,UAAU,GAAG,IAAI,EAAE,IAAI,EAAE,YAAY,GAAG,MAAM,GAAG,IAAI,CAMlG;AAED,6GAA6G;AAC7G,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,YAAY,GAAG,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAa7G;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC,CA2BjG"}
@@ -0,0 +1,120 @@
1
+ import { Readable } from 'node:stream';
2
+ import { mediaTypeAllowed } from './upload.js';
3
+ const FILE_RESPONSE = Symbol.for('pipework.fileResponse');
4
+ /**
5
+ * Builds the value a handler returns to answer with a file: `body` (Buffer,
6
+ * Uint8Array or Readable), `mediaType`, and optionally `filename`,
7
+ * `disposition` (`'attachment'` default, or `'inline'`) and `length` (the byte
8
+ * length of a stream, sent as Content-Length; without it a stream is sent
9
+ * chunked).
10
+ *
11
+ * Declare the route with `.file({ mediaTypes })` so OpenAPI describes it. The
12
+ * response carries Content-Type, Content-Length (Buffer, or stream with
13
+ * `length`), Content-Disposition with an ASCII `filename=` fallback and the
14
+ * exact name in `filename*=UTF-8''...`, and `X-Content-Type-Options: nosniff`.
15
+ *
16
+ * The request transaction (auto mode) has committed before the first byte is
17
+ * sent, so a stream must not need it. A stream that fails before its first
18
+ * byte gets a 500; one that fails after destroys the connection and logs the
19
+ * error, so the client sees an aborted download, never a complete-looking
20
+ * short one. Range requests and redirects are not supported.
21
+ */
22
+ export function file(init) {
23
+ if (typeof init.mediaType !== 'string' || init.mediaType.trim() === '' || /[\r\n]/.test(init.mediaType)) {
24
+ throw new Error('[pipework] http.file() needs a mediaType such as "application/pdf" (one line, not empty).');
25
+ }
26
+ const disposition = init.disposition ?? 'attachment';
27
+ if (disposition !== 'attachment' && disposition !== 'inline') {
28
+ throw new Error(`[pipework] http.file() disposition must be 'attachment' or 'inline', got ${String(disposition)}.`);
29
+ }
30
+ if (init.length !== undefined && (!Number.isInteger(init.length) || init.length < 0)) {
31
+ throw new Error(`[pipework] http.file() length must be a non-negative integer number of bytes, got ${String(init.length)}.`);
32
+ }
33
+ let body;
34
+ if (init.body instanceof Readable)
35
+ body = init.body;
36
+ else if (Buffer.isBuffer(init.body))
37
+ body = init.body;
38
+ else if (init.body instanceof Uint8Array)
39
+ body = Buffer.from(init.body.buffer, init.body.byteOffset, init.body.byteLength);
40
+ else
41
+ throw new Error('[pipework] http.file() body must be a Buffer, Uint8Array or Readable stream.');
42
+ return Object.freeze({
43
+ [FILE_RESPONSE]: true,
44
+ body,
45
+ mediaType: init.mediaType.trim(),
46
+ filename: init.filename,
47
+ disposition,
48
+ length: init.length,
49
+ });
50
+ }
51
+ /** True for a value made by `http.file()`. */
52
+ export function isFileResponse(value) {
53
+ return value !== null && typeof value === 'object' && value[FILE_RESPONSE] === true;
54
+ }
55
+ /** The reason a file response cannot be sent for a route declared with `declared`, or null. */
56
+ export function fileResponseProblem(declared, file) {
57
+ if (declared === null)
58
+ return null;
59
+ if (!mediaTypeAllowed(declared.mediaTypes, file.mediaType.split(';')[0].trim().toLowerCase())) {
60
+ return `The file's mediaType ${file.mediaType} is not in the route's .file() list (${declared.mediaTypes.join(', ')}).`;
61
+ }
62
+ return null;
63
+ }
64
+ /** Content-Disposition value per RFC 6266 / RFC 5987: ASCII fallback plus the exact name percent-encoded. */
65
+ export function contentDisposition(disposition, filename) {
66
+ if (filename === undefined || filename === '')
67
+ return disposition;
68
+ const wellFormed = filename.replace(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g, '\uFFFD');
69
+ let fallback = '';
70
+ for (const ch of wellFormed) {
71
+ const code = ch.codePointAt(0);
72
+ if (code > 0x7e)
73
+ fallback += '_';
74
+ else if (code < 0x20 || code === 0x7f || ch === '"' || ch === '\\' || ch === '/')
75
+ continue;
76
+ else
77
+ fallback += ch;
78
+ }
79
+ if (fallback.trim() === '')
80
+ fallback = 'file';
81
+ const encoded = encodeURIComponent(wellFormed).replace(/['()*]/g, (c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`);
82
+ return `${disposition}; filename="${fallback}"; filename*=UTF-8''${encoded}`;
83
+ }
84
+ /**
85
+ * Reads a stream's first chunk before anything is sent, so a stream that fails
86
+ * at once can still become a normal error response. Returns the stream to send
87
+ * (the same bytes, replayed), which fails after `length` mismatches or on error.
88
+ */
89
+ export async function primeStream(source, length) {
90
+ const iterator = source[Symbol.asyncIterator]();
91
+ let first;
92
+ try {
93
+ first = await iterator.next();
94
+ }
95
+ catch (error) {
96
+ source.destroy();
97
+ throw error;
98
+ }
99
+ async function* replay() {
100
+ let sent = 0;
101
+ try {
102
+ let step = first;
103
+ while (step.done !== true) {
104
+ const chunk = typeof step.value === 'string' ? Buffer.from(step.value) : step.value;
105
+ sent += chunk.length;
106
+ yield chunk;
107
+ step = await iterator.next();
108
+ }
109
+ if (length !== undefined && sent !== length) {
110
+ throw new Error(`[pipework] The file stream ended after ${sent} bytes but http.file() declared length ${length}.`);
111
+ }
112
+ }
113
+ finally {
114
+ if (!source.destroyed)
115
+ source.destroy();
116
+ }
117
+ }
118
+ return Readable.from(replay(), { objectMode: false });
119
+ }
120
+ //# sourceMappingURL=file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file.js","sourceRoot":"","sources":["../../../src/request/http/file.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  export { createServer, type PipeworkServer } from './server.js';
2
2
  export type { ServerConfig, RouteRegistration, ErrorResponse, HandlerResponse, InjectOptions, InjectResponse, HttpRequest, HttpResponse, CorsConfig, SecurityConfig, RateLimitConfig } from './types.js';
3
+ export type { FileResponse, FileResponseInit } from './file.js';
3
4
  export { buildErrorResponse, buildInternalErrorResponse } from './response.js';
4
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/request/http/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAA;AAC/D,YAAY,EAAE,YAAY,EAAE,iBAAiB,EAAE,aAAa,EAAE,eAAe,EAAE,aAAa,EAAE,cAAc,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AACxM,OAAO,EAAE,kBAAkB,EAAE,0BAA0B,EAAE,MAAM,eAAe,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/request/http/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAA;AAC/D,YAAY,EAAE,YAAY,EAAE,iBAAiB,EAAE,aAAa,EAAE,eAAe,EAAE,aAAa,EAAE,cAAc,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AACxM,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAA;AAC/D,OAAO,EAAE,kBAAkB,EAAE,0BAA0B,EAAE,MAAM,eAAe,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/request/http/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAuB,MAAM,aAAa,CAAA;AAE/D,OAAO,EAAE,kBAAkB,EAAE,0BAA0B,EAAE,MAAM,eAAe,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/request/http/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAuB,MAAM,aAAa,CAAA;AAG/D,OAAO,EAAE,kBAAkB,EAAE,0BAA0B,EAAE,MAAM,eAAe,CAAA"}
@@ -1,3 +1,6 @@
1
- /** HTTP server namespace — managed by manifold.start(), not directly accessible. */
2
- export declare const http: {};
1
+ import { file } from './file.js';
2
+ /** HTTP namespace: `http.file()` builds a file response; the server itself is managed by manifold.start(). */
3
+ export declare const http: {
4
+ readonly file: typeof file;
5
+ };
3
6
  //# sourceMappingURL=namespace.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"namespace.d.ts","sourceRoot":"","sources":["../../../src/request/http/namespace.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,eAAO,MAAM,IAAI,IAAc,CAAA"}
1
+ {"version":3,"file":"namespace.d.ts","sourceRoot":"","sources":["../../../src/request/http/namespace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEhC,8GAA8G;AAC9G,eAAO,MAAM,IAAI;;CAAoB,CAAA"}
@@ -1,3 +1,4 @@
1
- /** HTTP server namespace — managed by manifold.start(), not directly accessible. */
2
- export const http = {};
1
+ import { file } from './file.js';
2
+ /** HTTP namespace: `http.file()` builds a file response; the server itself is managed by manifold.start(). */
3
+ export const http = { file };
3
4
  //# sourceMappingURL=namespace.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"namespace.js","sourceRoot":"","sources":["../../../src/request/http/namespace.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,MAAM,CAAC,MAAM,IAAI,GAAG,EAAW,CAAA"}
1
+ {"version":3,"file":"namespace.js","sourceRoot":"","sources":["../../../src/request/http/namespace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEhC,8GAA8G;AAC9G,MAAM,CAAC,MAAM,IAAI,GAAG,EAAE,IAAI,EAAW,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/request/http/server.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AACtD,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AACzD,OAAO,KAAK,EAAE,YAAY,EAAsC,aAAa,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAkBjH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AAGnD,qGAAqG;AACrG,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;IACjG,gBAAgB,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,EAAE,GAAG,IAAI,CAAA;IAC7E,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,IAAI,CAAA;IACnD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACtB,MAAM,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC,CAAA;IACpD,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,CAAA;IACzB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CACvB;AAED,wHAAwH;AACxH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAE,YAAiB,GAAG,cAAc,CAkU1F"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/request/http/server.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AACtD,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AACzD,OAAO,KAAK,EAAE,YAAY,EAAsC,aAAa,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAsBjH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AAGnD,qGAAqG;AACrG,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;IACjG,gBAAgB,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,EAAE,GAAG,IAAI,CAAA;IAC7E,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,IAAI,CAAA;IACnD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACtB,MAAM,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC,CAAA;IACpD,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,CAAA;IACzB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CACvB;AAED,wHAAwH;AACxH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAE,YAAiB,GAAG,cAAc,CA+X1F"}
@@ -4,6 +4,7 @@ import Fastify, {} from 'fastify';
4
4
  import fastifyCors from '@fastify/cors';
5
5
  import fastifyHelmet from '@fastify/helmet';
6
6
  import fastifyRateLimit from '@fastify/rate-limit';
7
+ import fastifyMultipart from '@fastify/multipart';
7
8
  import { runInContext } from '../context/store.js';
8
9
  import { createRequestContext } from '../context/index.js';
9
10
  import { executeInTransaction } from '../context/run-in-transaction.js';
@@ -12,6 +13,8 @@ import { buildContext } from './middleware.js';
12
13
  import { closeTrace } from '../../trace/entry/close-trace.js';
13
14
  import { buildErrorResponse, buildInternalErrorResponse } from './response.js';
14
15
  import { isPipeworkError } from '../../core/errors/index.js';
16
+ import { checkUploadHeaders, uploadBodyLimit, binaryUpload, multipartUpload, settleUpload, MULTIPART_FIELD_LIMIT } from './upload.js';
17
+ import { isFileResponse, fileResponseProblem, contentDisposition, primeStream } from './file.js';
15
18
  import { toJsonSchema } from '../../data/schema/json-schema.js';
16
19
  import { generateOpenAPI } from '../openapi/generate.js';
17
20
  import { getBaseLogger, setLoggingConfig } from '../../core/logging/index.js';
@@ -126,7 +129,11 @@ export function createServer(instance, config = {}) {
126
129
  schema['params'] = toJsonSchema(handler.meta.paramsSchema);
127
130
  }
128
131
  const opts = Object.keys(schema).length > 0 ? { schema } : {};
129
- if (handler.meta.route?.bodyLimit !== undefined) {
132
+ const upload = handler.meta.upload ?? null;
133
+ if (upload !== null) {
134
+ opts['bodyLimit'] = uploadBodyLimit(upload);
135
+ }
136
+ else if (handler.meta.route?.bodyLimit !== undefined) {
130
137
  opts['bodyLimit'] = handler.meta.route.bodyLimit;
131
138
  }
132
139
  const screen = handler.meta.route?.screen;
@@ -169,6 +176,19 @@ export function createServer(instance, config = {}) {
169
176
  return undefined;
170
177
  };
171
178
  }
179
+ if (upload !== null) {
180
+ // After the screen: a refusal from headers alone (415, or 413 on a declared
181
+ // length) before anything is read.
182
+ const headerCheck = async (req, reply) => {
183
+ const refusal = checkUploadHeaders(upload, req.headers);
184
+ if (refusal === null)
185
+ return undefined;
186
+ void reply.header('connection', 'close');
187
+ return reply.status(refusal.httpStatus).send(buildErrorResponse(refusal));
188
+ };
189
+ const existing = opts['onRequest'];
190
+ opts['onRequest'] = existing === undefined ? [headerCheck] : [existing, headerCheck];
191
+ }
172
192
  if (handler.meta.wantsRawBody) {
173
193
  opts['preParsing'] = async (req, _reply, payload) => {
174
194
  const chunks = [];
@@ -179,8 +199,14 @@ export function createServer(instance, config = {}) {
179
199
  return Readable.from(raw);
180
200
  };
181
201
  }
182
- app[fastifyMethod](path, opts, async (req, reply) => {
202
+ const routeHandler = async (req, reply) => {
183
203
  let ctx;
204
+ let uploaded;
205
+ // Ends the upload stream and closes the connection if the body was left unread.
206
+ const finishUpload = (failed) => {
207
+ if (settleUpload(uploaded?.stream) || (failed && upload !== null))
208
+ void reply.header('connection', 'close');
209
+ };
184
210
  try {
185
211
  ctx = await buildContext(req, contextOptions, handler.meta.authRequirement);
186
212
  if (handler.meta.permission && rbacInstance) {
@@ -197,6 +223,11 @@ export function createServer(instance, config = {}) {
197
223
  if (rawBodyBuffer !== undefined) {
198
224
  requestObj.rawBody = rawBodyBuffer;
199
225
  }
226
+ if (upload !== null) {
227
+ uploaded = upload.kind === 'binary'
228
+ ? binaryUpload(req, upload.maxBytes)
229
+ : await multipartUpload(req, upload);
230
+ }
200
231
  const httpOptions = {
201
232
  request: requestObj,
202
233
  response: {
@@ -204,6 +235,7 @@ export function createServer(instance, config = {}) {
204
235
  onFinish: (cb) => watchResponse(reply, cb, req.log),
205
236
  },
206
237
  ...(rawBodyBuffer !== undefined ? { rawBody: rawBodyBuffer } : {}),
238
+ ...(uploaded !== undefined ? { upload: uploaded } : {}),
207
239
  };
208
240
  let result;
209
241
  if (handler.meta.jobTransaction === 'manual') {
@@ -222,22 +254,54 @@ export function createServer(instance, config = {}) {
222
254
  else {
223
255
  result = await runInContext(ctx, () => resolveAndExecute(handler, req.body, req.query, req.params, httpOptions));
224
256
  }
257
+ finishUpload(false);
225
258
  void closeTrace(instance, ctx.trace, 'closed');
226
- return sendResult(reply, result);
259
+ return await sendResult(reply, req, result, handler.meta.file ?? null, `${method} ${path}`);
227
260
  }
228
261
  catch (error) {
262
+ finishUpload(true);
229
263
  if (ctx !== undefined)
230
264
  void closeTrace(instance, ctx.trace, 'error');
265
+ if (error instanceof FileResponseError) {
266
+ req.log.error({ route: `${method} ${path}`, requestId: String(req.id), err: error }, 'File response refused');
267
+ return reply.status(500).send({ error: { code: 'FILE_RESPONSE_INVALID', message: error.message } });
268
+ }
231
269
  if (isPipeworkError(error)) {
232
270
  const retryAfter = error.retryAfterSeconds;
233
271
  if (typeof retryAfter === 'number')
234
272
  void reply.header('Retry-After', String(Math.max(0, Math.ceil(retryAfter))));
235
273
  return reply.status(error.httpStatus).send(buildErrorResponse(error));
236
274
  }
275
+ // A malformed multipart body surfaces as a Fastify client error (4xx).
276
+ const clientStatus = upload !== null ? error?.statusCode : undefined;
277
+ if (typeof clientStatus === 'number' && clientStatus >= 400 && clientStatus < 500) {
278
+ const e = error;
279
+ return reply.status(clientStatus).send({ error: { code: String(e.code ?? 'BAD_REQUEST'), message: String(e.message ?? 'Bad request') } });
280
+ }
237
281
  req.log.error(error, 'Unhandled error in route handler');
238
282
  return reply.status(500).send(buildInternalErrorResponse(error, config.exposeErrorDetails));
239
283
  }
240
- });
284
+ };
285
+ if (upload === null) {
286
+ app[fastifyMethod](path, opts, routeHandler);
287
+ }
288
+ else {
289
+ // Its own plugin scope: the body parsers here replace the JSON parser for
290
+ // this route only, so no other route's parsing changes.
291
+ void app.register(async (child) => {
292
+ child.removeAllContentTypeParsers();
293
+ if (upload.kind === 'binary') {
294
+ child.addContentTypeParser('*', (_req, payload, done) => { done(null, payload); });
295
+ }
296
+ else {
297
+ await child.register(fastifyMultipart, {
298
+ throwFileSizeLimit: false,
299
+ limits: { fileSize: upload.maxBytes + 1024, fieldSize: MULTIPART_FIELD_LIMIT, files: 1, fields: 100 },
300
+ });
301
+ }
302
+ child[fastifyMethod](path, opts, routeHandler);
303
+ });
304
+ }
241
305
  }
242
306
  function registerHandlers(handlers) {
243
307
  for (const handler of handlers) {
@@ -283,7 +347,7 @@ export function createServer(instance, config = {}) {
283
347
  ...(opts.remoteAddress !== undefined ? { remoteAddress: opts.remoteAddress } : {}),
284
348
  });
285
349
  const r = response;
286
- return { statusCode: r.statusCode, headers: r.headers, body: r.body, json: () => r.json() };
350
+ return { statusCode: r.statusCode, headers: r.headers, body: r.body, rawPayload: r.rawPayload, json: () => r.json() };
287
351
  }
288
352
  return { route, registerHandlers, registerResource: registerResourceFn, ready, inject, listen, close };
289
353
  }
@@ -339,7 +403,48 @@ function watchResponse(reply, cb, log) {
339
403
  raw.once('finish', onFinish);
340
404
  raw.once('close', onClose);
341
405
  }
342
- function sendResult(reply, result) {
406
+ /** A file response the route cannot send; becomes a 500 naming the reason. */
407
+ class FileResponseError extends Error {
408
+ }
409
+ async function sendFile(reply, req, file, declared, route) {
410
+ const problem = fileResponseProblem(declared, file);
411
+ if (problem !== null) {
412
+ if (!Buffer.isBuffer(file.body))
413
+ file.body.destroy();
414
+ throw new FileResponseError(`[pipework] ${route}: ${problem}`);
415
+ }
416
+ let body;
417
+ let length;
418
+ if (Buffer.isBuffer(file.body)) {
419
+ body = file.body;
420
+ length = file.body.length;
421
+ }
422
+ else {
423
+ body = await primeStream(file.body, file.length);
424
+ length = file.length;
425
+ const raw = reply.raw;
426
+ body.on('error', (err) => {
427
+ // Headers are out: the only honest signal left is a dead connection.
428
+ req.log.error({ route, requestId: String(req.id), err }, 'File stream failed while sending');
429
+ raw.destroy();
430
+ });
431
+ raw.once('close', () => { if (!body.destroyed)
432
+ body.destroy(); });
433
+ }
434
+ void reply.status(declared?.status ?? 200);
435
+ void reply.header('content-type', file.mediaType);
436
+ void reply.header('content-disposition', contentDisposition(file.disposition, file.filename));
437
+ void reply.header('x-content-type-options', 'nosniff');
438
+ if (length !== undefined)
439
+ void reply.header('content-length', String(length));
440
+ return reply.send(body);
441
+ }
442
+ async function sendResult(reply, req, result, fileConfig, route) {
443
+ if (isFileResponse(result))
444
+ return sendFile(reply, req, result, fileConfig, route);
445
+ if (fileConfig !== null) {
446
+ throw new FileResponseError(`[pipework] ${route} is declared with .file() and must return http.file({ body, mediaType, filename? }); it returned ${result === null ? 'null' : typeof result}.`);
447
+ }
343
448
  if (result !== null && typeof result === 'object' && 'status' in result && typeof result['status'] === 'number') {
344
449
  const response = result;
345
450
  if (response.body !== undefined) {