@schmock/core 2.4.1 → 2.6.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 +129 -0
- package/dist/abort.d.ts +11 -1
- package/dist/abort.js +13 -2
- package/dist/adapter.d.ts +21 -0
- package/dist/adapter.js +19 -0
- package/dist/admission.d.ts +21 -0
- package/dist/admission.js +39 -0
- package/dist/binary.d.ts +0 -1
- package/dist/builder.d.ts +16 -32
- package/dist/builder.js +425 -904
- package/dist/constants.d.ts +33 -2
- package/dist/constants.js +73 -1
- package/dist/debug-logger.d.ts +10 -0
- package/dist/debug-logger.js +31 -0
- package/dist/delay.d.ts +12 -0
- package/dist/delay.js +37 -0
- package/dist/errors.d.ts +13 -2
- package/dist/errors.js +21 -2
- package/dist/events.d.ts +17 -0
- package/dist/events.js +58 -0
- package/dist/generations.d.ts +48 -0
- package/dist/generations.js +82 -0
- package/dist/headers.d.ts +27 -0
- package/dist/headers.js +57 -0
- package/dist/helpers.d.ts +9 -10
- package/dist/helpers.js +4 -1
- package/dist/history.d.ts +56 -0
- package/dist/history.js +151 -0
- package/dist/http-helpers.d.ts +110 -5
- package/dist/http-helpers.js +328 -46
- package/dist/index.d.ts +295 -31
- package/dist/index.js +17 -9
- package/dist/interceptor.d.ts +40 -10
- package/dist/interceptor.js +412 -178
- package/dist/node-server.d.ts +27 -0
- package/dist/node-server.js +166 -0
- package/dist/parser.d.ts +0 -1
- package/dist/parser.js +145 -22
- package/dist/plugin-hooks.d.ts +57 -0
- package/dist/plugin-hooks.js +276 -0
- package/dist/plugin-pipeline.d.ts +0 -1
- package/dist/plugin-pipeline.js +25 -4
- package/dist/response-normalizer.d.ts +36 -1
- package/dist/response-normalizer.js +102 -0
- package/dist/response-parser.d.ts +19 -1
- package/dist/response-parser.js +77 -19
- package/dist/route-matcher.d.ts +0 -1
- package/dist/route-table.d.ts +64 -0
- package/dist/route-table.js +220 -0
- package/dist/snapshot.d.ts +14 -0
- package/dist/snapshot.js +98 -0
- package/dist/types.d.ts +34 -1
- package/package.json +8 -3
- package/dist/abort.d.ts.map +0 -1
- package/dist/binary.d.ts.map +0 -1
- package/dist/builder.d.ts.map +0 -1
- package/dist/constants.d.ts.map +0 -1
- package/dist/errors.d.ts.map +0 -1
- package/dist/helpers.d.ts.map +0 -1
- package/dist/http-helpers.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/interceptor.d.ts.map +0 -1
- package/dist/parser.d.ts.map +0 -1
- package/dist/plugin-pipeline.d.ts.map +0 -1
- package/dist/response-normalizer.d.ts.map +0 -1
- package/dist/response-parser.d.ts.map +0 -1
- package/dist/route-matcher.d.ts.map +0 -1
- package/dist/types.d.ts.map +0 -1
package/dist/helpers.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
/// <reference path="../schmock.d.ts" />
|
|
2
|
+
// Each helper returns its literal status (`[404, object]`, not
|
|
3
|
+
// `[number, object]`), as docs/api.md documents: a literal tuple is still
|
|
4
|
+
// assignable to `[number, object]`, and callers can destructure a typed status.
|
|
2
5
|
export function notFound(message = "Not Found") {
|
|
3
6
|
const body = typeof message === "string" ? { message } : message;
|
|
4
7
|
return [404, body];
|
|
@@ -39,7 +42,7 @@ function positiveInteger(value, fallback) {
|
|
|
39
42
|
* page 1 and a page size of 10) so a fractional, negative, NaN or infinite
|
|
40
43
|
* option can never produce a nonsensical slice or a negative `totalPages`. The
|
|
41
44
|
* returned envelope always echoes the NORMALIZED values, so it is internally
|
|
42
|
-
* consistent with `data`.
|
|
45
|
+
* consistent with `data`. `items` is only read, so a readonly array is fine.
|
|
43
46
|
*/
|
|
44
47
|
export function paginate(items, options = {}) {
|
|
45
48
|
const page = positiveInteger(options.page, 1);
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/** What history records about the request, captured before any hook runs. */
|
|
2
|
+
export interface RequestHistorySnapshot {
|
|
3
|
+
readonly query: Record<string, string>;
|
|
4
|
+
readonly headers: Record<string, string>;
|
|
5
|
+
readonly body: unknown;
|
|
6
|
+
}
|
|
7
|
+
/** A matched request as it is committed to history. */
|
|
8
|
+
interface RequestHistoryEntry {
|
|
9
|
+
/** The history generation the request was admitted under. */
|
|
10
|
+
readonly generation: symbol;
|
|
11
|
+
readonly method: Schmock.HttpMethod;
|
|
12
|
+
/** The namespace-stripped, normalized path the route matched. */
|
|
13
|
+
readonly path: string;
|
|
14
|
+
readonly params: Record<string, string>;
|
|
15
|
+
readonly snapshot: RequestHistorySnapshot;
|
|
16
|
+
readonly response: Schmock.Response;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* The mock's request log and its spy API.
|
|
20
|
+
*
|
|
21
|
+
* Every read returns deep copies, so a caller can never corrupt the records.
|
|
22
|
+
* A request is recorded only under the history generation it was admitted
|
|
23
|
+
* with: `startGeneration()` ends the current one, so a request still in
|
|
24
|
+
* flight when history is reset cannot write into the new log.
|
|
25
|
+
*/
|
|
26
|
+
export declare class RequestHistory {
|
|
27
|
+
#private;
|
|
28
|
+
/**
|
|
29
|
+
* @param limit `maxHistorySize`: FIFO bound on the number of records,
|
|
30
|
+
* `0` disables history, `undefined` keeps every record.
|
|
31
|
+
* @throws SchmockError `INVALID_CONFIG` when the limit is not a
|
|
32
|
+
* non-negative integer.
|
|
33
|
+
*/
|
|
34
|
+
constructor(limit: number | undefined);
|
|
35
|
+
/** The token an admitted request captures and records under. */
|
|
36
|
+
get generation(): symbol;
|
|
37
|
+
/**
|
|
38
|
+
* Copy what the CLIENT sent, before any plugin or the generator gets the
|
|
39
|
+
* live objects and can edit them. `undefined` when history is disabled.
|
|
40
|
+
*/
|
|
41
|
+
snapshotRequest(request: RequestHistorySnapshot): RequestHistorySnapshot | undefined;
|
|
42
|
+
/** Record a matched request, unless its history generation has ended. */
|
|
43
|
+
record(entry: RequestHistoryEntry): void;
|
|
44
|
+
/**
|
|
45
|
+
* Start a new generation: a request admitted before it can no longer
|
|
46
|
+
* record. The records themselves stay until `clear()`.
|
|
47
|
+
*/
|
|
48
|
+
startGeneration(): void;
|
|
49
|
+
/** Drop every record. */
|
|
50
|
+
clear(): void;
|
|
51
|
+
history(method?: Schmock.HttpMethod, path?: string): Schmock.RequestRecord[];
|
|
52
|
+
called(method?: Schmock.HttpMethod, path?: string): boolean;
|
|
53
|
+
callCount(method?: Schmock.HttpMethod, path?: string): number;
|
|
54
|
+
lastRequest(method?: Schmock.HttpMethod, path?: string): Schmock.RequestRecord | undefined;
|
|
55
|
+
}
|
|
56
|
+
export {};
|
package/dist/history.js
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { canonicalizePath, normalizePath } from "./constants.js";
|
|
2
|
+
import { SchmockError } from "./errors.js";
|
|
3
|
+
import { snapshotNormalizedBody, snapshotValue } from "./snapshot.js";
|
|
4
|
+
/**
|
|
5
|
+
* Reject a history limit that cannot bound anything.
|
|
6
|
+
*
|
|
7
|
+
* A negative limit used to read as "unbounded" and a fractional one evicted a
|
|
8
|
+
* fractional number of records, so a typo silently disabled the cap instead of
|
|
9
|
+
* failing. `Number.isInteger` also rejects NaN and Infinity. `0` stays valid
|
|
10
|
+
* and keeps meaning "history disabled".
|
|
11
|
+
*/
|
|
12
|
+
function assertValidHistoryLimit(limit) {
|
|
13
|
+
if (limit === undefined)
|
|
14
|
+
return;
|
|
15
|
+
if (!Number.isInteger(limit) || limit < 0) {
|
|
16
|
+
throw new SchmockError(`Invalid maxHistorySize: ${String(limit)}. Expected a non-negative integer (0 disables history).`, "INVALID_CONFIG", { maxHistorySize: limit });
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
function cloneRecord(r) {
|
|
20
|
+
return {
|
|
21
|
+
method: r.method,
|
|
22
|
+
path: r.path,
|
|
23
|
+
params: { ...r.params },
|
|
24
|
+
query: { ...r.query },
|
|
25
|
+
headers: { ...r.headers },
|
|
26
|
+
body: snapshotValue(r.body),
|
|
27
|
+
timestamp: r.timestamp,
|
|
28
|
+
response: {
|
|
29
|
+
status: r.response.status,
|
|
30
|
+
body: snapshotNormalizedBody(r.response.body),
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* History stores the canonical request path — percent-encoded and
|
|
36
|
+
* trailing-slash-normalized exactly as `handle()` produced it — so a spy
|
|
37
|
+
* filter must be put into the same form before it is compared, or the very
|
|
38
|
+
* string the caller passed to `handle()` would not match its own record.
|
|
39
|
+
* `canonicalizePath` is idempotent, so an already-encoded filter keeps
|
|
40
|
+
* matching and both spellings work.
|
|
41
|
+
*/
|
|
42
|
+
function historyMatcher(method, path) {
|
|
43
|
+
const wanted = path === undefined ? undefined : normalizePath(canonicalizePath(path));
|
|
44
|
+
return (r) => (!method || r.method === method) && (!wanted || r.path === wanted);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* The mock's request log and its spy API.
|
|
48
|
+
*
|
|
49
|
+
* Every read returns deep copies, so a caller can never corrupt the records.
|
|
50
|
+
* A request is recorded only under the history generation it was admitted
|
|
51
|
+
* with: `startGeneration()` ends the current one, so a request still in
|
|
52
|
+
* flight when history is reset cannot write into the new log.
|
|
53
|
+
*/
|
|
54
|
+
export class RequestHistory {
|
|
55
|
+
#records = [];
|
|
56
|
+
#generation = Symbol("schmock.history.generation");
|
|
57
|
+
#limit;
|
|
58
|
+
/**
|
|
59
|
+
* @param limit `maxHistorySize`: FIFO bound on the number of records,
|
|
60
|
+
* `0` disables history, `undefined` keeps every record.
|
|
61
|
+
* @throws SchmockError `INVALID_CONFIG` when the limit is not a
|
|
62
|
+
* non-negative integer.
|
|
63
|
+
*/
|
|
64
|
+
constructor(limit) {
|
|
65
|
+
assertValidHistoryLimit(limit);
|
|
66
|
+
this.#limit = limit;
|
|
67
|
+
}
|
|
68
|
+
/** The token an admitted request captures and records under. */
|
|
69
|
+
get generation() {
|
|
70
|
+
return this.#generation;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Copy what the CLIENT sent, before any plugin or the generator gets the
|
|
74
|
+
* live objects and can edit them. `undefined` when history is disabled.
|
|
75
|
+
*/
|
|
76
|
+
snapshotRequest(request) {
|
|
77
|
+
if (this.#limit === 0)
|
|
78
|
+
return undefined;
|
|
79
|
+
return {
|
|
80
|
+
query: { ...request.query },
|
|
81
|
+
headers: { ...request.headers },
|
|
82
|
+
body: snapshotValue(request.body),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
/** Record a matched request, unless its history generation has ended. */
|
|
86
|
+
record(entry) {
|
|
87
|
+
if (entry.generation !== this.#generation || this.#limit === 0)
|
|
88
|
+
return;
|
|
89
|
+
const limit = this.#limit;
|
|
90
|
+
this.#records.push({
|
|
91
|
+
method: entry.method,
|
|
92
|
+
path: entry.path,
|
|
93
|
+
params: { ...entry.params },
|
|
94
|
+
query: entry.snapshot.query,
|
|
95
|
+
headers: entry.snapshot.headers,
|
|
96
|
+
body: entry.snapshot.body,
|
|
97
|
+
timestamp: Date.now(),
|
|
98
|
+
response: {
|
|
99
|
+
status: entry.response.status,
|
|
100
|
+
body: snapshotNormalizedBody(entry.response.body),
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
// The constructor already rejected a limit that is not a non-negative
|
|
104
|
+
// integer, so a plain comparison is enough here.
|
|
105
|
+
if (limit !== undefined && this.#records.length > limit) {
|
|
106
|
+
this.#records.splice(0, this.#records.length - limit);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Start a new generation: a request admitted before it can no longer
|
|
111
|
+
* record. The records themselves stay until `clear()`.
|
|
112
|
+
*/
|
|
113
|
+
startGeneration() {
|
|
114
|
+
this.#generation = Symbol("schmock.history.generation");
|
|
115
|
+
}
|
|
116
|
+
/** Drop every record. */
|
|
117
|
+
clear() {
|
|
118
|
+
this.#records = [];
|
|
119
|
+
}
|
|
120
|
+
history(method, path) {
|
|
121
|
+
if (method || path) {
|
|
122
|
+
return this.#records
|
|
123
|
+
.filter(historyMatcher(method, path))
|
|
124
|
+
.map((r) => cloneRecord(r));
|
|
125
|
+
}
|
|
126
|
+
return this.#records.map((r) => cloneRecord(r));
|
|
127
|
+
}
|
|
128
|
+
called(method, path) {
|
|
129
|
+
if (method || path) {
|
|
130
|
+
return this.#records.some(historyMatcher(method, path));
|
|
131
|
+
}
|
|
132
|
+
return this.#records.length > 0;
|
|
133
|
+
}
|
|
134
|
+
callCount(method, path) {
|
|
135
|
+
if (method || path) {
|
|
136
|
+
return this.#records.filter(historyMatcher(method, path)).length;
|
|
137
|
+
}
|
|
138
|
+
return this.#records.length;
|
|
139
|
+
}
|
|
140
|
+
lastRequest(method, path) {
|
|
141
|
+
if (method || path) {
|
|
142
|
+
const filtered = this.#records.filter(historyMatcher(method, path));
|
|
143
|
+
const last = filtered[filtered.length - 1];
|
|
144
|
+
// FIX 2.3: return a deep clone so callers cannot corrupt internal history
|
|
145
|
+
return last ? cloneRecord(last) : undefined;
|
|
146
|
+
}
|
|
147
|
+
const last = this.#records[this.#records.length - 1];
|
|
148
|
+
// FIX 2.3: return a deep clone so callers cannot corrupt internal history
|
|
149
|
+
return last ? cloneRecord(last) : undefined;
|
|
150
|
+
}
|
|
151
|
+
}
|
package/dist/http-helpers.d.ts
CHANGED
|
@@ -15,7 +15,7 @@ interface ResponseWritable {
|
|
|
15
15
|
writeHead(status: number, headers: Record<string, string>): this;
|
|
16
16
|
end(body?: string | Uint8Array): this;
|
|
17
17
|
}
|
|
18
|
-
export type HttpIngressErrorCode = "MALFORMED_JSON" | "PAYLOAD_TOO_LARGE";
|
|
18
|
+
export type HttpIngressErrorCode = "MALFORMED_JSON" | "JSON_TOO_DEEP" | "MALFORMED_MULTIPART" | "PAYLOAD_TOO_LARGE";
|
|
19
19
|
/** An HTTP client error raised while collecting an incoming request body. */
|
|
20
20
|
export declare class HttpIngressError extends Error {
|
|
21
21
|
readonly status: 400 | 413;
|
|
@@ -29,15 +29,20 @@ export declare class HttpIngressError extends Error {
|
|
|
29
29
|
export declare function parseNodeHeaders(req: RequestWithHeaders): Record<string, string>;
|
|
30
30
|
/**
|
|
31
31
|
* Extract query parameters from a URL as a flat Record<string, string>.
|
|
32
|
+
* A repeated key resolves to its LAST value; every adapter follows this rule.
|
|
32
33
|
*/
|
|
33
34
|
export declare function parseNodeQuery(url: URL): Record<string, string>;
|
|
35
|
+
/** Default body size limit: 10 MB */
|
|
36
|
+
export declare const DEFAULT_MAX_BODY_SIZE: number;
|
|
34
37
|
/**
|
|
35
38
|
* Collect and parse the request body from a Node.js IncomingMessage.
|
|
36
|
-
*
|
|
37
|
-
*
|
|
39
|
+
* The body takes the shape the fetch interceptor gives it: parsed JSON for
|
|
40
|
+
* application/json and +json, an object for urlencoded forms, a string for
|
|
41
|
+
* text/*, FormData for multipart/*, and an ArrayBuffer for anything else.
|
|
38
42
|
* Returns undefined for empty bodies.
|
|
39
43
|
* @param req - Node.js IncomingMessage
|
|
40
|
-
* @param headers - Parsed request headers
|
|
44
|
+
* @param headers - Parsed request headers; content-length and content-type
|
|
45
|
+
* are looked up case-insensitively
|
|
41
46
|
* @param maxBodySize - Maximum body size in bytes (default: 10 MB)
|
|
42
47
|
*/
|
|
43
48
|
export declare function collectBody(req: BodyReadable, headers: Record<string, string>, maxBodySize?: number): Promise<unknown>;
|
|
@@ -68,5 +73,105 @@ export declare function writeSchmockResponse(res: ResponseWritable, response: Sc
|
|
|
68
73
|
* request finishes, goes idle, or exhausts the grace cap.
|
|
69
74
|
*/
|
|
70
75
|
export declare function writeRejectedSchmockResponse(req: RejectedRequestReadable, res: RejectedResponseWritable, response: Schmock.Response, extraHeaders?: Record<string, string>): void;
|
|
76
|
+
/** The parts of a Node.js IncomingMessage `serveNodeRequest` uses. */
|
|
77
|
+
type NodeRequest = RequestWithHeaders & BodyReadable & RejectedRequestReadable & {
|
|
78
|
+
readonly headers: {
|
|
79
|
+
readonly host?: string;
|
|
80
|
+
};
|
|
81
|
+
readonly method?: string;
|
|
82
|
+
readonly url?: string;
|
|
83
|
+
once(event: "aborted", listener: () => void): unknown;
|
|
84
|
+
off(event: "aborted", listener: () => void): unknown;
|
|
85
|
+
};
|
|
86
|
+
/** The parts of a Node.js ServerResponse `serveNodeRequest` uses. */
|
|
87
|
+
type NodeResponse = RejectedResponseWritable & {
|
|
88
|
+
readonly headersSent: boolean;
|
|
89
|
+
shouldKeepAlive: boolean;
|
|
90
|
+
destroy(error?: Error): unknown;
|
|
91
|
+
off(event: "close", listener: () => void): unknown;
|
|
92
|
+
};
|
|
93
|
+
/**
|
|
94
|
+
* The request `serveNodeRequest` accepts: the parts of a Node.js
|
|
95
|
+
* IncomingMessage it uses. Structural, so a request typed by any `@types/node`
|
|
96
|
+
* copy fits.
|
|
97
|
+
*/
|
|
98
|
+
export type NodeRequestLike = NodeRequest;
|
|
99
|
+
/**
|
|
100
|
+
* The response `serveNodeRequest` writes to: the parts of a Node.js
|
|
101
|
+
* ServerResponse it uses. Structural, so a response typed by any
|
|
102
|
+
* `@types/node` copy fits.
|
|
103
|
+
*/
|
|
104
|
+
export type NodeResponseLike = NodeResponse;
|
|
105
|
+
/** What `serveNodeRequest` tells `extraHeaders` about the response it writes. */
|
|
106
|
+
export interface ServeNodeResponseContext {
|
|
107
|
+
/**
|
|
108
|
+
* `true` for an error answer `serveNodeRequest` writes itself, `false` for
|
|
109
|
+
* the response `handle` produced.
|
|
110
|
+
*/
|
|
111
|
+
readonly isError: boolean;
|
|
112
|
+
/** The request pathname, or `undefined` when the request did not parse. */
|
|
113
|
+
readonly path: string | undefined;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* How `serveNodeRequest` answers a failed request. The body is the JSON
|
|
117
|
+
* `{ "error": message, "code": code }`.
|
|
118
|
+
*/
|
|
119
|
+
export interface HttpErrorReply {
|
|
120
|
+
readonly status: number;
|
|
121
|
+
readonly code: string;
|
|
122
|
+
readonly message: string;
|
|
123
|
+
/** Headers the answer carries besides its content type (a 405's `allow`). */
|
|
124
|
+
readonly headers?: Readonly<Record<string, string>>;
|
|
125
|
+
}
|
|
126
|
+
export interface ServeNodeRequestOptions {
|
|
127
|
+
/** Routes the parsed request: `mock.handle`, or a request admission's `handle`. */
|
|
128
|
+
readonly handle: Schmock.MockRequestHandler;
|
|
129
|
+
/**
|
|
130
|
+
* Largest request body accepted, in bytes. A larger one is answered 413 and
|
|
131
|
+
* the connection is closed. Defaults to 10 MB, the limit `mock.listen()`
|
|
132
|
+
* applies.
|
|
133
|
+
*/
|
|
134
|
+
readonly maxBodySize?: number;
|
|
135
|
+
/**
|
|
136
|
+
* Answer a request from its verb and path alone, before its body is read.
|
|
137
|
+
* Return a response to send it as is (through `extraHeaders`, like any
|
|
138
|
+
* answer from `handle`), or `undefined` to read the body and call `handle`.
|
|
139
|
+
* A throw is answered like a `handle` failure.
|
|
140
|
+
*
|
|
141
|
+
* For answers that never depend on the body — a CORS preflight, an
|
|
142
|
+
* authorization refusal — so an oversized, malformed or stalled upload
|
|
143
|
+
* cannot delay or replace them.
|
|
144
|
+
*/
|
|
145
|
+
readonly answerBeforeBody?: (method: Schmock.HttpMethod, path: string) => Schmock.Response | undefined;
|
|
146
|
+
/**
|
|
147
|
+
* Headers written over every response for this request (CORS headers, for
|
|
148
|
+
* example), replacing any case variant of the same name.
|
|
149
|
+
*/
|
|
150
|
+
readonly extraHeaders?: (context: ServeNodeResponseContext) => Record<string, string> | undefined;
|
|
151
|
+
/**
|
|
152
|
+
* Choose the answer for an error. Return `undefined` for the default: 400
|
|
153
|
+
* for a request that does not parse, 405 with `allow` for a method Schmock
|
|
154
|
+
* does not route, the ingress status for a body error (400, or 413 over
|
|
155
|
+
* `maxBodySize`), and 500 `SERVER_ERROR` with the error's message otherwise.
|
|
156
|
+
*/
|
|
157
|
+
readonly classifyError?: (error: unknown) => HttpErrorReply | undefined;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Serve one Node.js request through a mock: the bridge `mock.listen()` runs,
|
|
161
|
+
* usable with any `http.createServer` callback.
|
|
162
|
+
*
|
|
163
|
+
* It rejects a request without a parseable Host header or target (400) and a
|
|
164
|
+
* method Schmock does not route (405, with `allow`), gives `answerBeforeBody`
|
|
165
|
+
* the chance to answer without the body, then parses headers, query and body
|
|
166
|
+
* (400 for a malformed JSON or multipart body, 413 over `maxBodySize`, 10 MB
|
|
167
|
+
* by default) and calls `handle` with an abort signal that fires when the
|
|
168
|
+
* client goes away. Every failure is answered as `{ error, code }` JSON; an
|
|
169
|
+
* ingress failure also closes the connection, and a 413 is flushed while the
|
|
170
|
+
* client may still be uploading so it can read it.
|
|
171
|
+
*
|
|
172
|
+
* The returned promise never rejects. It settles once the response has been
|
|
173
|
+
* handed to Node, which is when per-request resources (a request admission)
|
|
174
|
+
* can be released.
|
|
175
|
+
*/
|
|
176
|
+
export declare function serveNodeRequest(req: NodeRequest, res: NodeResponse, options: ServeNodeRequestOptions): Promise<void>;
|
|
71
177
|
export {};
|
|
72
|
-
//# sourceMappingURL=http-helpers.d.ts.map
|