@nifrajs/core 3.5.0 → 4.0.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.
- package/README.md +26 -0
- package/dist/assurance.d.ts +7 -0
- package/dist/assurance.d.ts.map +1 -1
- package/dist/assurance.js +39 -3
- package/dist/assurance.js.map +1 -1
- package/dist/capabilities.d.ts +20 -2
- package/dist/capabilities.d.ts.map +1 -1
- package/dist/capabilities.js +47 -15
- package/dist/capabilities.js.map +1 -1
- package/dist/diff.d.ts +2 -1
- package/dist/diff.d.ts.map +1 -1
- package/dist/diff.js +26 -2
- package/dist/diff.js.map +1 -1
- package/dist/durable-adapters.d.ts.map +1 -1
- package/dist/durable-adapters.js +16 -3
- package/dist/durable-adapters.js.map +1 -1
- package/dist/durable-effect.d.ts.map +1 -1
- package/dist/durable-effect.js +6 -3
- package/dist/durable-effect.js.map +1 -1
- package/dist/edge-kit.d.ts +2 -0
- package/dist/edge-kit.d.ts.map +1 -1
- package/dist/edge-kit.js +2 -0
- package/dist/edge-kit.js.map +1 -1
- package/dist/effect-lifecycle.d.ts.map +1 -1
- package/dist/effect-lifecycle.js +2 -1
- package/dist/effect-lifecycle.js.map +1 -1
- package/dist/effect-scope.d.ts.map +1 -1
- package/dist/effect-scope.js +1 -1
- package/dist/effect-scope.js.map +1 -1
- package/dist/errors.d.ts +1 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js.map +1 -1
- package/dist/evidence.d.ts +24 -1
- package/dist/evidence.d.ts.map +1 -1
- package/dist/evidence.js +168 -13
- package/dist/evidence.js.map +1 -1
- package/dist/idempotency.d.ts +31 -0
- package/dist/idempotency.d.ts.map +1 -1
- package/dist/idempotency.js +40 -8
- package/dist/idempotency.js.map +1 -1
- package/dist/index.d.ts +8 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/dist/internal/code-unit-order.d.ts +7 -0
- package/dist/internal/code-unit-order.d.ts.map +1 -0
- package/dist/internal/code-unit-order.js +9 -0
- package/dist/internal/code-unit-order.js.map +1 -0
- package/dist/internal/durable-saga-protocol.d.ts.map +1 -1
- package/dist/internal/durable-saga-protocol.js +2 -0
- package/dist/internal/durable-saga-protocol.js.map +1 -1
- package/dist/internal/route-catalog.d.ts +6 -6
- package/dist/internal/route-catalog.d.ts.map +1 -1
- package/dist/internal/route-catalog.js +20 -18
- package/dist/internal/route-catalog.js.map +1 -1
- package/dist/internal/route-compiler.d.ts +7 -6
- package/dist/internal/route-compiler.d.ts.map +1 -1
- package/dist/internal/route-compiler.js +36 -4
- package/dist/internal/route-compiler.js.map +1 -1
- package/dist/internal/route-execution.d.ts +7 -3
- package/dist/internal/route-execution.d.ts.map +1 -1
- package/dist/internal/route-execution.js.map +1 -1
- package/dist/internal/route-lanes.d.ts +1 -0
- package/dist/internal/route-lanes.d.ts.map +1 -1
- package/dist/internal/route-lanes.js +34 -29
- package/dist/internal/route-lanes.js.map +1 -1
- package/dist/internal/route-program.d.ts +8 -2
- package/dist/internal/route-program.d.ts.map +1 -1
- package/dist/internal/route-program.js +222 -20
- package/dist/internal/route-program.js.map +1 -1
- package/dist/ledger.d.ts.map +1 -1
- package/dist/ledger.js +8 -5
- package/dist/ledger.js.map +1 -1
- package/dist/manifest.d.ts.map +1 -1
- package/dist/manifest.js +41 -37
- package/dist/manifest.js.map +1 -1
- package/dist/mount.d.ts +36 -0
- package/dist/mount.d.ts.map +1 -1
- package/dist/mount.js +32 -0
- package/dist/mount.js.map +1 -1
- package/dist/reflection.d.ts +26 -0
- package/dist/reflection.d.ts.map +1 -1
- package/dist/reflection.js +65 -1
- package/dist/reflection.js.map +1 -1
- package/dist/response-observer.d.ts +1 -1
- package/dist/response-observer.d.ts.map +1 -1
- package/dist/response-observer.js.map +1 -1
- package/dist/router/overlap.d.ts +23 -0
- package/dist/router/overlap.d.ts.map +1 -0
- package/dist/router/overlap.js +224 -0
- package/dist/router/overlap.js.map +1 -0
- package/dist/router/pattern.d.ts +117 -2
- package/dist/router/pattern.d.ts.map +1 -1
- package/dist/router/pattern.js +283 -23
- package/dist/router/pattern.js.map +1 -1
- package/dist/router/router.d.ts +18 -4
- package/dist/router/router.d.ts.map +1 -1
- package/dist/router/router.js +51 -44
- package/dist/router/router.js.map +1 -1
- package/dist/server/auth.d.ts +53 -0
- package/dist/server/auth.d.ts.map +1 -0
- package/dist/server/auth.js +9 -0
- package/dist/server/auth.js.map +1 -0
- package/dist/server/bare-error-lane.d.ts +12 -7
- package/dist/server/bare-error-lane.d.ts.map +1 -1
- package/dist/server/bare-error-lane.js +13 -11
- package/dist/server/bare-error-lane.js.map +1 -1
- package/dist/server/body-lane.d.ts +20 -2
- package/dist/server/body-lane.d.ts.map +1 -1
- package/dist/server/body-lane.js +26 -7
- package/dist/server/body-lane.js.map +1 -1
- package/dist/server/body-parser.d.ts +68 -0
- package/dist/server/body-parser.d.ts.map +1 -0
- package/dist/server/body-parser.js +172 -0
- package/dist/server/body-parser.js.map +1 -0
- package/dist/server/body.d.ts.map +1 -1
- package/dist/server/body.js +62 -7
- package/dist/server/body.js.map +1 -1
- package/dist/server/client-ip.d.ts +8 -0
- package/dist/server/client-ip.d.ts.map +1 -1
- package/dist/server/client-ip.js +8 -0
- package/dist/server/client-ip.js.map +1 -1
- package/dist/server/context.d.ts +71 -6
- package/dist/server/context.d.ts.map +1 -1
- package/dist/server/contract.d.ts +15 -5
- package/dist/server/contract.d.ts.map +1 -1
- package/dist/server/contract.js +25 -4
- package/dist/server/contract.js.map +1 -1
- package/dist/server/core-copies.d.ts +2 -0
- package/dist/server/core-copies.d.ts.map +1 -0
- package/dist/server/core-copies.js +20 -0
- package/dist/server/core-copies.js.map +1 -0
- package/dist/server/edge.d.ts.map +1 -1
- package/dist/server/edge.js +2 -0
- package/dist/server/edge.js.map +1 -1
- package/dist/server/http.d.ts +11 -0
- package/dist/server/http.d.ts.map +1 -1
- package/dist/server/http.js +36 -0
- package/dist/server/http.js.map +1 -1
- package/dist/server/idempotency-lane.d.ts +6 -0
- package/dist/server/idempotency-lane.d.ts.map +1 -1
- package/dist/server/idempotency-lane.js +130 -73
- package/dist/server/idempotency-lane.js.map +1 -1
- package/dist/server/install.d.ts +4 -0
- package/dist/server/install.d.ts.map +1 -1
- package/dist/server/install.js +4 -0
- package/dist/server/install.js.map +1 -1
- package/dist/server/methods.d.ts +45 -0
- package/dist/server/methods.d.ts.map +1 -0
- package/dist/server/methods.js +37 -0
- package/dist/server/methods.js.map +1 -0
- package/dist/server/multipart.d.ts +63 -0
- package/dist/server/multipart.d.ts.map +1 -0
- package/dist/server/multipart.js +374 -0
- package/dist/server/multipart.js.map +1 -0
- package/dist/server/node-outcome-hook.d.ts +20 -0
- package/dist/server/node-outcome-hook.d.ts.map +1 -1
- package/dist/server/node-outcome-hook.js +15 -6
- package/dist/server/node-outcome-hook.js.map +1 -1
- package/dist/server/not-found-answer.d.ts +40 -0
- package/dist/server/not-found-answer.d.ts.map +1 -0
- package/dist/server/not-found-answer.js +56 -0
- package/dist/server/not-found-answer.js.map +1 -0
- package/dist/server/not-found.d.ts +23 -0
- package/dist/server/not-found.d.ts.map +1 -0
- package/dist/server/not-found.js +81 -0
- package/dist/server/not-found.js.map +1 -0
- package/dist/server/plugin.d.ts +26 -1
- package/dist/server/plugin.d.ts.map +1 -1
- package/dist/server/plugin.js.map +1 -1
- package/dist/server/proto-guard.d.ts +18 -5
- package/dist/server/proto-guard.d.ts.map +1 -1
- package/dist/server/proto-guard.js +114 -9
- package/dist/server/proto-guard.js.map +1 -1
- package/dist/server/query.d.ts +7 -0
- package/dist/server/query.d.ts.map +1 -1
- package/dist/server/query.js +47 -0
- package/dist/server/query.js.map +1 -1
- package/dist/server/registry.d.ts +13 -2
- package/dist/server/registry.d.ts.map +1 -1
- package/dist/server/request-context.d.ts +11 -0
- package/dist/server/request-context.d.ts.map +1 -1
- package/dist/server/request-context.js +33 -19
- package/dist/server/request-context.js.map +1 -1
- package/dist/server/request-lineage.d.ts +8 -0
- package/dist/server/request-lineage.d.ts.map +1 -0
- package/dist/server/request-lineage.js +14 -0
- package/dist/server/request-lineage.js.map +1 -0
- package/dist/server/request-target.d.ts +31 -0
- package/dist/server/request-target.d.ts.map +1 -0
- package/dist/server/request-target.js +44 -0
- package/dist/server/request-target.js.map +1 -0
- package/dist/server/respond.d.ts +1 -1
- package/dist/server/respond.d.ts.map +1 -1
- package/dist/server/respond.js +16 -4
- package/dist/server/respond.js.map +1 -1
- package/dist/server/response-contract-lane.d.ts +19 -1
- package/dist/server/response-contract-lane.d.ts.map +1 -1
- package/dist/server/response-contract-lane.js +59 -14
- package/dist/server/response-contract-lane.js.map +1 -1
- package/dist/server/response-observer-runtime.d.ts +9 -5
- package/dist/server/response-observer-runtime.d.ts.map +1 -1
- package/dist/server/response-observer-runtime.js +10 -6
- package/dist/server/response-observer-runtime.js.map +1 -1
- package/dist/server/runtime-core.d.ts +2 -0
- package/dist/server/runtime-core.d.ts.map +1 -1
- package/dist/server/runtime-core.js.map +1 -1
- package/dist/server/server-types.d.ts +53 -3
- package/dist/server/server-types.d.ts.map +1 -1
- package/dist/server/server.d.ts +191 -19
- package/dist/server/server.d.ts.map +1 -1
- package/dist/server/server.js +1206 -218
- package/dist/server/server.js.map +1 -1
- package/dist/server/sse.d.ts.map +1 -1
- package/dist/server/sse.js +10 -7
- package/dist/server/sse.js.map +1 -1
- package/dist/server/static-headers.d.ts +3 -0
- package/dist/server/static-headers.d.ts.map +1 -1
- package/dist/server/static-headers.js +19 -1
- package/dist/server/static-headers.js.map +1 -1
- package/dist/server/transport-lane.d.ts +8 -0
- package/dist/server/transport-lane.d.ts.map +1 -1
- package/dist/server/transport-lane.js +9 -8
- package/dist/server/transport-lane.js.map +1 -1
- package/dist/server/validation.d.ts.map +1 -1
- package/dist/server/validation.js +5 -1
- package/dist/server/validation.js.map +1 -1
- package/dist/server/websocket.d.ts +10 -3
- package/dist/server/websocket.d.ts.map +1 -1
- package/dist/server/websocket.js +7 -4
- package/dist/server/websocket.js.map +1 -1
- package/dist/server/ws-bun.d.ts +2 -0
- package/dist/server/ws-bun.d.ts.map +1 -1
- package/dist/server/ws-bun.js +6 -3
- package/dist/server/ws-bun.js.map +1 -1
- package/dist/server/ws-hook.d.ts +2 -1
- package/dist/server/ws-hook.d.ts.map +1 -1
- package/dist/server.d.ts +7 -4
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +4 -1
- package/dist/server.js.map +1 -1
- package/dist/single-copy-register.js +5 -0
- package/dist/single-copy-register.js.map +1 -1
- package/dist/single-copy.d.ts +46 -3
- package/dist/single-copy.d.ts.map +1 -1
- package/dist/single-copy.js +125 -12
- package/dist/single-copy.js.map +1 -1
- package/dist/tool-contract.d.ts +23 -0
- package/dist/tool-contract.d.ts.map +1 -1
- package/dist/tool-contract.js +37 -3
- package/dist/tool-contract.js.map +1 -1
- package/dist/transport-codec.d.ts.map +1 -1
- package/dist/transport-codec.js +2 -1
- package/dist/transport-codec.js.map +1 -1
- package/package.json +27 -2
- package/src/assurance.ts +52 -2
- package/src/capabilities.ts +81 -22
- package/src/diff.ts +31 -6
- package/src/durable-adapters.ts +20 -3
- package/src/durable-effect.ts +10 -3
- package/src/edge-kit.ts +7 -0
- package/src/effect-lifecycle.ts +5 -1
- package/src/effect-scope.ts +2 -1
- package/src/errors.ts +3 -0
- package/src/evidence.ts +237 -12
- package/src/idempotency.ts +72 -8
- package/src/index.ts +40 -3
- package/src/internal/code-unit-order.ts +8 -0
- package/src/internal/durable-saga-protocol.ts +2 -0
- package/src/internal/route-catalog.ts +19 -18
- package/src/internal/route-compiler.ts +62 -13
- package/src/internal/route-execution.ts +13 -3
- package/src/internal/route-lanes.ts +37 -28
- package/src/internal/route-program.ts +434 -20
- package/src/ledger.ts +11 -5
- package/src/manifest.ts +41 -36
- package/src/mount.ts +62 -0
- package/src/reflection.ts +84 -1
- package/src/response-observer.ts +1 -0
- package/src/router/overlap.ts +258 -0
- package/src/router/pattern.ts +349 -25
- package/src/router/router.ts +76 -51
- package/src/server/auth.ts +75 -0
- package/src/server/bare-error-lane.ts +12 -11
- package/src/server/body-lane.ts +46 -6
- package/src/server/body-parser.ts +241 -0
- package/src/server/body.ts +82 -9
- package/src/server/client-ip.ts +9 -0
- package/src/server/context.ts +219 -12
- package/src/server/contract.ts +54 -9
- package/src/server/core-copies.ts +21 -0
- package/src/server/edge.ts +2 -0
- package/src/server/http.ts +34 -0
- package/src/server/idempotency-lane.ts +147 -72
- package/src/server/install.ts +6 -0
- package/src/server/methods.ts +143 -0
- package/src/server/multipart.ts +424 -0
- package/src/server/node-outcome-hook.ts +40 -7
- package/src/server/not-found-answer.ts +109 -0
- package/src/server/not-found.ts +121 -0
- package/src/server/plugin.ts +45 -1
- package/src/server/proto-guard.ts +128 -9
- package/src/server/query.ts +49 -0
- package/src/server/registry.ts +17 -2
- package/src/server/request-context.ts +44 -16
- package/src/server/request-lineage.ts +15 -0
- package/src/server/request-target.ts +46 -0
- package/src/server/respond.ts +14 -3
- package/src/server/response-contract-lane.ts +97 -16
- package/src/server/response-observer-runtime.ts +37 -8
- package/src/server/runtime-core.ts +2 -0
- package/src/server/server-types.ts +59 -2
- package/src/server/server.ts +1613 -269
- package/src/server/sse.ts +10 -8
- package/src/server/static-headers.ts +22 -1
- package/src/server/transport-lane.ts +17 -9
- package/src/server/validation.ts +7 -1
- package/src/server/websocket.ts +23 -9
- package/src/server/ws-bun.ts +8 -3
- package/src/server/ws-hook.ts +2 -1
- package/src/server.ts +38 -2
- package/src/single-copy-register.ts +5 -0
- package/src/single-copy.ts +160 -12
- package/src/tool-contract.ts +66 -3
- package/src/transport-codec.ts +2 -1
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `all()` and `method()`. A method with no route on a path is still a `405`, and a runtime's HTTP
|
|
3
|
+
* parser may refuse a token it does not know before the server sees the request.
|
|
4
|
+
*/
|
|
5
|
+
import { RouteConfigError } from "../errors.js";
|
|
6
|
+
import { isRegistrableMethod, METHODS } from "../router/router.js";
|
|
7
|
+
const ASCII_NAME = /^[A-Za-z0-9-]+$/;
|
|
8
|
+
function plugin(methods, path, schemaOrHandler, handler) {
|
|
9
|
+
const schema = handler === undefined ? undefined : schemaOrHandler;
|
|
10
|
+
const run = handler ?? schemaOrHandler;
|
|
11
|
+
if (typeof run !== "function")
|
|
12
|
+
throw new TypeError("a route needs a handler function");
|
|
13
|
+
const routes = methods.map((method) => ({ method, path, schema, handler: run }));
|
|
14
|
+
return (app) => {
|
|
15
|
+
app.registerBatch(routes);
|
|
16
|
+
return app;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export function all(path, schemaOrHandler, handler) {
|
|
20
|
+
return plugin(METHODS, path, schemaOrHandler, handler);
|
|
21
|
+
}
|
|
22
|
+
export function method(name, path, schemaOrHandler, handler) {
|
|
23
|
+
const names = typeof name === "string" ? [name] : name;
|
|
24
|
+
if (!Array.isArray(names) || names.length === 0) {
|
|
25
|
+
throw new RouteConfigError("INVALID_METHOD", "method() needs a method name or a list of them");
|
|
26
|
+
}
|
|
27
|
+
const methods = names.map((value) => {
|
|
28
|
+
// Checked before the case fold: a letter outside ASCII can fold to an ASCII one.
|
|
29
|
+
const upper = typeof value === "string" && ASCII_NAME.test(value) ? value.toUpperCase() : "";
|
|
30
|
+
if (!isRegistrableMethod(upper)) {
|
|
31
|
+
throw new RouteConfigError("INVALID_METHOD", `unsupported HTTP method ${JSON.stringify(value)}`);
|
|
32
|
+
}
|
|
33
|
+
return upper;
|
|
34
|
+
});
|
|
35
|
+
return plugin(methods, path, schemaOrHandler, handler);
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=methods.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"methods.js","sourceRoot":"","sources":["../../src/server/methods.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,EAAE,mBAAmB,EAAE,OAAO,EAAe,MAAM,qBAAqB,CAAA;AAsB/E,MAAM,UAAU,GAAG,iBAAiB,CAAA;AAEpC,SAAS,MAAM,CACb,OAA0B,EAC1B,IAAY,EACZ,eAA4C,EAC5C,OAAkC;IAElC,MAAM,MAAM,GAAG,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAE,eAA+B,CAAA;IACnF,MAAM,GAAG,GAAG,OAAO,IAAI,eAAe,CAAA;IACtC,IAAI,OAAO,GAAG,KAAK,UAAU;QAAE,MAAM,IAAI,SAAS,CAAC,kCAAkC,CAAC,CAAA;IACtF,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,CAAA;IAChF,OAAO,CAAC,GAAG,EAAE,EAAE;QACb,GAAG,CAAC,aAAa,CAAC,MAAM,CAAC,CAAA;QACzB,OAAO,GAAG,CAAA;IACZ,CAAC,CAAA;AACH,CAAC;AA2BD,MAAM,UAAU,GAAG,CACjB,IAAY,EACZ,eAA4C,EAC5C,OAAuB;IAEvB,OAAO,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,CAAC,CAAA;AACxD,CAAC;AA4CD,MAAM,UAAU,MAAM,CACpB,IAAgC,EAChC,IAAY,EACZ,eAA4C,EAC5C,OAAuB;IAEvB,MAAM,KAAK,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IACtD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChD,MAAM,IAAI,gBAAgB,CAAC,gBAAgB,EAAE,gDAAgD,CAAC,CAAA;IAChG,CAAC;IACD,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,KAAc,EAAE,EAAE;QAC3C,iFAAiF;QACjF,MAAM,KAAK,GAAG,OAAO,KAAK,KAAK,QAAQ,IAAI,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;QAC5F,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC,EAAE,CAAC;YAChC,MAAM,IAAI,gBAAgB,CACxB,gBAAgB,EAChB,2BAA2B,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CACnD,CAAA;QACH,CAAC;QACD,OAAO,KAAK,CAAA;IACd,CAAC,CAAC,CAAA;IACF,OAAO,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,CAAC,CAAA;AACxD,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed `multipart/form-data` request bodies - `multipartBody(schema, limits?)`.
|
|
3
|
+
*
|
|
4
|
+
* A route reads JSON and urlencoded bodies by default and answers `415` to everything else. Wrapping
|
|
5
|
+
* its body schema opts that one route into multipart: the parts are read under the route's
|
|
6
|
+
* `bodyLimit`, bounded by count and size, collected into one record, and handed to the schema.
|
|
7
|
+
*
|
|
8
|
+
* import { multipartBody } from "@nifrajs/core/multipart"
|
|
9
|
+
* import { t } from "@nifrajs/schema"
|
|
10
|
+
*
|
|
11
|
+
* app.post(
|
|
12
|
+
* "/avatars",
|
|
13
|
+
* {
|
|
14
|
+
* body: multipartBody(
|
|
15
|
+
* t.form({ avatar: t.file({ maxBytes: 2_000_000, accept: ["image/png"] }), alt: t.string() }),
|
|
16
|
+
* ),
|
|
17
|
+
* bodyLimit: 2_500_000,
|
|
18
|
+
* },
|
|
19
|
+
* (c) => store(c.body.avatar),
|
|
20
|
+
* )
|
|
21
|
+
*
|
|
22
|
+
* The schema sees a null-prototype record: a text part is a string, a file part is a `File`, and a
|
|
23
|
+
* name that repeats becomes an array in part order. A file part with no bytes is left out: that is
|
|
24
|
+
* what an empty file input submits, so an optional file field validates as absent.
|
|
25
|
+
*
|
|
26
|
+
* What the reader guarantees before the schema runs:
|
|
27
|
+
* - the body is at most `bodyLimit` bytes, measured on the bytes delivered and not on the header
|
|
28
|
+
* - at most `maxFields + maxFiles` parts, counted on the raw bytes before anything is parsed
|
|
29
|
+
* - one boundary, taken from the header by one strict grammar and handed to the parser as-is
|
|
30
|
+
* - every text value is at most `maxFieldBytes` and every file at most `maxFileBytes`
|
|
31
|
+
* - a file name is a bare name: no directory, no control or bidirectional-override characters
|
|
32
|
+
* - a `__proto__` part follows the app's prototype-poisoning policy
|
|
33
|
+
*
|
|
34
|
+
* What it does not: a file's `name` and `type` are still the client's claim. Check content with a
|
|
35
|
+
* schema that reads the bytes, and store uploads under a key you generate.
|
|
36
|
+
*
|
|
37
|
+
* The whole body is buffered, so a request costs about twice its size in memory while it is parsed.
|
|
38
|
+
* Send large uploads straight to storage with a presigned URL instead of raising `bodyLimit`.
|
|
39
|
+
*/
|
|
40
|
+
import type { StandardSchemaV1 } from "../schema/standard.js";
|
|
41
|
+
/** Per-route bounds on a multipart body. The total size is the route's `bodyLimit`. */
|
|
42
|
+
export interface MultipartLimits {
|
|
43
|
+
/** Most text parts a request may carry. Default `100`. */
|
|
44
|
+
readonly maxFields?: number;
|
|
45
|
+
/** Most file parts a request may carry. Empty files are not counted. Default `10`. */
|
|
46
|
+
readonly maxFiles?: number;
|
|
47
|
+
/** Largest text value, in UTF-8 bytes. Default `65536`. */
|
|
48
|
+
readonly maxFieldBytes?: number;
|
|
49
|
+
/** Largest single file, in bytes. Defaults to no bound beyond the route's `bodyLimit`. */
|
|
50
|
+
readonly maxFileBytes?: number;
|
|
51
|
+
}
|
|
52
|
+
/** A value of the record handed to the schema: one part, or every part that shared the name. */
|
|
53
|
+
export type MultipartValue = string | File | Array<string | File>;
|
|
54
|
+
/**
|
|
55
|
+
* Opt a route's body schema into `multipart/form-data`. Returns a copy of `schema` that also reads
|
|
56
|
+
* multipart bodies; the schema itself is not changed, and JSON and urlencoded bodies still reach it.
|
|
57
|
+
* Opting in a schema that already was replaces its limits, and a schema that reads another media
|
|
58
|
+
* type through a parser of its own keeps reading it.
|
|
59
|
+
*
|
|
60
|
+
* Throws a `RangeError` for a limit that is not a non-negative safe integer.
|
|
61
|
+
*/
|
|
62
|
+
export declare function multipartBody<Schema extends StandardSchemaV1>(schema: Schema, limits?: MultipartLimits): Schema;
|
|
63
|
+
//# sourceMappingURL=multipart.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"multipart.d.ts","sourceRoot":"","sources":["../../src/server/multipart.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAM7D,uFAAuF;AACvF,MAAM,WAAW,eAAe;IAC9B,0DAA0D;IAC1D,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B,sFAAsF;IACtF,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;IAC1B,2DAA2D;IAC3D,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAA;IAC/B,0FAA0F;IAC1F,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAC/B;AAED,gGAAgG;AAChG,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,IAAI,GAAG,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;AAiVjE;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,MAAM,SAAS,gBAAgB,EAC3D,MAAM,EAAE,MAAM,EACd,MAAM,GAAE,eAAoB,GAC3B,MAAM,CAiBR"}
|
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
import { assertByteLimit, readBoundedBytes, UNLIMITED_BODY_BYTES } from "./body.js";
|
|
2
|
+
import { SCHEMA_BODY_READER } from "./body-lane.js";
|
|
3
|
+
import { plainError } from "./http.js";
|
|
4
|
+
const DEFAULT_MAX_FIELDS = 100;
|
|
5
|
+
const DEFAULT_MAX_FILES = 10;
|
|
6
|
+
const DEFAULT_MAX_FIELD_BYTES = 65_536;
|
|
7
|
+
const MEDIA_TYPE = "multipart/form-data";
|
|
8
|
+
// RFC 2046 `bchars` without the space: what a boundary may be made of.
|
|
9
|
+
const BOUNDARY = /^[0-9A-Za-z'()+_,\-./:=?]{1,70}$/;
|
|
10
|
+
// RFC 9110 `token`: a parameter name, and a value that needs no quoting.
|
|
11
|
+
const TOKEN = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
|
|
12
|
+
const FALLBACK_FILE_NAME = "file";
|
|
13
|
+
const MAX_FILE_NAME_LENGTH = 255;
|
|
14
|
+
const DASH = 45;
|
|
15
|
+
const QUOTE = 34;
|
|
16
|
+
const BACKSLASH = 92;
|
|
17
|
+
const SLASH = 47;
|
|
18
|
+
const SEMICOLON = 59;
|
|
19
|
+
const SPACE = 32;
|
|
20
|
+
const TAB = 9;
|
|
21
|
+
const INVALID = () => plainError(400, "invalid_multipart");
|
|
22
|
+
function limitOf(value, fallback, name) {
|
|
23
|
+
if (value === undefined)
|
|
24
|
+
return fallback;
|
|
25
|
+
assertByteLimit(value, `multipartBody: ${name}`);
|
|
26
|
+
return value;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* The boundary of a `multipart/form-data` content type. `undefined` when the media type is another
|
|
30
|
+
* one, `null` when it is multipart but its parameters are malformed, repeat `boundary`, or carry a
|
|
31
|
+
* boundary outside the RFC 2046 alphabet.
|
|
32
|
+
*/
|
|
33
|
+
function boundaryOf(contentType) {
|
|
34
|
+
const semi = contentType.indexOf(";");
|
|
35
|
+
const essence = (semi === -1 ? contentType : contentType.slice(0, semi)).trim().toLowerCase();
|
|
36
|
+
if (essence !== MEDIA_TYPE)
|
|
37
|
+
return undefined;
|
|
38
|
+
if (semi === -1)
|
|
39
|
+
return null;
|
|
40
|
+
const end = contentType.length;
|
|
41
|
+
let boundary;
|
|
42
|
+
let i = semi;
|
|
43
|
+
while (i < end) {
|
|
44
|
+
i++; // past the `;`
|
|
45
|
+
while (i < end && isBlank(contentType.charCodeAt(i)))
|
|
46
|
+
i++;
|
|
47
|
+
if (i >= end)
|
|
48
|
+
break;
|
|
49
|
+
const eq = contentType.indexOf("=", i);
|
|
50
|
+
if (eq === -1)
|
|
51
|
+
return null;
|
|
52
|
+
const name = contentType.slice(i, eq);
|
|
53
|
+
if (!TOKEN.test(name))
|
|
54
|
+
return null;
|
|
55
|
+
i = eq + 1;
|
|
56
|
+
let value;
|
|
57
|
+
if (contentType.charCodeAt(i) === QUOTE) {
|
|
58
|
+
let close = i + 1;
|
|
59
|
+
while (close < end && contentType.charCodeAt(close) !== QUOTE) {
|
|
60
|
+
close += contentType.charCodeAt(close) === BACKSLASH ? 2 : 1;
|
|
61
|
+
}
|
|
62
|
+
if (close >= end)
|
|
63
|
+
return null;
|
|
64
|
+
// Kept raw: an escaped character is outside the boundary alphabet, so it fails the test below.
|
|
65
|
+
value = contentType.slice(i + 1, close);
|
|
66
|
+
i = close + 1;
|
|
67
|
+
while (i < end && isBlank(contentType.charCodeAt(i)))
|
|
68
|
+
i++;
|
|
69
|
+
if (i < end && contentType.charCodeAt(i) !== SEMICOLON)
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
const next = contentType.indexOf(";", i);
|
|
74
|
+
const stop = next === -1 ? end : next;
|
|
75
|
+
value = contentType.slice(i, stop).trimEnd();
|
|
76
|
+
i = stop;
|
|
77
|
+
}
|
|
78
|
+
if (name.toLowerCase() !== "boundary")
|
|
79
|
+
continue;
|
|
80
|
+
if (boundary !== undefined || !BOUNDARY.test(value))
|
|
81
|
+
return null;
|
|
82
|
+
boundary = value;
|
|
83
|
+
}
|
|
84
|
+
return boundary ?? null;
|
|
85
|
+
}
|
|
86
|
+
function isBlank(code) {
|
|
87
|
+
return code === SPACE || code === TAB;
|
|
88
|
+
}
|
|
89
|
+
function failureTable(pattern) {
|
|
90
|
+
const table = new Uint8Array(pattern.length);
|
|
91
|
+
for (let i = 1, k = 0; i < pattern.length; i++) {
|
|
92
|
+
while (k > 0 && pattern[i] !== pattern[k])
|
|
93
|
+
k = table[k - 1];
|
|
94
|
+
if (pattern[i] === pattern[k])
|
|
95
|
+
k++;
|
|
96
|
+
table[i] = k;
|
|
97
|
+
}
|
|
98
|
+
return table;
|
|
99
|
+
}
|
|
100
|
+
/** `end` is the index after the last delimiter, or -1 when there was none. */
|
|
101
|
+
function delimiters(bytes, count, end) {
|
|
102
|
+
return { count, closed: end !== -1 && bytes[end] === DASH && bytes[end + 1] === DASH };
|
|
103
|
+
}
|
|
104
|
+
/** Knuth-Morris-Pratt from `start`: linear in the input whatever the pattern repeats. */
|
|
105
|
+
function scanFrom(bytes, pattern, start, counted, lastEnd, limit) {
|
|
106
|
+
const table = failureTable(pattern);
|
|
107
|
+
const size = pattern.length;
|
|
108
|
+
let count = counted;
|
|
109
|
+
let end = lastEnd;
|
|
110
|
+
for (let i = start, k = 0; i < bytes.length; i++) {
|
|
111
|
+
const byte = bytes[i];
|
|
112
|
+
while (k > 0 && byte !== pattern[k])
|
|
113
|
+
k = table[k - 1];
|
|
114
|
+
if (byte === pattern[k])
|
|
115
|
+
k++;
|
|
116
|
+
if (k === size) {
|
|
117
|
+
end = i + 1;
|
|
118
|
+
if (++count > limit)
|
|
119
|
+
break;
|
|
120
|
+
k = 0;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return delimiters(bytes, count, end);
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Find the non-overlapping occurrences of `pattern` (which starts with a dash), stopping once the
|
|
127
|
+
* count passes `limit`. Every `--boundary` is counted wherever it sits, which is at least what any
|
|
128
|
+
* parser can treat as a delimiter.
|
|
129
|
+
*
|
|
130
|
+
* The native search for the next dash skips binary content at memory speed. A body built to make
|
|
131
|
+
* the verify loop re-read the same bytes (dashes against a boundary of dashes) spends a budget of
|
|
132
|
+
* one pass over the input, then the scan continues with the linear matcher.
|
|
133
|
+
*/
|
|
134
|
+
function scanDelimiters(bytes, pattern, limit) {
|
|
135
|
+
const size = pattern.length;
|
|
136
|
+
const last = bytes.length - size;
|
|
137
|
+
let count = 0;
|
|
138
|
+
let end = -1;
|
|
139
|
+
let work = 0;
|
|
140
|
+
let i = 0;
|
|
141
|
+
while (i <= last) {
|
|
142
|
+
i = bytes.indexOf(DASH, i);
|
|
143
|
+
if (i === -1 || i > last)
|
|
144
|
+
break;
|
|
145
|
+
let k = 1;
|
|
146
|
+
while (k < size && bytes[i + k] === pattern[k])
|
|
147
|
+
k++;
|
|
148
|
+
if (k === size) {
|
|
149
|
+
i += size;
|
|
150
|
+
end = i;
|
|
151
|
+
if (++count > limit)
|
|
152
|
+
break;
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
work += k;
|
|
156
|
+
if (work > bytes.length)
|
|
157
|
+
return scanFrom(bytes, pattern, i, count, end, limit);
|
|
158
|
+
i++;
|
|
159
|
+
}
|
|
160
|
+
return delimiters(bytes, count, end);
|
|
161
|
+
}
|
|
162
|
+
/** True when `value` takes more than `max` bytes as UTF-8. */
|
|
163
|
+
function exceedsUtf8(value, max) {
|
|
164
|
+
const length = value.length;
|
|
165
|
+
// A UTF-16 code unit is one to three UTF-8 bytes, so most values are decided without a walk.
|
|
166
|
+
if (length > max)
|
|
167
|
+
return true;
|
|
168
|
+
if (length * 3 <= max)
|
|
169
|
+
return false;
|
|
170
|
+
let bytes = 0;
|
|
171
|
+
for (let i = 0; i < length; i++) {
|
|
172
|
+
const code = value.charCodeAt(i);
|
|
173
|
+
if (code < 0x80)
|
|
174
|
+
bytes += 1;
|
|
175
|
+
else if (code < 0x800)
|
|
176
|
+
bytes += 2;
|
|
177
|
+
else if (code >= 0xd800 && code <= 0xdbff && i + 1 < length) {
|
|
178
|
+
const low = value.charCodeAt(i + 1);
|
|
179
|
+
if (low >= 0xdc00 && low <= 0xdfff) {
|
|
180
|
+
bytes += 4;
|
|
181
|
+
i++;
|
|
182
|
+
}
|
|
183
|
+
else
|
|
184
|
+
bytes += 3;
|
|
185
|
+
}
|
|
186
|
+
else
|
|
187
|
+
bytes += 3;
|
|
188
|
+
if (bytes > max)
|
|
189
|
+
return true;
|
|
190
|
+
}
|
|
191
|
+
return false;
|
|
192
|
+
}
|
|
193
|
+
/** C0 controls, DEL, line separators, and the characters that reorder or hide text in a label. */
|
|
194
|
+
function isUnsafeNameCode(code) {
|
|
195
|
+
return (code < 0x20 ||
|
|
196
|
+
code === 0x7f ||
|
|
197
|
+
code === 0x200e ||
|
|
198
|
+
code === 0x200f ||
|
|
199
|
+
(code >= 0x2028 && code <= 0x202e) ||
|
|
200
|
+
(code >= 0x2066 && code <= 0x2069));
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* A client file name reduced to a bare name: the text after the last `/` or `\`, without control
|
|
204
|
+
* and bidirectional characters, at most 255 code units. A name with nothing left is `"file"`.
|
|
205
|
+
*/
|
|
206
|
+
function safeFileName(raw) {
|
|
207
|
+
let start = 0;
|
|
208
|
+
let dirty = false;
|
|
209
|
+
for (let i = 0; i < raw.length; i++) {
|
|
210
|
+
const code = raw.charCodeAt(i);
|
|
211
|
+
if (code === SLASH || code === BACKSLASH) {
|
|
212
|
+
start = i + 1;
|
|
213
|
+
dirty = false;
|
|
214
|
+
}
|
|
215
|
+
else if (isUnsafeNameCode(code))
|
|
216
|
+
dirty = true;
|
|
217
|
+
}
|
|
218
|
+
let name = raw;
|
|
219
|
+
if (dirty) {
|
|
220
|
+
name = "";
|
|
221
|
+
for (let i = start; i < raw.length; i++) {
|
|
222
|
+
if (!isUnsafeNameCode(raw.charCodeAt(i)))
|
|
223
|
+
name += raw[i];
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
else if (start > 0)
|
|
227
|
+
name = raw.slice(start);
|
|
228
|
+
name = name.trim();
|
|
229
|
+
if (name.length > MAX_FILE_NAME_LENGTH) {
|
|
230
|
+
const lastKept = name.charCodeAt(MAX_FILE_NAME_LENGTH - 1);
|
|
231
|
+
// Never end on the first half of a surrogate pair.
|
|
232
|
+
const cut = lastKept >= 0xd800 && lastKept <= 0xdbff ? 1 : 0;
|
|
233
|
+
name = name.slice(0, MAX_FILE_NAME_LENGTH - cut).trimEnd();
|
|
234
|
+
}
|
|
235
|
+
return name === "" || name === "." || name === ".." ? FALLBACK_FILE_NAME : name;
|
|
236
|
+
}
|
|
237
|
+
/** `part` as a `File` called `name`, keeping its bytes, type, and timestamp. */
|
|
238
|
+
function renamedFile(part, name) {
|
|
239
|
+
const modified = part.lastModified;
|
|
240
|
+
const options = modified === undefined ? { type: part.type } : { type: part.type, lastModified: modified };
|
|
241
|
+
let file = new File([part], name, options);
|
|
242
|
+
// A runtime may hand back the single source part with its own name when nothing else changes;
|
|
243
|
+
// a second, empty part forces a new file.
|
|
244
|
+
if (file.name !== name)
|
|
245
|
+
file = new File([part, ""], name, options);
|
|
246
|
+
if (file.name !== name || file.size !== part.size) {
|
|
247
|
+
throw new Error("multipartBody: this runtime did not apply a file name");
|
|
248
|
+
}
|
|
249
|
+
return file;
|
|
250
|
+
}
|
|
251
|
+
function createReader(limits, inner) {
|
|
252
|
+
const maxFields = limitOf(limits.maxFields, DEFAULT_MAX_FIELDS, "maxFields");
|
|
253
|
+
const maxFiles = limitOf(limits.maxFiles, DEFAULT_MAX_FILES, "maxFiles");
|
|
254
|
+
const maxFieldBytes = limitOf(limits.maxFieldBytes, DEFAULT_MAX_FIELD_BYTES, "maxFieldBytes");
|
|
255
|
+
const maxFileBytes = limitOf(limits.maxFileBytes, UNLIMITED_BODY_BYTES, "maxFileBytes");
|
|
256
|
+
// Every part sits between two delimiters, and the last delimiter closes the body.
|
|
257
|
+
const maxDelimiters = maxFields + maxFiles + 1;
|
|
258
|
+
const read = async (source, contentType, maxBodyBytes, protoPoisoning) => {
|
|
259
|
+
const boundary = boundaryOf(contentType);
|
|
260
|
+
if (boundary === undefined) {
|
|
261
|
+
// Not a multipart body: a reader the schema already carried for another media type takes it.
|
|
262
|
+
return inner === undefined
|
|
263
|
+
? plainError(415, "unsupported_media_type")
|
|
264
|
+
: inner(source, contentType, maxBodyBytes, protoPoisoning);
|
|
265
|
+
}
|
|
266
|
+
if (boundary === null)
|
|
267
|
+
return INVALID();
|
|
268
|
+
const read = await readBoundedBytes(source, maxBodyBytes);
|
|
269
|
+
if (!read.ok) {
|
|
270
|
+
return read.status === 413
|
|
271
|
+
? plainError(413, "payload_too_large")
|
|
272
|
+
: plainError(400, "invalid_content_length");
|
|
273
|
+
}
|
|
274
|
+
const bytes = read.bytes;
|
|
275
|
+
// Counted on the raw bytes: the platform parser allocates per part, so a body of many tiny
|
|
276
|
+
// parts must be refused before it is parsed, not after.
|
|
277
|
+
const delimiter = new Uint8Array(boundary.length + 2);
|
|
278
|
+
delimiter[0] = DASH;
|
|
279
|
+
delimiter[1] = DASH;
|
|
280
|
+
for (let i = 0; i < boundary.length; i++)
|
|
281
|
+
delimiter[i + 2] = boundary.charCodeAt(i);
|
|
282
|
+
const found = scanDelimiters(bytes, delimiter, maxDelimiters);
|
|
283
|
+
if (found.count > maxDelimiters)
|
|
284
|
+
return plainError(413, "too_many_parts");
|
|
285
|
+
// A body is over when `--boundary--` says so. One that stops short is refused here, because a
|
|
286
|
+
// parser that tolerates it hands back the parts it saw as if they were the whole form.
|
|
287
|
+
if (!found.closed)
|
|
288
|
+
return INVALID();
|
|
289
|
+
// The parser is given the boundary this reader extracted, never the request's own header: two
|
|
290
|
+
// readings of one header (a repeated or oddly quoted parameter) would let a body be counted
|
|
291
|
+
// under one boundary and parsed under another.
|
|
292
|
+
const canonical = `${MEDIA_TYPE}; boundary=${TOKEN.test(boundary) ? boundary : `"${boundary}"`}`;
|
|
293
|
+
// Typed by what is read from it: the global `FormData` and `BodyInit` names do not resolve to
|
|
294
|
+
// the same declarations under every lib config.
|
|
295
|
+
let form;
|
|
296
|
+
try {
|
|
297
|
+
form = (await new Response(bytes, {
|
|
298
|
+
headers: { "content-type": canonical },
|
|
299
|
+
}).formData());
|
|
300
|
+
}
|
|
301
|
+
catch {
|
|
302
|
+
return INVALID();
|
|
303
|
+
}
|
|
304
|
+
const record = Object.create(null);
|
|
305
|
+
let fields = 0;
|
|
306
|
+
let files = 0;
|
|
307
|
+
for (const [name, part] of form) {
|
|
308
|
+
if (name === "__proto__" && protoPoisoning !== "ignore") {
|
|
309
|
+
if (protoPoisoning === "reject")
|
|
310
|
+
return INVALID();
|
|
311
|
+
continue;
|
|
312
|
+
}
|
|
313
|
+
let value;
|
|
314
|
+
if (typeof part === "string") {
|
|
315
|
+
if (++fields > maxFields)
|
|
316
|
+
return plainError(413, "too_many_fields");
|
|
317
|
+
if (exceedsUtf8(part, maxFieldBytes))
|
|
318
|
+
return plainError(413, "field_too_large");
|
|
319
|
+
value = part;
|
|
320
|
+
}
|
|
321
|
+
else {
|
|
322
|
+
// A file input left empty still submits a part with no bytes. Runtimes disagree on whether
|
|
323
|
+
// a named empty file keeps its name, so every empty file is treated as that input.
|
|
324
|
+
if (part.size === 0)
|
|
325
|
+
continue;
|
|
326
|
+
const rawName = part.name;
|
|
327
|
+
const clientName = typeof rawName === "string" ? rawName : "";
|
|
328
|
+
if (++files > maxFiles)
|
|
329
|
+
return plainError(413, "too_many_files");
|
|
330
|
+
if (part.size > maxFileBytes)
|
|
331
|
+
return plainError(413, "file_too_large");
|
|
332
|
+
const name = safeFileName(clientName);
|
|
333
|
+
value = part instanceof File && part.name === name ? part : renamedFile(part, name);
|
|
334
|
+
}
|
|
335
|
+
const existing = record[name];
|
|
336
|
+
if (existing === undefined)
|
|
337
|
+
record[name] = value;
|
|
338
|
+
else if (Array.isArray(existing))
|
|
339
|
+
existing.push(value);
|
|
340
|
+
else
|
|
341
|
+
record[name] = [existing, value];
|
|
342
|
+
}
|
|
343
|
+
return record;
|
|
344
|
+
};
|
|
345
|
+
const mediaTypes = inner?.mediaTypes;
|
|
346
|
+
return mediaTypes === undefined
|
|
347
|
+
? read
|
|
348
|
+
: Object.defineProperty(read, "mediaTypes", { value: mediaTypes });
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Opt a route's body schema into `multipart/form-data`. Returns a copy of `schema` that also reads
|
|
352
|
+
* multipart bodies; the schema itself is not changed, and JSON and urlencoded bodies still reach it.
|
|
353
|
+
* Opting in a schema that already was replaces its limits, and a schema that reads another media
|
|
354
|
+
* type through a parser of its own keeps reading it.
|
|
355
|
+
*
|
|
356
|
+
* Throws a `RangeError` for a limit that is not a non-negative safe integer.
|
|
357
|
+
*/
|
|
358
|
+
export function multipartBody(schema, limits = {}) {
|
|
359
|
+
const carried = schema[SCHEMA_BODY_READER];
|
|
360
|
+
const reader = {
|
|
361
|
+
value: createReader(limits, typeof carried === "function" ? carried : undefined),
|
|
362
|
+
};
|
|
363
|
+
if (typeof schema === "function") {
|
|
364
|
+
// A callable schema cannot be copied; an object that delegates to it reads the same.
|
|
365
|
+
return Object.defineProperty(Object.create(schema), SCHEMA_BODY_READER, reader);
|
|
366
|
+
}
|
|
367
|
+
// The reader goes in with the copied properties rather than after them: a schema that was already
|
|
368
|
+
// opted in carries a reader that cannot be redefined, and the limits given here replace its own.
|
|
369
|
+
return Object.create(Object.getPrototypeOf(schema), {
|
|
370
|
+
...Object.getOwnPropertyDescriptors(schema),
|
|
371
|
+
[SCHEMA_BODY_READER]: reader,
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
//# sourceMappingURL=multipart.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"multipart.js","sourceRoot":"","sources":["../../src/server/multipart.ts"],"names":[],"mappings":"AAwCA,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAA;AACnF,OAAO,EAAE,kBAAkB,EAAyB,MAAM,gBAAgB,CAAA;AAC1E,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AAkBtC,MAAM,kBAAkB,GAAG,GAAG,CAAA;AAC9B,MAAM,iBAAiB,GAAG,EAAE,CAAA;AAC5B,MAAM,uBAAuB,GAAG,MAAM,CAAA;AAEtC,MAAM,UAAU,GAAG,qBAAqB,CAAA;AACxC,uEAAuE;AACvE,MAAM,QAAQ,GAAG,kCAAkC,CAAA;AACnD,yEAAyE;AACzE,MAAM,KAAK,GAAG,gCAAgC,CAAA;AAC9C,MAAM,kBAAkB,GAAG,MAAM,CAAA;AACjC,MAAM,oBAAoB,GAAG,GAAG,CAAA;AAEhC,MAAM,IAAI,GAAG,EAAE,CAAA;AACf,MAAM,KAAK,GAAG,EAAE,CAAA;AAChB,MAAM,SAAS,GAAG,EAAE,CAAA;AACpB,MAAM,KAAK,GAAG,EAAE,CAAA;AAChB,MAAM,SAAS,GAAG,EAAE,CAAA;AACpB,MAAM,KAAK,GAAG,EAAE,CAAA;AAChB,MAAM,GAAG,GAAG,CAAC,CAAA;AAEb,MAAM,OAAO,GAAG,GAAmB,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,mBAAmB,CAAC,CAAA;AAE1E,SAAS,OAAO,CAAC,KAAyB,EAAE,QAAgB,EAAE,IAAY;IACxE,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,QAAQ,CAAA;IACxC,eAAe,CAAC,KAAK,EAAE,kBAAkB,IAAI,EAAE,CAAC,CAAA;IAChD,OAAO,KAAK,CAAA;AACd,CAAC;AAED;;;;GAIG;AACH,SAAS,UAAU,CAAC,WAAmB;IACrC,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IACrC,MAAM,OAAO,GAAG,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;IAC7F,IAAI,OAAO,KAAK,UAAU;QAAE,OAAO,SAAS,CAAA;IAC5C,IAAI,IAAI,KAAK,CAAC,CAAC;QAAE,OAAO,IAAI,CAAA;IAE5B,MAAM,GAAG,GAAG,WAAW,CAAC,MAAM,CAAA;IAC9B,IAAI,QAA4B,CAAA;IAChC,IAAI,CAAC,GAAG,IAAI,CAAA;IACZ,OAAO,CAAC,GAAG,GAAG,EAAE,CAAC;QACf,CAAC,EAAE,CAAA,CAAC,eAAe;QACnB,OAAO,CAAC,GAAG,GAAG,IAAI,OAAO,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YAAE,CAAC,EAAE,CAAA;QACzD,IAAI,CAAC,IAAI,GAAG;YAAE,MAAK;QACnB,MAAM,EAAE,GAAG,WAAW,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAA;QACtC,IAAI,EAAE,KAAK,CAAC,CAAC;YAAE,OAAO,IAAI,CAAA;QAC1B,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;QACrC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAA;QAClC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;QACV,IAAI,KAAa,CAAA;QACjB,IAAI,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,KAAK,EAAE,CAAC;YACxC,IAAI,KAAK,GAAG,CAAC,GAAG,CAAC,CAAA;YACjB,OAAO,KAAK,GAAG,GAAG,IAAI,WAAW,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,KAAK,EAAE,CAAC;gBAC9D,KAAK,IAAI,WAAW,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;YAC9D,CAAC;YACD,IAAI,KAAK,IAAI,GAAG;gBAAE,OAAO,IAAI,CAAA;YAC7B,+FAA+F;YAC/F,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,CAAA;YACvC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAA;YACb,OAAO,CAAC,GAAG,GAAG,IAAI,OAAO,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;gBAAE,CAAC,EAAE,CAAA;YACzD,IAAI,CAAC,GAAG,GAAG,IAAI,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,SAAS;gBAAE,OAAO,IAAI,CAAA;QACrE,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAA;YACxC,MAAM,IAAI,GAAG,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAA;YACrC,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,OAAO,EAAE,CAAA;YAC5C,CAAC,GAAG,IAAI,CAAA;QACV,CAAC;QACD,IAAI,IAAI,CAAC,WAAW,EAAE,KAAK,UAAU;YAAE,SAAQ;QAC/C,IAAI,QAAQ,KAAK,SAAS,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC;YAAE,OAAO,IAAI,CAAA;QAChE,QAAQ,GAAG,KAAK,CAAA;IAClB,CAAC;IACD,OAAO,QAAQ,IAAI,IAAI,CAAA;AACzB,CAAC;AAED,SAAS,OAAO,CAAC,IAAY;IAC3B,OAAO,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,GAAG,CAAA;AACvC,CAAC;AAED,SAAS,YAAY,CAAC,OAAmB;IACvC,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;IAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/C,OAAO,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC;YAAE,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAAE,CAAA;QAC5D,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC;YAAE,CAAC,EAAE,CAAA;QAClC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;IACd,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAQD,8EAA8E;AAC9E,SAAS,UAAU,CAAC,KAAiB,EAAE,KAAa,EAAE,GAAW;IAC/D,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,IAAI,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,KAAK,IAAI,EAAE,CAAA;AACxF,CAAC;AAED,yFAAyF;AACzF,SAAS,QAAQ,CACf,KAAiB,EACjB,OAAmB,EACnB,KAAa,EACb,OAAe,EACf,OAAe,EACf,KAAa;IAEb,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,CAAC,CAAA;IACnC,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAA;IAC3B,IAAI,KAAK,GAAG,OAAO,CAAA;IACnB,IAAI,GAAG,GAAG,OAAO,CAAA;IACjB,KAAK,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACjD,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;QACrB,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC;YAAE,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAAE,CAAA;QACtD,IAAI,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC;YAAE,CAAC,EAAE,CAAA;QAC5B,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;YACf,GAAG,GAAG,CAAC,GAAG,CAAC,CAAA;YACX,IAAI,EAAE,KAAK,GAAG,KAAK;gBAAE,MAAK;YAC1B,CAAC,GAAG,CAAC,CAAA;QACP,CAAC;IACH,CAAC;IACD,OAAO,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC,CAAA;AACtC,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,cAAc,CAAC,KAAiB,EAAE,OAAmB,EAAE,KAAa;IAC3E,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAA;IAC3B,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,GAAG,IAAI,CAAA;IAChC,IAAI,KAAK,GAAG,CAAC,CAAA;IACb,IAAI,GAAG,GAAG,CAAC,CAAC,CAAA;IACZ,IAAI,IAAI,GAAG,CAAC,CAAA;IACZ,IAAI,CAAC,GAAG,CAAC,CAAA;IACT,OAAO,CAAC,IAAI,IAAI,EAAE,CAAC;QACjB,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;QAC1B,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI;YAAE,MAAK;QAC/B,IAAI,CAAC,GAAG,CAAC,CAAA;QACT,OAAO,CAAC,GAAG,IAAI,IAAI,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC;YAAE,CAAC,EAAE,CAAA;QACnD,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;YACf,CAAC,IAAI,IAAI,CAAA;YACT,GAAG,GAAG,CAAC,CAAA;YACP,IAAI,EAAE,KAAK,GAAG,KAAK;gBAAE,MAAK;YAC1B,SAAQ;QACV,CAAC;QACD,IAAI,IAAI,CAAC,CAAA;QACT,IAAI,IAAI,GAAG,KAAK,CAAC,MAAM;YAAE,OAAO,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC,CAAA;QAC9E,CAAC,EAAE,CAAA;IACL,CAAC;IACD,OAAO,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC,CAAA;AACtC,CAAC;AAED,8DAA8D;AAC9D,SAAS,WAAW,CAAC,KAAa,EAAE,GAAW;IAC7C,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAA;IAC3B,6FAA6F;IAC7F,IAAI,MAAM,GAAG,GAAG;QAAE,OAAO,IAAI,CAAA;IAC7B,IAAI,MAAM,GAAG,CAAC,IAAI,GAAG;QAAE,OAAO,KAAK,CAAA;IACnC,IAAI,KAAK,GAAG,CAAC,CAAA;IACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAChC,MAAM,IAAI,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAA;QAChC,IAAI,IAAI,GAAG,IAAI;YAAE,KAAK,IAAI,CAAC,CAAA;aACtB,IAAI,IAAI,GAAG,KAAK;YAAE,KAAK,IAAI,CAAC,CAAA;aAC5B,IAAI,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,EAAE,CAAC;YAC5D,MAAM,GAAG,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;YACnC,IAAI,GAAG,IAAI,MAAM,IAAI,GAAG,IAAI,MAAM,EAAE,CAAC;gBACnC,KAAK,IAAI,CAAC,CAAA;gBACV,CAAC,EAAE,CAAA;YACL,CAAC;;gBAAM,KAAK,IAAI,CAAC,CAAA;QACnB,CAAC;;YAAM,KAAK,IAAI,CAAC,CAAA;QACjB,IAAI,KAAK,GAAG,GAAG;YAAE,OAAO,IAAI,CAAA;IAC9B,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED,kGAAkG;AAClG,SAAS,gBAAgB,CAAC,IAAY;IACpC,OAAO,CACL,IAAI,GAAG,IAAI;QACX,IAAI,KAAK,IAAI;QACb,IAAI,KAAK,MAAM;QACf,IAAI,KAAK,MAAM;QACf,CAAC,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC;QAClC,CAAC,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC,CACnC,CAAA;AACH,CAAC;AAED;;;GAGG;AACH,SAAS,YAAY,CAAC,GAAW;IAC/B,IAAI,KAAK,GAAG,CAAC,CAAA;IACb,IAAI,KAAK,GAAG,KAAK,CAAA;IACjB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACpC,MAAM,IAAI,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAA;QAC9B,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACzC,KAAK,GAAG,CAAC,GAAG,CAAC,CAAA;YACb,KAAK,GAAG,KAAK,CAAA;QACf,CAAC;aAAM,IAAI,gBAAgB,CAAC,IAAI,CAAC;YAAE,KAAK,GAAG,IAAI,CAAA;IACjD,CAAC;IACD,IAAI,IAAI,GAAG,GAAG,CAAA;IACd,IAAI,KAAK,EAAE,CAAC;QACV,IAAI,GAAG,EAAE,CAAA;QACT,KAAK,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACxC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;gBAAE,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,CAAA;QAC1D,CAAC;IACH,CAAC;SAAM,IAAI,KAAK,GAAG,CAAC;QAAE,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;IAC7C,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,CAAA;IAClB,IAAI,IAAI,CAAC,MAAM,GAAG,oBAAoB,EAAE,CAAC;QACvC,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,oBAAoB,GAAG,CAAC,CAAC,CAAA;QAC1D,mDAAmD;QACnD,MAAM,GAAG,GAAG,QAAQ,IAAI,MAAM,IAAI,QAAQ,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QAC5D,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,oBAAoB,GAAG,GAAG,CAAC,CAAC,OAAO,EAAE,CAAA;IAC5D,CAAC;IACD,OAAO,IAAI,KAAK,EAAE,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAA;AACjF,CAAC;AAED,gFAAgF;AAChF,SAAS,WAAW,CAAC,IAAU,EAAE,IAAY;IAC3C,MAAM,QAAQ,GAAI,IAAsB,CAAC,YAAY,CAAA;IACrD,MAAM,OAAO,GACX,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAA;IAC5F,IAAI,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;IAC1C,8FAA8F;IAC9F,0CAA0C;IAC1C,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI;QAAE,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;IAClE,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;QAClD,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAA;IAC1E,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED,SAAS,YAAY,CACnB,MAAuB,EACvB,KAAmC;IAEnC,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,kBAAkB,EAAE,WAAW,CAAC,CAAA;IAC5E,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,iBAAiB,EAAE,UAAU,CAAC,CAAA;IACxE,MAAM,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,uBAAuB,EAAE,eAAe,CAAC,CAAA;IAC7F,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,oBAAoB,EAAE,cAAc,CAAC,CAAA;IACvF,kFAAkF;IAClF,MAAM,aAAa,GAAG,SAAS,GAAG,QAAQ,GAAG,CAAC,CAAA;IAE9C,MAAM,IAAI,GAAqB,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,cAAc,EAAE,EAAE;QACzF,MAAM,QAAQ,GAAG,UAAU,CAAC,WAAW,CAAC,CAAA;QACxC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC3B,6FAA6F;YAC7F,OAAO,KAAK,KAAK,SAAS;gBACxB,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,wBAAwB,CAAC;gBAC3C,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,cAAc,CAAC,CAAA;QAC9D,CAAC;QACD,IAAI,QAAQ,KAAK,IAAI;YAAE,OAAO,OAAO,EAAE,CAAA;QAEvC,MAAM,IAAI,GAAG,MAAM,gBAAgB,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;QACzD,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;YACb,OAAO,IAAI,CAAC,MAAM,KAAK,GAAG;gBACxB,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,mBAAmB,CAAC;gBACtC,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,wBAAwB,CAAC,CAAA;QAC/C,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAA;QAExB,2FAA2F;QAC3F,wDAAwD;QACxD,MAAM,SAAS,GAAG,IAAI,UAAU,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;QACrD,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,CAAA;QACnB,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,CAAA;QACnB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE;YAAE,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAA;QACnF,MAAM,KAAK,GAAG,cAAc,CAAC,KAAK,EAAE,SAAS,EAAE,aAAa,CAAC,CAAA;QAC7D,IAAI,KAAK,CAAC,KAAK,GAAG,aAAa;YAAE,OAAO,UAAU,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAA;QACzE,8FAA8F;QAC9F,uFAAuF;QACvF,IAAI,CAAC,KAAK,CAAC,MAAM;YAAE,OAAO,OAAO,EAAE,CAAA;QAEnC,8FAA8F;QAC9F,4FAA4F;QAC5F,+CAA+C;QAC/C,MAAM,SAAS,GAAG,GAAG,UAAU,cAAc,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,QAAQ,GAAG,EAAE,CAAA;QAChG,8FAA8F;QAC9F,gDAAgD;QAChD,IAAI,IAAuC,CAAA;QAC3C,IAAI,CAAC;YACH,IAAI,GAAG,CAAC,MAAM,IAAI,QAAQ,CAAC,KAAkD,EAAE;gBAC7E,OAAO,EAAE,EAAE,cAAc,EAAE,SAAS,EAAE;aACvC,CAAC,CAAC,QAAQ,EAAE,CAAiD,CAAA;QAChE,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,OAAO,EAAE,CAAA;QAClB,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAmC,CAAA;QACpE,IAAI,MAAM,GAAG,CAAC,CAAA;QACd,IAAI,KAAK,GAAG,CAAC,CAAA;QACb,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;YAChC,IAAI,IAAI,KAAK,WAAW,IAAI,cAAc,KAAK,QAAQ,EAAE,CAAC;gBACxD,IAAI,cAAc,KAAK,QAAQ;oBAAE,OAAO,OAAO,EAAE,CAAA;gBACjD,SAAQ;YACV,CAAC;YACD,IAAI,KAAoB,CAAA;YACxB,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC7B,IAAI,EAAE,MAAM,GAAG,SAAS;oBAAE,OAAO,UAAU,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAA;gBACnE,IAAI,WAAW,CAAC,IAAI,EAAE,aAAa,CAAC;oBAAE,OAAO,UAAU,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAA;gBAC/E,KAAK,GAAG,IAAI,CAAA;YACd,CAAC;iBAAM,CAAC;gBACN,2FAA2F;gBAC3F,mFAAmF;gBACnF,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC;oBAAE,SAAQ;gBAC7B,MAAM,OAAO,GAAI,IAAsB,CAAC,IAAI,CAAA;gBAC5C,MAAM,UAAU,GAAG,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAA;gBAC7D,IAAI,EAAE,KAAK,GAAG,QAAQ;oBAAE,OAAO,UAAU,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAA;gBAChE,IAAI,IAAI,CAAC,IAAI,GAAG,YAAY;oBAAE,OAAO,UAAU,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAA;gBACtE,MAAM,IAAI,GAAG,YAAY,CAAC,UAAU,CAAC,CAAA;gBACrC,KAAK,GAAG,IAAI,YAAY,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;YACrF,CAAC;YACD,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,CAAA;YAC7B,IAAI,QAAQ,KAAK,SAAS;gBAAE,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAA;iBAC3C,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;gBAAE,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;;gBACjD,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;QACvC,CAAC;QACD,OAAO,MAAM,CAAA;IACf,CAAC,CAAA;IACD,MAAM,UAAU,GAAG,KAAK,EAAE,UAAU,CAAA;IACpC,OAAO,UAAU,KAAK,SAAS;QAC7B,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,YAAY,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAA;AACtE,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAC3B,MAAc,EACd,SAA0B,EAAE;IAE5B,MAAM,OAAO,GAAI,MAA+D,CAC9E,kBAAkB,CACnB,CAAA;IACD,MAAM,MAAM,GAAuB;QACjC,KAAK,EAAE,YAAY,CAAC,MAAM,EAAE,OAAO,OAAO,KAAK,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;KACjF,CAAA;IACD,IAAI,OAAO,MAAM,KAAK,UAAU,EAAE,CAAC;QACjC,qFAAqF;QACrF,OAAO,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,kBAAkB,EAAE,MAAM,CAAW,CAAA;IAC3F,CAAC;IACD,kGAAkG;IAClG,iGAAiG;IACjG,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE;QAClD,GAAG,MAAM,CAAC,yBAAyB,CAAC,MAAM,CAAC;QAC3C,CAAC,kBAAkB,CAAC,EAAE,MAAM;KAC7B,CAAW,CAAA;AACd,CAAC"}
|
|
@@ -52,6 +52,8 @@ export interface NodeResponseContext {
|
|
|
52
52
|
/** Mutable ONLY through a body hook's replacement object (e.g. an ETag 304); header hooks read. */
|
|
53
53
|
status: number;
|
|
54
54
|
headers: Record<string, string | readonly string[]> | undefined;
|
|
55
|
+
/** True when core has proved the record uses lowercase wire names before native hooks run. */
|
|
56
|
+
readonly headersAreLowercase?: boolean;
|
|
55
57
|
readonly cookies: readonly string[] | undefined;
|
|
56
58
|
/** The framework-serialized body bytes (`null` for a bodiless render). Replaceable by body hooks. */
|
|
57
59
|
body: string | Uint8Array | null;
|
|
@@ -70,6 +72,24 @@ export interface ResponseBodyReplacement {
|
|
|
70
72
|
* by definition - transforming those is exactly what the full `onResponse` contract is for.
|
|
71
73
|
*/
|
|
72
74
|
export type ResponseBodyHook = (body: string | Uint8Array, headers: ResponseHeadersView, req: NodeRequestContext, status: number) => MaybePromise<string | Uint8Array | ResponseBodyReplacement | undefined>;
|
|
75
|
+
/**
|
|
76
|
+
* Native equivalent of a paired `onResponseBody` hook - the body tier's twin, mirroring what
|
|
77
|
+
* `onNodeResponseHeaders` is to `onResponseHeaders`. It receives the same already-serialized bytes
|
|
78
|
+
* the portable hook would (never `null` - bodiless renders skip the twin exactly as they skip the
|
|
79
|
+
* portable hook) plus the outcome record itself, so a twin that only reads the bytes and writes
|
|
80
|
+
* headers pays no header-view allocation. It returns through the same replacement channel
|
|
81
|
+
* (`undefined` keeps the body; bytes or a `{ body, status }` replacement is applied by the shared
|
|
82
|
+
* `applyBodyReplacement`), so a twin and its portable hook are observably identical.
|
|
83
|
+
*
|
|
84
|
+
* Header writes go straight to `response.headers`, whose contract is the lowercase wire spelling
|
|
85
|
+
* (the same contract `setNodeHeader` documents): a plain assignment of a name like `__proto__`
|
|
86
|
+
* hits the inherited setter and is an inert no-op rather than pollution - `c.set.headers` behaves
|
|
87
|
+
* the same way - so a header that must round-trip under that name needs `defineProperty`. The
|
|
88
|
+
* twin must preserve its portable hook's observable header/body/status semantics; direct `body`
|
|
89
|
+
* or `status` writes outside the return channel are still honored deterministically by the finish
|
|
90
|
+
* step, but they have no portable equivalent, so prefer the return.
|
|
91
|
+
*/
|
|
92
|
+
export type NodeResponseBodyHook = (body: string | Uint8Array, response: NodeResponseContext, req: NodeRequestContext, status: number) => MaybePromise<string | Uint8Array | ResponseBodyReplacement | undefined>;
|
|
73
93
|
/** Native equivalent of a paired `onResponse` hook. It must preserve the Web hook's header semantics. */
|
|
74
94
|
export type NodeResponseHook = (response: NodeResponseContext, req: NodeRequestContext) => MaybePromise<void>;
|
|
75
95
|
export declare function recordHeadersView(target: NodeResponseContext): ResponseHeadersView;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node-outcome-hook.d.ts","sourceRoot":"","sources":["../../src/server/node-outcome-hook.ts"],"names":[],"mappings":"AAAA,qGAAqG;AAErG,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAE5C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAEvD;;;;;;;GAOG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAA;CACjD;AAED;;;;;;GAMG;AACH,MAAM,WAAW,mBAAmB;IAClC,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;IAChC,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAA;IAC1B,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACtC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACzC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAC3B;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,mBAAmB,GAAG,CAChC,OAAO,EAAE,mBAAmB,EAC5B,GAAG,EAAE,kBAAkB,EACvB,MAAM,EAAE,MAAM,KACX,YAAY,CAAC,IAAI,CAAC,CAAA;AAEvB,0GAA0G;AAC1G,MAAM,MAAM,eAAe,GAAG,CAC5B,OAAO,EAAE,kBAAkB,EAC3B,QAAQ,CAAC,EAAE,QAAQ,KAChB,YAAY,CAAC,QAAQ,GAAG,SAAS,CAAC,CAAA;AAEvC;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,mGAAmG;IACnG,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC,GAAG,SAAS,CAAA;IAC/D,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAA;IAC/C,qGAAqG;IACrG,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAAA;CACjC;AAED,oGAAoG;AACpG,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAAA;IAC1C,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CACzB;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAC7B,IAAI,EAAE,MAAM,GAAG,UAAU,EACzB,OAAO,EAAE,mBAAmB,EAC5B,GAAG,EAAE,kBAAkB,EACvB,MAAM,EAAE,MAAM,KACX,YAAY,CAAC,MAAM,GAAG,UAAU,GAAG,uBAAuB,GAAG,SAAS,CAAC,CAAA;AAE5E,yGAAyG;AACzG,MAAM,MAAM,gBAAgB,GAAG,CAC7B,QAAQ,EAAE,mBAAmB,EAC7B,GAAG,EAAE,kBAAkB,KACpB,YAAY,CAAC,IAAI,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"node-outcome-hook.d.ts","sourceRoot":"","sources":["../../src/server/node-outcome-hook.ts"],"names":[],"mappings":"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"}
|
|
@@ -61,13 +61,18 @@ class RecordHeadersView {
|
|
|
61
61
|
* a raw record write from a custom native twin uses lowercase names (the wire form the record
|
|
62
62
|
* documents), so it stays visible without a scan. */
|
|
63
63
|
#actual(lower) {
|
|
64
|
+
return this.#key(lower) ?? lower;
|
|
65
|
+
}
|
|
66
|
+
/** As {@link #actual}, but `undefined` when the record holds no such header: only an own property
|
|
67
|
+
* is a header, so an inherited `constructor` or `toString` never reads as one. */
|
|
68
|
+
#key(lower) {
|
|
64
69
|
const record = this.#target.headers;
|
|
65
|
-
if (record
|
|
70
|
+
if (record === undefined)
|
|
71
|
+
return undefined;
|
|
72
|
+
if (Object.hasOwn(record, lower))
|
|
66
73
|
return lower;
|
|
67
74
|
const known = this.#alias?.get(lower);
|
|
68
|
-
|
|
69
|
-
return known;
|
|
70
|
-
return lower;
|
|
75
|
+
return known !== undefined && Object.hasOwn(record, known) ? known : undefined;
|
|
71
76
|
}
|
|
72
77
|
/** The backing record if the outcome has one, prepared on first touch; `undefined` otherwise. */
|
|
73
78
|
#readable() {
|
|
@@ -115,14 +120,18 @@ class RecordHeadersView {
|
|
|
115
120
|
const headers = this.#readable();
|
|
116
121
|
if (headers === undefined)
|
|
117
122
|
return null;
|
|
118
|
-
const
|
|
123
|
+
const key = this.#key(RecordHeadersView.#lower(name));
|
|
124
|
+
const value = key === undefined ? undefined : headers[key];
|
|
119
125
|
if (value === undefined)
|
|
120
126
|
return null;
|
|
121
127
|
return typeof value === "string" ? value : (value.join(", ") ?? null);
|
|
122
128
|
}
|
|
123
129
|
has(name) {
|
|
124
130
|
const headers = this.#readable();
|
|
125
|
-
|
|
131
|
+
if (headers === undefined)
|
|
132
|
+
return false;
|
|
133
|
+
const key = this.#key(RecordHeadersView.#lower(name));
|
|
134
|
+
return key !== undefined && headers[key] !== undefined;
|
|
126
135
|
}
|
|
127
136
|
set(name, value) {
|
|
128
137
|
const headers = this.#writable();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node-outcome-hook.js","sourceRoot":"","sources":["../../src/server/node-outcome-hook.ts"],"names":[],"mappings":"AAAA,qGAAqG;AAGrG,OAAO,EAAE,0BAA0B,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"node-outcome-hook.js","sourceRoot":"","sources":["../../src/server/node-outcome-hook.ts"],"names":[],"mappings":"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"}
|