@fluojs/platform-nodejs 1.0.6 → 2.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.ko.md +41 -11
- package/README.md +41 -11
- package/dist/index.d.ts +10 -55
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -55
- package/dist/internal.d.ts +3 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +2 -0
- package/dist/node/internal-node-compression.d.ts +22 -0
- package/dist/node/internal-node-compression.d.ts.map +1 -0
- package/dist/node/internal-node-compression.js +121 -0
- package/dist/node/internal-node-early-hints.d.ts +11 -0
- package/dist/node/internal-node-early-hints.d.ts.map +1 -0
- package/dist/node/internal-node-early-hints.js +99 -0
- package/dist/node/internal-node-listen.d.ts +24 -0
- package/dist/node/internal-node-listen.d.ts.map +1 -0
- package/dist/node/internal-node-listen.js +167 -0
- package/dist/node/internal-node-request.d.ts +163 -0
- package/dist/node/internal-node-request.d.ts.map +1 -0
- package/dist/node/internal-node-request.js +498 -0
- package/dist/node/internal-node-response-stream.d.ts +10 -0
- package/dist/node/internal-node-response-stream.d.ts.map +1 -0
- package/dist/node/internal-node-response-stream.js +69 -0
- package/dist/node/internal-node-response.d.ts +28 -0
- package/dist/node/internal-node-response.d.ts.map +1 -0
- package/dist/node/internal-node-response.js +181 -0
- package/dist/node/internal-node-shutdown.d.ts +34 -0
- package/dist/node/internal-node-shutdown.d.ts.map +1 -0
- package/dist/node/internal-node-shutdown.js +83 -0
- package/dist/node/internal-node.d.ts +114 -0
- package/dist/node/internal-node.d.ts.map +1 -0
- package/dist/node/internal-node.js +262 -0
- package/dist/node/json-logger.d.ts +8 -0
- package/dist/node/json-logger.d.ts.map +1 -0
- package/dist/node/json-logger.js +45 -0
- package/dist/node/logger.d.ts +37 -0
- package/dist/node/logger.d.ts.map +1 -0
- package/dist/node/logger.js +103 -0
- package/dist/node/node-compression.d.ts +2 -0
- package/dist/node/node-compression.d.ts.map +1 -0
- package/dist/node/node-compression.js +1 -0
- package/dist/node/node-request.d.ts +2 -0
- package/dist/node/node-request.d.ts.map +1 -0
- package/dist/node/node-request.js +1 -0
- package/dist/node/node-response.d.ts +2 -0
- package/dist/node/node-response.d.ts.map +1 -0
- package/dist/node/node-response.js +1 -0
- package/dist/node/node-shutdown.d.ts +2 -0
- package/dist/node/node-shutdown.d.ts.map +1 -0
- package/dist/node/node-shutdown.js +1 -0
- package/dist/node/node-static-assets.d.ts +26 -0
- package/dist/node/node-static-assets.d.ts.map +1 -0
- package/dist/node/node-static-assets.js +244 -0
- package/dist/node/node.d.ts +2 -0
- package/dist/node/node.d.ts.map +1 -0
- package/dist/node/node.js +1 -0
- package/package.json +17 -6
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { validateHeaderName, validateHeaderValue } from 'node:http';
|
|
2
|
+
import { EarlyHintsWriteError, RequestAbortedError } from '@fluojs/http';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Create the request-scoped Early Hints writer shared by Node-backed adapters.
|
|
6
|
+
*
|
|
7
|
+
* @param response Native Node response that emits HTTP 103 informational responses.
|
|
8
|
+
* @param isCommitted Probe for facade-level final response ownership.
|
|
9
|
+
* @returns An Early Hints capability that settles on native write, error, or disconnect.
|
|
10
|
+
*/
|
|
11
|
+
export function createNodeEarlyHintsCapability(response, isCommitted) {
|
|
12
|
+
return {
|
|
13
|
+
write(headers) {
|
|
14
|
+
if (isCommitted() || response.headersSent || response.writableEnded) {
|
|
15
|
+
return Promise.reject(new EarlyHintsWriteError('Cannot write HTTP 103 Early Hints after the final response is committed.'));
|
|
16
|
+
}
|
|
17
|
+
if (response.destroyed || response.socket?.destroyed) {
|
|
18
|
+
return Promise.reject(new RequestAbortedError('Request aborted before HTTP 103 Early Hints could be written.'));
|
|
19
|
+
}
|
|
20
|
+
let nativeHeaders;
|
|
21
|
+
try {
|
|
22
|
+
nativeHeaders = cloneEarlyHintsHeaders(headers);
|
|
23
|
+
} catch (cause) {
|
|
24
|
+
return Promise.reject(new EarlyHintsWriteError('HTTP 103 Early Hints contains an invalid header name or value.', {
|
|
25
|
+
cause
|
|
26
|
+
}));
|
|
27
|
+
}
|
|
28
|
+
if (!hasNonEmptyLink(nativeHeaders.link)) {
|
|
29
|
+
return Promise.reject(new EarlyHintsWriteError('HTTP 103 Early Hints requires at least one non-empty link value.'));
|
|
30
|
+
}
|
|
31
|
+
return new Promise((resolve, reject) => {
|
|
32
|
+
let settled = false;
|
|
33
|
+
const cleanup = () => {
|
|
34
|
+
response.removeListener('close', onClose);
|
|
35
|
+
response.removeListener('error', onError);
|
|
36
|
+
};
|
|
37
|
+
const settle = action => {
|
|
38
|
+
if (settled) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
settled = true;
|
|
42
|
+
cleanup();
|
|
43
|
+
action();
|
|
44
|
+
};
|
|
45
|
+
const onClose = () => {
|
|
46
|
+
settle(() => reject(new RequestAbortedError('Request aborted while HTTP 103 Early Hints were being written.')));
|
|
47
|
+
};
|
|
48
|
+
const onError = cause => {
|
|
49
|
+
settle(() => reject(new EarlyHintsWriteError('Native HTTP transport failed to write HTTP 103 Early Hints.', {
|
|
50
|
+
cause
|
|
51
|
+
})));
|
|
52
|
+
};
|
|
53
|
+
const onWritten = () => {
|
|
54
|
+
settle(resolve);
|
|
55
|
+
};
|
|
56
|
+
response.once('close', onClose);
|
|
57
|
+
response.once('error', onError);
|
|
58
|
+
try {
|
|
59
|
+
response.writeEarlyHints(nativeHeaders, onWritten);
|
|
60
|
+
} catch (cause) {
|
|
61
|
+
settle(() => reject(new EarlyHintsWriteError('Native HTTP transport rejected HTTP 103 Early Hints.', {
|
|
62
|
+
cause
|
|
63
|
+
})));
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
function hasNonEmptyLink(link) {
|
|
70
|
+
return typeof link === 'string' ? link.length > 0 : Array.isArray(link) && link.length > 0 && link.every(value => typeof value === 'string' && value.length > 0);
|
|
71
|
+
}
|
|
72
|
+
function cloneEarlyHintsHeaders(headers) {
|
|
73
|
+
const cloned = Object.create(null);
|
|
74
|
+
const names = new Set();
|
|
75
|
+
for (const [name, value] of Object.entries(headers)) {
|
|
76
|
+
validateHeaderName(name);
|
|
77
|
+
const normalizedName = name.toLowerCase();
|
|
78
|
+
if (normalizedName === 'content-length' || normalizedName === 'transfer-encoding') {
|
|
79
|
+
throw new TypeError(`Header is not permitted in HTTP 103 Early Hints: ${name}`);
|
|
80
|
+
}
|
|
81
|
+
if (names.has(normalizedName)) {
|
|
82
|
+
throw new TypeError(`Duplicate Early Hints header name: ${name}`);
|
|
83
|
+
}
|
|
84
|
+
names.add(normalizedName);
|
|
85
|
+
if (typeof value === 'string') {
|
|
86
|
+
validateHeaderValue(name, value);
|
|
87
|
+
cloned[normalizedName] = value;
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
if (!Array.isArray(value) || !value.every(entry => typeof entry === 'string')) {
|
|
91
|
+
throw new TypeError(`Invalid Early Hints header value: ${name}`);
|
|
92
|
+
}
|
|
93
|
+
for (const entry of value) {
|
|
94
|
+
validateHeaderValue(name, entry);
|
|
95
|
+
}
|
|
96
|
+
cloned[normalizedName] = [...value];
|
|
97
|
+
}
|
|
98
|
+
return cloned;
|
|
99
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Server as HttpServer } from 'node:http';
|
|
2
|
+
import type { Server as HttpsServer } from 'node:https';
|
|
3
|
+
interface NodeListenRetryOptions {
|
|
4
|
+
readonly host: string | undefined;
|
|
5
|
+
readonly port: number;
|
|
6
|
+
readonly retryDelayMs: number;
|
|
7
|
+
readonly retryLimit: number;
|
|
8
|
+
}
|
|
9
|
+
type NodeServer = HttpServer | HttpsServer;
|
|
10
|
+
/** Owns one Node server's listen, retry cancellation, and close admission state. */
|
|
11
|
+
export declare class NodeListenLifecycle {
|
|
12
|
+
private readonly server;
|
|
13
|
+
private readonly options;
|
|
14
|
+
private closeInFlight?;
|
|
15
|
+
private closing;
|
|
16
|
+
private listenAbortController?;
|
|
17
|
+
private listenInFlight?;
|
|
18
|
+
constructor(server: NodeServer, options: NodeListenRetryOptions);
|
|
19
|
+
close(closeServer: () => Promise<void>): Promise<void>;
|
|
20
|
+
listen(onAdmitted: () => void): Promise<void>;
|
|
21
|
+
cancel(): Promise<void>;
|
|
22
|
+
}
|
|
23
|
+
export {};
|
|
24
|
+
//# sourceMappingURL=internal-node-listen.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"internal-node-listen.d.ts","sourceRoot":"","sources":["../../src/node/internal-node-listen.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,WAAW,CAAC;AACtD,OAAO,KAAK,EAAE,MAAM,IAAI,WAAW,EAAE,MAAM,YAAY,CAAC;AAExD,UAAU,sBAAsB;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,KAAK,UAAU,GAAG,UAAU,GAAG,WAAW,CAAC;AAU3C,oFAAoF;AACpF,qBAAa,mBAAmB;IAO5B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAP1B,OAAO,CAAC,aAAa,CAAC,CAAgB;IACtC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,qBAAqB,CAAC,CAAkB;IAChD,OAAO,CAAC,cAAc,CAAC,CAAgB;gBAGpB,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,sBAAsB;IAGlD,KAAK,CAAC,WAAW,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBtD,MAAM,CAAC,UAAU,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IA8BvC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;CAkB9B"}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
class NodeListenCancelledError extends Error {
|
|
2
|
+
name = 'NodeListenCancelledError';
|
|
3
|
+
constructor() {
|
|
4
|
+
super('Node HTTP adapter startup was cancelled during shutdown.');
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/** Owns one Node server's listen, retry cancellation, and close admission state. */
|
|
9
|
+
export class NodeListenLifecycle {
|
|
10
|
+
closeInFlight;
|
|
11
|
+
closing = false;
|
|
12
|
+
listenAbortController;
|
|
13
|
+
listenInFlight;
|
|
14
|
+
constructor(server, options) {
|
|
15
|
+
this.server = server;
|
|
16
|
+
this.options = options;
|
|
17
|
+
}
|
|
18
|
+
close(closeServer) {
|
|
19
|
+
if (this.closeInFlight) {
|
|
20
|
+
return this.closeInFlight;
|
|
21
|
+
}
|
|
22
|
+
this.closing = true;
|
|
23
|
+
const closeInFlight = (async () => {
|
|
24
|
+
await this.cancel();
|
|
25
|
+
await closeServer();
|
|
26
|
+
})().finally(() => {
|
|
27
|
+
if (this.closeInFlight === closeInFlight) {
|
|
28
|
+
this.closeInFlight = undefined;
|
|
29
|
+
this.closing = false;
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
this.closeInFlight = closeInFlight;
|
|
33
|
+
return closeInFlight;
|
|
34
|
+
}
|
|
35
|
+
listen(onAdmitted) {
|
|
36
|
+
if (this.closing) {
|
|
37
|
+
return Promise.reject(new NodeListenCancelledError());
|
|
38
|
+
}
|
|
39
|
+
if (this.listenInFlight) {
|
|
40
|
+
return this.listenInFlight;
|
|
41
|
+
}
|
|
42
|
+
onAdmitted();
|
|
43
|
+
const abortController = new AbortController();
|
|
44
|
+
this.listenAbortController = abortController;
|
|
45
|
+
const listenInFlight = listenNodeServerWithRetry(this.server, this.options, abortController.signal).finally(() => {
|
|
46
|
+
if (this.listenInFlight === listenInFlight) {
|
|
47
|
+
this.listenInFlight = undefined;
|
|
48
|
+
}
|
|
49
|
+
if (this.listenAbortController === abortController) {
|
|
50
|
+
this.listenAbortController = undefined;
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
this.listenInFlight = listenInFlight;
|
|
54
|
+
return listenInFlight;
|
|
55
|
+
}
|
|
56
|
+
async cancel() {
|
|
57
|
+
const listenInFlight = this.listenInFlight;
|
|
58
|
+
if (!listenInFlight) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
this.listenAbortController?.abort();
|
|
62
|
+
try {
|
|
63
|
+
await listenInFlight;
|
|
64
|
+
} catch (error) {
|
|
65
|
+
if (error instanceof NodeListenCancelledError) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
throw error;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function listenNodeServerWithRetry(server, options, signal) {
|
|
73
|
+
return new Promise((resolve, reject) => {
|
|
74
|
+
let activeErrorListener;
|
|
75
|
+
let activeListeningListener;
|
|
76
|
+
let attemptInFlight = false;
|
|
77
|
+
let retryTimeout;
|
|
78
|
+
let settled = false;
|
|
79
|
+
const finish = error => {
|
|
80
|
+
if (settled) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
settled = true;
|
|
84
|
+
if (retryTimeout) {
|
|
85
|
+
clearTimeout(retryTimeout);
|
|
86
|
+
}
|
|
87
|
+
if (activeErrorListener) {
|
|
88
|
+
server.off('error', activeErrorListener);
|
|
89
|
+
}
|
|
90
|
+
if (activeListeningListener) {
|
|
91
|
+
server.off('listening', activeListeningListener);
|
|
92
|
+
}
|
|
93
|
+
signal.removeEventListener('abort', onAbort);
|
|
94
|
+
if (error) {
|
|
95
|
+
reject(error);
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
resolve();
|
|
99
|
+
};
|
|
100
|
+
const cancel = () => {
|
|
101
|
+
finish(new NodeListenCancelledError());
|
|
102
|
+
};
|
|
103
|
+
const onAbort = () => {
|
|
104
|
+
if (attemptInFlight) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
cancel();
|
|
108
|
+
};
|
|
109
|
+
const tryListen = attempt => {
|
|
110
|
+
if (signal.aborted) {
|
|
111
|
+
cancel();
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
attemptInFlight = true;
|
|
115
|
+
const onError = error => {
|
|
116
|
+
attemptInFlight = false;
|
|
117
|
+
activeErrorListener = undefined;
|
|
118
|
+
server.off('listening', onListening);
|
|
119
|
+
activeListeningListener = undefined;
|
|
120
|
+
if (signal.aborted) {
|
|
121
|
+
cancel();
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
if (error.code === 'EADDRINUSE' && attempt < options.retryLimit) {
|
|
125
|
+
server.close(() => {
|
|
126
|
+
if (settled) {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
if (signal.aborted) {
|
|
130
|
+
cancel();
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
retryTimeout = setTimeout(() => {
|
|
134
|
+
retryTimeout = undefined;
|
|
135
|
+
tryListen(attempt + 1);
|
|
136
|
+
}, options.retryDelayMs);
|
|
137
|
+
});
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
finish(error);
|
|
141
|
+
};
|
|
142
|
+
const onListening = () => {
|
|
143
|
+
attemptInFlight = false;
|
|
144
|
+
activeListeningListener = undefined;
|
|
145
|
+
server.off('error', onError);
|
|
146
|
+
activeErrorListener = undefined;
|
|
147
|
+
if (signal.aborted) {
|
|
148
|
+
server.close(cancel);
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
finish();
|
|
152
|
+
};
|
|
153
|
+
activeErrorListener = onError;
|
|
154
|
+
activeListeningListener = onListening;
|
|
155
|
+
server.once('error', onError);
|
|
156
|
+
server.once('listening', onListening);
|
|
157
|
+
server.listen({
|
|
158
|
+
host: options.host,
|
|
159
|
+
port: options.port
|
|
160
|
+
});
|
|
161
|
+
};
|
|
162
|
+
signal.addEventListener('abort', onAbort, {
|
|
163
|
+
once: true
|
|
164
|
+
});
|
|
165
|
+
tryListen(0);
|
|
166
|
+
});
|
|
167
|
+
}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import type { IncomingHttpHeaders, IncomingMessage, ServerResponse } from 'node:http';
|
|
2
|
+
import { type FrameworkRequest, type FrameworkRequestConnection, PayloadTooLargeException } from '@fluojs/http';
|
|
3
|
+
import type { MultipartOptions } from '@fluojs/runtime';
|
|
4
|
+
type MemoizedValue<T> = () => T;
|
|
5
|
+
type QueryRecord = Record<string, string | string[] | undefined>;
|
|
6
|
+
/**
|
|
7
|
+
* Options for creating a deferred framework request shell from a Node-backed adapter.
|
|
8
|
+
*/
|
|
9
|
+
export interface DeferredFrameworkRequestShellOptions<RawRequest> {
|
|
10
|
+
cookieHeader?: string | string[] | undefined;
|
|
11
|
+
connection?: FrameworkRequestConnection;
|
|
12
|
+
headers?: FrameworkRequest['headers'];
|
|
13
|
+
headersFactory?: () => FrameworkRequest['headers'];
|
|
14
|
+
materializeBody?: () => Promise<void>;
|
|
15
|
+
method?: string;
|
|
16
|
+
path: string;
|
|
17
|
+
query?: QueryRecord;
|
|
18
|
+
queryFactory?: () => QueryRecord;
|
|
19
|
+
raw: RawRequest;
|
|
20
|
+
requestId?: string;
|
|
21
|
+
signal: AbortSignal | (() => AbortSignal);
|
|
22
|
+
url: string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* HTTP payload-size error that closes the underlying Node request stream after the response commits.
|
|
26
|
+
*/
|
|
27
|
+
export declare class NodeRequestPayloadTooLargeException extends PayloadTooLargeException {
|
|
28
|
+
private readonly request;
|
|
29
|
+
constructor(request: IncomingMessage);
|
|
30
|
+
prepareResponse(response: ServerResponse): void;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Creates a framework request from a raw Node incoming message.
|
|
34
|
+
*
|
|
35
|
+
* @param request - Raw Node request carrying headers, URL, and body stream.
|
|
36
|
+
* @param signal - Abort signal tied to the response lifecycle.
|
|
37
|
+
* @param multipartOptions - Multipart parser options applied to multipart requests.
|
|
38
|
+
* @param maxBodySize - Maximum allowed non-multipart body size in bytes.
|
|
39
|
+
* @param preserveRawBody - Whether to retain the raw request body bytes.
|
|
40
|
+
* @returns The normalized framework request used by the dispatcher.
|
|
41
|
+
*/
|
|
42
|
+
export declare function createFrameworkRequest(request: IncomingMessage, signal: AbortSignal, multipartOptions?: MultipartOptions, maxBodySize?: number, preserveRawBody?: boolean): Promise<FrameworkRequest>;
|
|
43
|
+
/**
|
|
44
|
+
* Creates the cheap Node framework request shell before consuming the body stream.
|
|
45
|
+
*
|
|
46
|
+
* @param request - Raw Node request carrying headers, URL, and body stream.
|
|
47
|
+
* @param signal - Abort signal tied to the response lifecycle.
|
|
48
|
+
* @param multipartOptions - Multipart parser options applied when materializing multipart requests.
|
|
49
|
+
* @param maxBodySize - Maximum allowed non-multipart body size in bytes.
|
|
50
|
+
* @param preserveRawBody - Whether materialization should retain raw request body bytes.
|
|
51
|
+
* @returns The framework request shell with metadata snapshotted and body materialization deferred.
|
|
52
|
+
*/
|
|
53
|
+
export declare function createDeferredFrameworkRequest(request: IncomingMessage, signal: AbortSignal, multipartOptions?: MultipartOptions, maxBodySize?: number, preserveRawBody?: boolean): FrameworkRequest;
|
|
54
|
+
/**
|
|
55
|
+
* Creates a framework request shell from already-snapshotted Node adapter metadata.
|
|
56
|
+
*
|
|
57
|
+
* @param options - Raw request, metadata factories, and deferred body materialization hooks.
|
|
58
|
+
* @returns A framework request with lazy headers, cookies, query values, and optional body materialization.
|
|
59
|
+
*/
|
|
60
|
+
export declare function createDeferredFrameworkRequestShell<RawRequest>({ cookieHeader, connection, headers, headersFactory, materializeBody, method, path, query, queryFactory, raw, requestId, signal, url, }: DeferredFrameworkRequestShellOptions<RawRequest>): FrameworkRequest;
|
|
61
|
+
/**
|
|
62
|
+
* Materializes a deferred Node framework request body exactly once.
|
|
63
|
+
*
|
|
64
|
+
* @param request - Framework request returned by {@link createDeferredFrameworkRequest}.
|
|
65
|
+
* @returns A promise that settles after body, rawBody, and files fields are populated when applicable.
|
|
66
|
+
*/
|
|
67
|
+
export declare function materializeFrameworkRequestBody(request: FrameworkRequest): Promise<void>;
|
|
68
|
+
/**
|
|
69
|
+
* Creates a synchronous memoized value resolver.
|
|
70
|
+
*
|
|
71
|
+
* @param factory - Function that computes the value on first access.
|
|
72
|
+
* @returns A stable resolver that returns the cached value after the first call.
|
|
73
|
+
*/
|
|
74
|
+
export declare function createMemoizedValue<T>(factory: () => T): MemoizedValue<T>;
|
|
75
|
+
/**
|
|
76
|
+
* Creates an async memoized side-effect resolver.
|
|
77
|
+
*
|
|
78
|
+
* @param factory - Async function to run at most once.
|
|
79
|
+
* @returns A resolver that returns the same in-flight or completed promise for every call.
|
|
80
|
+
*/
|
|
81
|
+
export declare function createMemoizedAsyncValue(factory: () => Promise<void>): () => Promise<void>;
|
|
82
|
+
/**
|
|
83
|
+
* Creates an abort signal that fires when the Node response closes unexpectedly.
|
|
84
|
+
*
|
|
85
|
+
* @param response - Raw Node server response associated with the request.
|
|
86
|
+
* @returns An abort signal for downstream request cancellation handling.
|
|
87
|
+
*/
|
|
88
|
+
export declare function createRequestSignal(response: ServerResponse): AbortSignal;
|
|
89
|
+
/**
|
|
90
|
+
* Resolves the request identifier from the preferred inbound headers.
|
|
91
|
+
*
|
|
92
|
+
* @param headers - Raw Node request headers.
|
|
93
|
+
* @returns The request identifier when present.
|
|
94
|
+
*/
|
|
95
|
+
export declare function resolveRequestIdFromHeaders(headers: IncomingHttpHeaders): string | undefined;
|
|
96
|
+
/**
|
|
97
|
+
* Parses a raw URL search string into the framework query shape.
|
|
98
|
+
*
|
|
99
|
+
* @param search - Raw search string, with or without a leading question mark.
|
|
100
|
+
* @returns Query values where repeated keys become string arrays.
|
|
101
|
+
*/
|
|
102
|
+
export declare function parseQueryParamsFromSearch(search: string): Record<string, string | string[]>;
|
|
103
|
+
/**
|
|
104
|
+
* Snapshots host-parsed query values when they already match framework semantics.
|
|
105
|
+
*
|
|
106
|
+
* @param query - Host query object exposed by a Node-backed adapter.
|
|
107
|
+
* @returns A cloned query record when all values are strings or string arrays; otherwise `undefined` for raw URL fallback.
|
|
108
|
+
*/
|
|
109
|
+
export declare function snapshotSimpleQueryRecord(query: unknown): QueryRecord | undefined;
|
|
110
|
+
/**
|
|
111
|
+
* Clones Node request headers into the framework header record shape.
|
|
112
|
+
*
|
|
113
|
+
* @param headers - Raw Node incoming headers.
|
|
114
|
+
* @returns A shallow header snapshot with array values cloned.
|
|
115
|
+
*/
|
|
116
|
+
export declare function cloneRequestHeaders(headers: IncomingHttpHeaders): FrameworkRequest['headers'];
|
|
117
|
+
/**
|
|
118
|
+
* Clones a single Node header value when it is array-backed.
|
|
119
|
+
*
|
|
120
|
+
* @param value - Header value to snapshot.
|
|
121
|
+
* @returns The original scalar value or a cloned array value.
|
|
122
|
+
*/
|
|
123
|
+
export declare function cloneHeaderValue<T extends string | string[] | undefined>(value: T): T;
|
|
124
|
+
/**
|
|
125
|
+
* Reads the primary value from a Node header value.
|
|
126
|
+
*
|
|
127
|
+
* @param headerValue - Header value that may contain multiple entries.
|
|
128
|
+
* @returns The first header value when present.
|
|
129
|
+
*/
|
|
130
|
+
export declare function readPrimaryHeaderValue(headerValue: string | string[] | undefined): string | undefined;
|
|
131
|
+
/**
|
|
132
|
+
* Normalizes a Node content-type header to its primary media type.
|
|
133
|
+
*
|
|
134
|
+
* @param headerValue - Raw content-type header value.
|
|
135
|
+
* @returns Lowercase primary media type without parameters, or `undefined` when absent.
|
|
136
|
+
*/
|
|
137
|
+
export declare function normalizePrimaryContentType(headerValue: string | string[] | undefined): string | undefined;
|
|
138
|
+
/**
|
|
139
|
+
* Parses a Node cookie header into framework cookie values.
|
|
140
|
+
*
|
|
141
|
+
* @param cookieHeader - Raw cookie header value or values.
|
|
142
|
+
* @returns Cookie name/value pairs with percent-decoded values when possible.
|
|
143
|
+
*/
|
|
144
|
+
export declare function parseCookieHeader(cookieHeader: string | string[] | undefined): Record<string, string>;
|
|
145
|
+
/**
|
|
146
|
+
* Splits a raw Node request URL into path and search components.
|
|
147
|
+
*
|
|
148
|
+
* @param rawUrl - Raw request URL, absolute URL, or undefined value from Node.
|
|
149
|
+
* @returns The pathname and search string used by framework request matching and query parsing.
|
|
150
|
+
*/
|
|
151
|
+
export declare function splitRawRequestUrl(rawUrl: string | undefined): {
|
|
152
|
+
path: string;
|
|
153
|
+
search: string;
|
|
154
|
+
};
|
|
155
|
+
/**
|
|
156
|
+
* Resolves a raw Node request URL into an absolute URL string.
|
|
157
|
+
*
|
|
158
|
+
* @param rawUrl - Raw request URL, absolute URL, or undefined value from Node.
|
|
159
|
+
* @returns An absolute URL suitable for Web-standard parsers.
|
|
160
|
+
*/
|
|
161
|
+
export declare function resolveAbsoluteRequestUrl(rawUrl: string | undefined): string;
|
|
162
|
+
export {};
|
|
163
|
+
//# sourceMappingURL=internal-node-request.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"internal-node-request.d.ts","sourceRoot":"","sources":["../../src/node/internal-node-request.ts"],"names":[],"mappings":"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"}
|