@hyperttp/core 1.3.0 → 1.3.3
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/Core/HyperCore.d.ts +185 -8
- package/Core/HyperCore.d.ts.map +1 -1
- package/Core/HyperCore.js +246 -99
- package/Core/HyperCore.js.map +1 -1
- package/README.md +169 -96
- package/package.json +2 -2
- package/transports/manager.d.ts +61 -3
- package/transports/manager.d.ts.map +1 -1
- package/transports/manager.js +130 -93
- package/transports/manager.js.map +1 -1
- package/transports/node.d.ts +26 -9
- package/transports/node.d.ts.map +1 -1
- package/transports/node.js +63 -134
- package/transports/node.js.map +1 -1
- package/utils/decompress.d.ts +20 -0
- package/utils/decompress.d.ts.map +1 -1
- package/utils/decompress.js +75 -25
- package/utils/decompress.js.map +1 -1
- package/utils/merge.js +12 -18
- package/utils/merge.js.map +1 -1
- package/utils/normalize.d.ts +26 -1
- package/utils/normalize.d.ts.map +1 -1
- package/utils/normalize.js +68 -89
- package/utils/normalize.js.map +1 -1
- package/utils/pipeline.d.ts +42 -10
- package/utils/pipeline.d.ts.map +1 -1
- package/utils/pipeline.js +34 -15
- package/utils/pipeline.js.map +1 -1
- package/utils/response.d.ts +41 -23
- package/utils/response.d.ts.map +1 -1
- package/utils/response.js +76 -36
- package/utils/response.js.map +1 -1
- package/utils/retryUtils.d.ts +20 -0
- package/utils/retryUtils.d.ts.map +1 -1
- package/utils/retryUtils.js +24 -0
- package/utils/retryUtils.js.map +1 -1
package/utils/decompress.d.ts
CHANGED
|
@@ -1,7 +1,27 @@
|
|
|
1
1
|
import type { TransportStreamExtensions } from "@hyperttp/types";
|
|
2
2
|
type StreamPayload = ReadableStream<Uint8Array> & TransportStreamExtensions;
|
|
3
3
|
type BufferPayload = Uint8Array & TransportStreamExtensions;
|
|
4
|
+
/**
|
|
5
|
+
* @ru Полностью декомпрессирует буфер, последовательно применяя цепочку алгоритмов из Content-Encoding.
|
|
6
|
+
* @en Fully decompresses a buffer by sequentially applying the Content-Encoding chain.
|
|
7
|
+
* @param body - Compressed Uint8Array body.
|
|
8
|
+
* @param encoding - Raw Content-Encoding header (may contain multiple comma-separated values).
|
|
9
|
+
* @returns Decompressed buffer with a noop dump method.
|
|
10
|
+
*/
|
|
4
11
|
export declare function decompressBuffer(body: Uint8Array, encoding: string): BufferPayload;
|
|
12
|
+
/**
|
|
13
|
+
* @ru Создаёт декомпрессирующий поток, минимизируя конвертацию между Web и Node.js стримами.
|
|
14
|
+
* @en Creates a decompressing stream while minimising conversion between Web and Node.js streams.
|
|
15
|
+
*
|
|
16
|
+
* @ru Алгоритм: для gzip/deflate при наличии глобального DecompressionStream использует Web Streams API,
|
|
17
|
+
* иначе переключается на Node.js zlib. Brotli всегда идёт через Node.js (до появления стандартного Web-потока).
|
|
18
|
+
* @en Algorithm: for gzip/deflate, if global DecompressionStream is available, uses Web Streams API;
|
|
19
|
+
* otherwise falls back to Node.js zlib. Brotli always goes through Node.js (until standard Web stream is available).
|
|
20
|
+
*
|
|
21
|
+
* @param body - Original compressed ReadableStream.
|
|
22
|
+
* @param encoding - Raw Content-Encoding header (may be a chain).
|
|
23
|
+
* @returns Decompressed ReadableStream with a dump method that cancels the stream.
|
|
24
|
+
*/
|
|
5
25
|
export declare function createDecompressStream(body: ReadableStream<Uint8Array>, encoding: string): StreamPayload;
|
|
6
26
|
export {};
|
|
7
27
|
//# sourceMappingURL=decompress.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decompress.d.ts","sourceRoot":"","sources":["../../src/utils/decompress.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAEjE,KAAK,aAAa,GAAG,cAAc,CAAC,UAAU,CAAC,GAAG,yBAAyB,CAAC;AAC5E,KAAK,aAAa,GAAG,UAAU,GAAG,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"decompress.d.ts","sourceRoot":"","sources":["../../src/utils/decompress.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAEjE,KAAK,aAAa,GAAG,cAAc,CAAC,UAAU,CAAC,GAAG,yBAAyB,CAAC;AAC5E,KAAK,aAAa,GAAG,UAAU,GAAG,yBAAyB,CAAC;AAqE5D;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,MAAM,GACf,aAAa,CASf;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,cAAc,CAAC,UAAU,CAAC,EAChC,QAAQ,EAAE,MAAM,GACf,aAAa,CA+Cf"}
|
package/utils/decompress.js
CHANGED
|
@@ -1,16 +1,34 @@
|
|
|
1
1
|
import { brotliDecompressSync, createBrotliDecompress, createGunzip, createInflate, gunzipSync, inflateSync, } from "node:zlib";
|
|
2
2
|
import { Readable } from "node:stream";
|
|
3
|
+
/**
|
|
4
|
+
* @ru Разбирает заголовок Content-Encoding в массив алгоритмов, исключая "identity".
|
|
5
|
+
* @en Parses Content-Encoding header into an array of algorithms, excluding "identity".
|
|
6
|
+
* @param encoding - Raw Content-Encoding header value (e.g., "gzip, deflate").
|
|
7
|
+
* @returns Array of normalized encoding names.
|
|
8
|
+
*/
|
|
3
9
|
function parseEncodings(encoding) {
|
|
4
10
|
return encoding
|
|
5
11
|
.split(",")
|
|
6
12
|
.map((part) => part.trim().toLowerCase())
|
|
7
13
|
.filter((part) => part.length > 0 && part !== "identity");
|
|
8
14
|
}
|
|
15
|
+
/**
|
|
16
|
+
* @ru Добавляет noop-метод dump к буферу, сохраняя совместимость с TransportStreamExtensions.
|
|
17
|
+
* @en Attaches a noop dump method to a buffer, maintaining TransportStreamExtensions compatibility.
|
|
18
|
+
* @param buffer - The Uint8Array buffer.
|
|
19
|
+
* @returns Buffer with dump method attached.
|
|
20
|
+
*/
|
|
9
21
|
function attachNoopDump(buffer) {
|
|
10
22
|
const payload = buffer;
|
|
11
23
|
payload.dump = async () => { };
|
|
12
24
|
return payload;
|
|
13
25
|
}
|
|
26
|
+
/**
|
|
27
|
+
* @ru Добавляет метод dump к стриму, который отменяет (cancel) поток.
|
|
28
|
+
* @en Attaches a dump method to a stream that cancels the stream.
|
|
29
|
+
* @param stream - ReadableStream to enhance.
|
|
30
|
+
* @returns Stream with dump method attached.
|
|
31
|
+
*/
|
|
14
32
|
function attachStreamDump(stream) {
|
|
15
33
|
const payload = stream;
|
|
16
34
|
payload.dump = async () => {
|
|
@@ -23,8 +41,16 @@ function attachStreamDump(stream) {
|
|
|
23
41
|
};
|
|
24
42
|
return payload;
|
|
25
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* @ru Применяет один этап декомпрессии к буферу синхронно (для одиночных чанков).
|
|
46
|
+
* @en Applies a single decompression step to a buffer synchronously (for single chunks).
|
|
47
|
+
* @param input - Compressed buffer.
|
|
48
|
+
* @param encoding - Single encoding name ("gzip", "deflate", "br").
|
|
49
|
+
* @returns Decompressed buffer, or original if encoding is unknown.
|
|
50
|
+
* @throws If decompression fails due to corrupt data.
|
|
51
|
+
*/
|
|
26
52
|
function decompressOnce(input, encoding) {
|
|
27
|
-
const buffer = Buffer.from(input);
|
|
53
|
+
const buffer = Buffer.from(input.buffer, input.byteOffset, input.byteLength);
|
|
28
54
|
switch (encoding) {
|
|
29
55
|
case "gzip":
|
|
30
56
|
case "x-gzip":
|
|
@@ -37,42 +63,66 @@ function decompressOnce(input, encoding) {
|
|
|
37
63
|
return input;
|
|
38
64
|
}
|
|
39
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* @ru Полностью декомпрессирует буфер, последовательно применяя цепочку алгоритмов из Content-Encoding.
|
|
68
|
+
* @en Fully decompresses a buffer by sequentially applying the Content-Encoding chain.
|
|
69
|
+
* @param body - Compressed Uint8Array body.
|
|
70
|
+
* @param encoding - Raw Content-Encoding header (may contain multiple comma-separated values).
|
|
71
|
+
* @returns Decompressed buffer with a noop dump method.
|
|
72
|
+
*/
|
|
40
73
|
export function decompressBuffer(body, encoding) {
|
|
41
74
|
let current = body;
|
|
42
|
-
|
|
43
|
-
|
|
75
|
+
const encodings = parseEncodings(encoding);
|
|
76
|
+
for (let i = 0; i < encodings.length; i++) {
|
|
77
|
+
current = decompressOnce(current, encodings[i]);
|
|
44
78
|
}
|
|
45
79
|
return attachNoopDump(current);
|
|
46
80
|
}
|
|
81
|
+
/**
|
|
82
|
+
* @ru Создаёт декомпрессирующий поток, минимизируя конвертацию между Web и Node.js стримами.
|
|
83
|
+
* @en Creates a decompressing stream while minimising conversion between Web and Node.js streams.
|
|
84
|
+
*
|
|
85
|
+
* @ru Алгоритм: для gzip/deflate при наличии глобального DecompressionStream использует Web Streams API,
|
|
86
|
+
* иначе переключается на Node.js zlib. Brotli всегда идёт через Node.js (до появления стандартного Web-потока).
|
|
87
|
+
* @en Algorithm: for gzip/deflate, if global DecompressionStream is available, uses Web Streams API;
|
|
88
|
+
* otherwise falls back to Node.js zlib. Brotli always goes through Node.js (until standard Web stream is available).
|
|
89
|
+
*
|
|
90
|
+
* @param body - Original compressed ReadableStream.
|
|
91
|
+
* @param encoding - Raw Content-Encoding header (may be a chain).
|
|
92
|
+
* @returns Decompressed ReadableStream with a dump method that cancels the stream.
|
|
93
|
+
*/
|
|
47
94
|
export function createDecompressStream(body, encoding) {
|
|
95
|
+
const encodings = parseEncodings(encoding);
|
|
96
|
+
if (encodings.length === 0)
|
|
97
|
+
return attachStreamDump(body);
|
|
48
98
|
let current = body;
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
99
|
+
let nodeReadableStream = null;
|
|
100
|
+
for (let i = 0; i < encodings.length; i++) {
|
|
101
|
+
const enc = encodings[i];
|
|
102
|
+
const isGzip = enc === "gzip" || enc === "x-gzip";
|
|
103
|
+
const isDeflate = enc === "deflate";
|
|
104
|
+
if ((isGzip || isDeflate) && typeof DecompressionStream !== "undefined") {
|
|
105
|
+
if (nodeReadableStream) {
|
|
106
|
+
current = Readable.toWeb(nodeReadableStream);
|
|
107
|
+
nodeReadableStream = null;
|
|
54
108
|
}
|
|
55
|
-
|
|
56
|
-
const decompressed = nodeReadable.pipe(createGunzip());
|
|
57
|
-
current = Readable.toWeb(decompressed);
|
|
58
|
-
continue;
|
|
109
|
+
current = current.pipeThrough(new DecompressionStream(isGzip ? "gzip" : "deflate"));
|
|
59
110
|
}
|
|
60
|
-
|
|
61
|
-
if (
|
|
62
|
-
|
|
63
|
-
continue;
|
|
111
|
+
else {
|
|
112
|
+
if (!nodeReadableStream) {
|
|
113
|
+
nodeReadableStream = Readable.fromWeb(current);
|
|
64
114
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
const nodeReadable = Readable.fromWeb(current);
|
|
72
|
-
const decompressed = nodeReadable.pipe(createBrotliDecompress());
|
|
73
|
-
current = Readable.toWeb(decompressed);
|
|
115
|
+
if (isGzip)
|
|
116
|
+
nodeReadableStream = nodeReadableStream.pipe(createGunzip());
|
|
117
|
+
else if (isDeflate)
|
|
118
|
+
nodeReadableStream = nodeReadableStream.pipe(createInflate());
|
|
119
|
+
else if (enc === "br")
|
|
120
|
+
nodeReadableStream = nodeReadableStream.pipe(createBrotliDecompress());
|
|
74
121
|
}
|
|
75
122
|
}
|
|
123
|
+
if (nodeReadableStream) {
|
|
124
|
+
current = Readable.toWeb(nodeReadableStream);
|
|
125
|
+
}
|
|
76
126
|
return attachStreamDump(current);
|
|
77
127
|
}
|
|
78
128
|
//# sourceMappingURL=decompress.js.map
|
package/utils/decompress.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decompress.js","sourceRoot":"","sources":["../../src/utils/decompress.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,YAAY,EACZ,aAAa,EACb,UAAU,EACV,WAAW,GACZ,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAMvC,SAAS,cAAc,CAAC,QAAgB;IACtC,OAAO,QAAQ;SACZ,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;SACxC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,KAAK,UAAU,CAAC,CAAC;AAC9D,CAAC;AAED,SAAS,cAAc,CAAC,MAAkB;IACxC,MAAM,OAAO,GAAG,MAAuB,CAAC;IACxC,OAAO,CAAC,IAAI,GAAG,KAAK,IAAmB,EAAE,GAAE,CAAC,CAAC;IAC7C,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,gBAAgB,CAAC,MAAkC;IAC1D,MAAM,OAAO,GAAG,MAAuB,CAAC;IACxC,OAAO,CAAC,IAAI,GAAG,KAAK,IAAmB,EAAE;QACvC,IAAI,CAAC;YACH,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC;QACzB,CAAC;QAAC,MAAM,CAAC;YACP,EAAE;QACJ,CAAC;IACH,CAAC,CAAC;IACF,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,cAAc,CAAC,KAAiB,EAAE,QAAgB;IACzD,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"decompress.js","sourceRoot":"","sources":["../../src/utils/decompress.ts"],"names":[],"mappings":"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"}
|
package/utils/merge.js
CHANGED
|
@@ -7,23 +7,17 @@
|
|
|
7
7
|
*/
|
|
8
8
|
export function deepMerge(target, source) {
|
|
9
9
|
const output = { ...target };
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
else if (sourceValue !== undefined) {
|
|
24
|
-
output[key] = sourceValue;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
10
|
+
for (const key of Object.keys(source)) {
|
|
11
|
+
const sourceValue = source[key];
|
|
12
|
+
const targetValue = output[key];
|
|
13
|
+
if (isObject(sourceValue) && isObject(targetValue)) {
|
|
14
|
+
output[key] = deepMerge(targetValue, sourceValue);
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
if (sourceValue !== undefined) {
|
|
18
|
+
output[key] = isObject(sourceValue)
|
|
19
|
+
? deepMerge({}, sourceValue)
|
|
20
|
+
: sourceValue;
|
|
27
21
|
}
|
|
28
22
|
}
|
|
29
23
|
return output;
|
|
@@ -34,6 +28,6 @@ export function deepMerge(target, source) {
|
|
|
34
28
|
* @param item - Evaluated runtime variable value context.
|
|
35
29
|
*/
|
|
36
30
|
function isObject(item) {
|
|
37
|
-
return
|
|
31
|
+
return Object.prototype.toString.call(item) === "[object Object]";
|
|
38
32
|
}
|
|
39
33
|
//# sourceMappingURL=merge.js.map
|
package/utils/merge.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"merge.js","sourceRoot":"","sources":["../../src/utils/merge.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CAGvB,MAAS,EAAE,MAAS;IACpB,MAAM,MAAM,
|
|
1
|
+
{"version":3,"file":"merge.js","sourceRoot":"","sources":["../../src/utils/merge.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CAGvB,MAAS,EAAE,MAAS;IACpB,MAAM,MAAM,GAA4B,EAAE,GAAG,MAAM,EAAE,CAAC;IAEtD,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACtC,MAAM,WAAW,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QAChC,MAAM,WAAW,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QAEhC,IAAI,QAAQ,CAAC,WAAW,CAAC,IAAI,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;YACnD,MAAM,CAAC,GAAG,CAAC,GAAG,SAAS,CACrB,WAAsC,EACtC,WAAsC,CACvC,CAAC;YACF,SAAS;QACX,CAAC;QAED,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;YAC9B,MAAM,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,WAAW,CAAC;gBACjC,CAAC,CAAC,SAAS,CAAC,EAAE,EAAE,WAAsC,CAAC;gBACvD,CAAC,CAAC,WAAW,CAAC;QAClB,CAAC;IACH,CAAC;IAED,OAAO,MAAe,CAAC;AACzB,CAAC;AAED;;;;GAIG;AACH,SAAS,QAAQ,CAAC,IAAa;IAC7B,OAAO,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,iBAAiB,CAAC;AACpE,CAAC"}
|
package/utils/normalize.d.ts
CHANGED
|
@@ -1,7 +1,32 @@
|
|
|
1
1
|
import type { Method, RequestBodyData } from "@hyperttp/types";
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* @ru Нормализует строку HTTP-метода в стандартную заглавную форму (например, "get" → "GET").
|
|
4
|
+
* @en Normalizes an HTTP method string to its standard uppercase form (e.g., "get" → "GET").
|
|
5
|
+
* @param method - Raw method string.
|
|
6
|
+
* @returns Normalized method (e.g., "GET", "POST", etc.).
|
|
7
|
+
*/
|
|
3
8
|
export declare function normalizeMethod(method: string): Method;
|
|
9
|
+
/**
|
|
10
|
+
* @ru Извлекает и нормализует URL из строки или объекта запроса (поддерживает поля url, _url, или комбинацию scheme/host/path).
|
|
11
|
+
* @en Extracts and normalizes a URL from a string or request object (supports url, _url fields, or scheme/host/path combination).
|
|
12
|
+
* @param req - Request object or plain URL string.
|
|
13
|
+
* @returns Normalized URL string.
|
|
14
|
+
* @throws If URL cannot be determined.
|
|
15
|
+
*/
|
|
4
16
|
export declare function normalizeUrl(req: any): string;
|
|
17
|
+
/**
|
|
18
|
+
* @ru Нормализует входные заголовки (объект, массив пар) в стандартный объект с ключами в нижнем регистре и правильным объединением значений.
|
|
19
|
+
* @en Normalizes input headers (object, array of pairs) into a standard object with lower‑case keys and proper value merging.
|
|
20
|
+
* @param headers - Raw headers (plain object, array of [key, value] pairs, or null/undefined).
|
|
21
|
+
* @returns Normalized headers object (keys are lower‑case, values are strings or arrays for set-cookie).
|
|
22
|
+
*/
|
|
5
23
|
export declare function normalizeHeaders(headers: unknown): Record<string, string | string[]>;
|
|
24
|
+
/**
|
|
25
|
+
* @ru Возвращает тело запроса только для методов, поддерживающих тело (не GET/HEAD), иначе undefined.
|
|
26
|
+
* @en Returns the request body only for methods that support a body (not GET/HEAD), otherwise undefined.
|
|
27
|
+
* @param method - HTTP method.
|
|
28
|
+
* @param body - Original request body (if any).
|
|
29
|
+
* @returns The body for allowed methods, or undefined for GET/HEAD.
|
|
30
|
+
*/
|
|
6
31
|
export declare function normalizeBody(method: Method, body: RequestBodyData | undefined): RequestBodyData | undefined;
|
|
7
32
|
//# sourceMappingURL=normalize.d.ts.map
|
package/utils/normalize.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../src/utils/normalize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../src/utils/normalize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAuC/D;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAGtD;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,CAU7C;AA0CD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,OAAO,GACf,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CA+CnC;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,eAAe,GAAG,SAAS,GAChC,eAAe,GAAG,SAAS,CAE7B"}
|
package/utils/normalize.js
CHANGED
|
@@ -33,12 +33,23 @@ const METHOD_CACHE = {
|
|
|
33
33
|
options: "OPTIONS",
|
|
34
34
|
OPTIONS: "OPTIONS",
|
|
35
35
|
};
|
|
36
|
+
/**
|
|
37
|
+
* @ru Нормализует строку HTTP-метода в стандартную заглавную форму (например, "get" → "GET").
|
|
38
|
+
* @en Normalizes an HTTP method string to its standard uppercase form (e.g., "get" → "GET").
|
|
39
|
+
* @param method - Raw method string.
|
|
40
|
+
* @returns Normalized method (e.g., "GET", "POST", etc.).
|
|
41
|
+
*/
|
|
36
42
|
export function normalizeMethod(method) {
|
|
37
43
|
const cached = METHOD_CACHE[method];
|
|
38
|
-
|
|
39
|
-
return cached;
|
|
40
|
-
return method.toUpperCase();
|
|
44
|
+
return cached !== undefined ? cached : method.toUpperCase();
|
|
41
45
|
}
|
|
46
|
+
/**
|
|
47
|
+
* @ru Извлекает и нормализует URL из строки или объекта запроса (поддерживает поля url, _url, или комбинацию scheme/host/path).
|
|
48
|
+
* @en Extracts and normalizes a URL from a string or request object (supports url, _url fields, or scheme/host/path combination).
|
|
49
|
+
* @param req - Request object or plain URL string.
|
|
50
|
+
* @returns Normalized URL string.
|
|
51
|
+
* @throws If URL cannot be determined.
|
|
52
|
+
*/
|
|
42
53
|
export function normalizeUrl(req) {
|
|
43
54
|
if (typeof req === "string")
|
|
44
55
|
return req;
|
|
@@ -51,45 +62,58 @@ export function normalizeUrl(req) {
|
|
|
51
62
|
}
|
|
52
63
|
throw new Error("URL missing in request");
|
|
53
64
|
}
|
|
65
|
+
/**
|
|
66
|
+
* @ru Вспомогательная функция для добавления заголовка в результирующий объект с учётом правил объединения (одиночные, множественные, cookie, set-cookie).
|
|
67
|
+
* @en Helper function to append a header to the result object, respecting merging rules (single-value, multi-value, cookie, set-cookie).
|
|
68
|
+
* @param out - Target object accumulating headers.
|
|
69
|
+
* @param lowerKey - Header name in lower case.
|
|
70
|
+
* @param value - Header value as a string.
|
|
71
|
+
*/
|
|
72
|
+
function appendHeader(out, lowerKey, value) {
|
|
73
|
+
if (SINGLE_VALUE_HEADERS[lowerKey] !== undefined) {
|
|
74
|
+
out[lowerKey] = value;
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
const existing = out[lowerKey];
|
|
78
|
+
if (existing === undefined) {
|
|
79
|
+
out[lowerKey] = value;
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
if (lowerKey === "set-cookie") {
|
|
83
|
+
if (Array.isArray(existing)) {
|
|
84
|
+
existing.push(value);
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
out[lowerKey] = [existing, value];
|
|
88
|
+
}
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
if (lowerKey === "cookie" || lowerKey === "cookie2") {
|
|
92
|
+
out[lowerKey] = `${existing}; ${value}`;
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
out[lowerKey] = `${existing}, ${value}`;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* @ru Нормализует входные заголовки (объект, массив пар) в стандартный объект с ключами в нижнем регистре и правильным объединением значений.
|
|
99
|
+
* @en Normalizes input headers (object, array of pairs) into a standard object with lower‑case keys and proper value merging.
|
|
100
|
+
* @param headers - Raw headers (plain object, array of [key, value] pairs, or null/undefined).
|
|
101
|
+
* @returns Normalized headers object (keys are lower‑case, values are strings or arrays for set-cookie).
|
|
102
|
+
*/
|
|
54
103
|
export function normalizeHeaders(headers) {
|
|
55
104
|
const out = Object.create(null);
|
|
56
105
|
if (!headers || typeof headers !== "object")
|
|
57
106
|
return out;
|
|
58
107
|
if (Array.isArray(headers)) {
|
|
59
|
-
|
|
108
|
+
const len = headers.length;
|
|
109
|
+
for (let i = 0; i < len; i += 2) {
|
|
60
110
|
const key = headers[i];
|
|
61
111
|
if (typeof key !== "string" || !key)
|
|
62
112
|
continue;
|
|
63
113
|
const rawValue = headers[i + 1];
|
|
64
114
|
if (rawValue === undefined || rawValue === null)
|
|
65
115
|
continue;
|
|
66
|
-
|
|
67
|
-
const value = typeof rawValue === "string" ? rawValue : String(rawValue);
|
|
68
|
-
if (SINGLE_VALUE_HEADERS[lower] !== undefined) {
|
|
69
|
-
out[lower] = value;
|
|
70
|
-
continue;
|
|
71
|
-
}
|
|
72
|
-
const existing = out[lower];
|
|
73
|
-
if (existing === undefined) {
|
|
74
|
-
out[lower] = value;
|
|
75
|
-
continue;
|
|
76
|
-
}
|
|
77
|
-
if (lower === "set-cookie") {
|
|
78
|
-
if (Array.isArray(existing)) {
|
|
79
|
-
existing.push(value);
|
|
80
|
-
}
|
|
81
|
-
else {
|
|
82
|
-
out[lower] = [existing, value];
|
|
83
|
-
}
|
|
84
|
-
continue;
|
|
85
|
-
}
|
|
86
|
-
if (lower === "cookie" || lower === "cookie2") {
|
|
87
|
-
out[lower] = `${existing}; ${value}`;
|
|
88
|
-
continue;
|
|
89
|
-
}
|
|
90
|
-
out[lower] = Array.isArray(existing)
|
|
91
|
-
? `${existing.join(", ")}, ${value}`
|
|
92
|
-
: `${existing}, ${value}`;
|
|
116
|
+
appendHeader(out, key.toLowerCase(), typeof rawValue === "string" ? rawValue : String(rawValue));
|
|
93
117
|
}
|
|
94
118
|
return out;
|
|
95
119
|
}
|
|
@@ -101,74 +125,29 @@ export function normalizeHeaders(headers) {
|
|
|
101
125
|
continue;
|
|
102
126
|
const lower = key.toLowerCase();
|
|
103
127
|
if (Array.isArray(val)) {
|
|
104
|
-
|
|
128
|
+
const vLen = val.length;
|
|
129
|
+
for (let i = 0; i < vLen; i++) {
|
|
105
130
|
const rawValue = val[i];
|
|
106
|
-
if (rawValue
|
|
107
|
-
|
|
108
|
-
const value = typeof rawValue === "string" ? rawValue : String(rawValue);
|
|
109
|
-
if (SINGLE_VALUE_HEADERS[lower] !== undefined) {
|
|
110
|
-
out[lower] = value;
|
|
111
|
-
continue;
|
|
112
|
-
}
|
|
113
|
-
const existing = out[lower];
|
|
114
|
-
if (existing === undefined) {
|
|
115
|
-
out[lower] = value;
|
|
116
|
-
continue;
|
|
117
|
-
}
|
|
118
|
-
if (lower === "set-cookie") {
|
|
119
|
-
if (Array.isArray(existing)) {
|
|
120
|
-
existing.push(value);
|
|
121
|
-
}
|
|
122
|
-
else {
|
|
123
|
-
out[lower] = [existing, value];
|
|
124
|
-
}
|
|
125
|
-
continue;
|
|
126
|
-
}
|
|
127
|
-
if (lower === "cookie" || lower === "cookie2") {
|
|
128
|
-
out[lower] = `${existing}; ${value}`;
|
|
129
|
-
continue;
|
|
131
|
+
if (rawValue !== undefined && rawValue !== null) {
|
|
132
|
+
appendHeader(out, lower, typeof rawValue === "string" ? rawValue : String(rawValue));
|
|
130
133
|
}
|
|
131
|
-
out[lower] = Array.isArray(existing)
|
|
132
|
-
? `${existing.join(", ")}, ${value}`
|
|
133
|
-
: `${existing}, ${value}`;
|
|
134
134
|
}
|
|
135
135
|
}
|
|
136
136
|
else {
|
|
137
|
-
|
|
138
|
-
if (SINGLE_VALUE_HEADERS[lower] !== undefined) {
|
|
139
|
-
out[lower] = value;
|
|
140
|
-
continue;
|
|
141
|
-
}
|
|
142
|
-
const existing = out[lower];
|
|
143
|
-
if (existing === undefined) {
|
|
144
|
-
out[lower] = value;
|
|
145
|
-
continue;
|
|
146
|
-
}
|
|
147
|
-
if (lower === "set-cookie") {
|
|
148
|
-
if (Array.isArray(existing)) {
|
|
149
|
-
existing.push(value);
|
|
150
|
-
}
|
|
151
|
-
else {
|
|
152
|
-
out[lower] = [existing, value];
|
|
153
|
-
}
|
|
154
|
-
continue;
|
|
155
|
-
}
|
|
156
|
-
if (lower === "cookie" || lower === "cookie2") {
|
|
157
|
-
out[lower] = `${existing}; ${value}`;
|
|
158
|
-
continue;
|
|
159
|
-
}
|
|
160
|
-
out[lower] = Array.isArray(existing)
|
|
161
|
-
? `${existing.join(", ")}, ${value}`
|
|
162
|
-
: `${existing}, ${value}`;
|
|
137
|
+
appendHeader(out, lower, typeof val === "string" ? val : String(val));
|
|
163
138
|
}
|
|
164
139
|
}
|
|
165
140
|
}
|
|
166
141
|
return out;
|
|
167
142
|
}
|
|
143
|
+
/**
|
|
144
|
+
* @ru Возвращает тело запроса только для методов, поддерживающих тело (не GET/HEAD), иначе undefined.
|
|
145
|
+
* @en Returns the request body only for methods that support a body (not GET/HEAD), otherwise undefined.
|
|
146
|
+
* @param method - HTTP method.
|
|
147
|
+
* @param body - Original request body (if any).
|
|
148
|
+
* @returns The body for allowed methods, or undefined for GET/HEAD.
|
|
149
|
+
*/
|
|
168
150
|
export function normalizeBody(method, body) {
|
|
169
|
-
|
|
170
|
-
return undefined;
|
|
171
|
-
}
|
|
172
|
-
return body ?? undefined;
|
|
151
|
+
return method === "GET" || method === "HEAD" ? undefined : body;
|
|
173
152
|
}
|
|
174
153
|
//# sourceMappingURL=normalize.js.map
|
package/utils/normalize.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normalize.js","sourceRoot":"","sources":["../../src/utils/normalize.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"normalize.js","sourceRoot":"","sources":["../../src/utils/normalize.ts"],"names":[],"mappings":"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"}
|
package/utils/pipeline.d.ts
CHANGED
|
@@ -4,48 +4,80 @@ import type { HyperPlugin, PluginContext, InternalRequest, HttpResponse, Hypertt
|
|
|
4
4
|
* @en Hook record structure with metadata for optimization and sorting.
|
|
5
5
|
*/
|
|
6
6
|
export interface HookRecord<T> {
|
|
7
|
+
/** @ru Уникальное имя хука. @en Unique hook name. */
|
|
7
8
|
readonly name: string;
|
|
9
|
+
/** @ru Приоритет выполнения (выше значение — раньше выполнение). @en Execution priority (higher value runs earlier). */
|
|
8
10
|
readonly priority: number;
|
|
11
|
+
/** @ru Функция-обработчик. @en Handler function. */
|
|
9
12
|
readonly run: T;
|
|
10
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* @ru Контейнер конвейеров для различных фаз обработки запроса/ответа.
|
|
16
|
+
* @en Pipeline container for different request/response processing phases.
|
|
17
|
+
*/
|
|
11
18
|
export interface PipelineContainer {
|
|
19
|
+
/** @ru Хуки, выполняемые перед отправкой запроса. @en Hooks executed before sending the request. */
|
|
12
20
|
readonly request: HookRecord<Required<HyperPlugin>["onRequest"]>[];
|
|
21
|
+
/** @ru Хуки, обрабатывающие сырые данные транспорта. @en Hooks processing raw transport data. */
|
|
13
22
|
readonly responseData: HookRecord<Required<HyperPlugin>["onResponseData"]>[];
|
|
23
|
+
/** @ru Хуки, мутирующие ответ (последовательное выполнение). @en Hooks that mutate the response (sequential execution). */
|
|
14
24
|
readonly responseMutators: HookRecord<Required<HyperPlugin>["onResponse"]>[];
|
|
25
|
+
/** @ru Хуки с побочными эффектами (выполняются в фоне). @en Side-effect hooks (executed in the background). */
|
|
15
26
|
readonly responseSideEffects: HookRecord<Required<HyperPlugin>["onResponse"]>[];
|
|
27
|
+
/** @ru Хуки для перехвата ошибок. @en Error interception hooks. */
|
|
16
28
|
readonly error: HookRecord<Required<HyperPlugin>["onError"]>[];
|
|
17
29
|
}
|
|
18
30
|
/**
|
|
19
|
-
* @ru
|
|
31
|
+
* @ru Создаёт пустой контейнер для конвейеров плагинов.
|
|
20
32
|
* @en Creates an empty container for plugin pipelines.
|
|
33
|
+
* @returns An empty pipeline container.
|
|
21
34
|
*/
|
|
22
35
|
export declare function createPipelines(): PipelineContainer;
|
|
23
36
|
/**
|
|
24
37
|
* @ru Вставляет хук в массив с сохранением сортировки по убыванию приоритета (деревья поиска тут избыточны).
|
|
25
38
|
* @en Inserts a hook into the array maintaining descending priority order.
|
|
39
|
+
* @param list - Target array to insert into.
|
|
40
|
+
* @param hook - Hook record to insert.
|
|
26
41
|
*/
|
|
27
42
|
export declare function insertHookSorted<T>(list: HookRecord<T>[], hook: HookRecord<T>): void;
|
|
28
43
|
/**
|
|
29
|
-
* @ru Выполняет конвейер пред-запроса. Поддерживает short-circuit (ранний возврат ответа).
|
|
30
|
-
* Использует Fast-Path для синхронных хуков без аллокации микротасок.
|
|
44
|
+
* @ru Выполняет конвейер пред-запроса. Поддерживает short-circuit (ранний возврат ответа). Использует Fast-Path для синхронных хуков без аллокации микротасок.
|
|
31
45
|
* @en Executes the pre-request pipeline. Supports short-circuiting with fast-path for sync hooks.
|
|
46
|
+
* @param hooks - Array of request hooks.
|
|
47
|
+
* @param req - Internal request object.
|
|
48
|
+
* @param ctx - Plugin context.
|
|
49
|
+
* @returns A response if short-circuited, null otherwise, or a promise.
|
|
32
50
|
*/
|
|
33
51
|
export declare function executeRequestPipeline(hooks: readonly HookRecord<Required<HyperPlugin>["onRequest"]>[], req: InternalRequest, ctx: PluginContext): Promise<HttpResponse<unknown> | null> | HttpResponse<unknown> | null | void;
|
|
34
52
|
/**
|
|
35
|
-
* @ru Выполняет низкоуровневый конвейер трансформации сырых данных транспорта (фаза DATA).
|
|
36
|
-
*
|
|
37
|
-
* @
|
|
53
|
+
* @ru Выполняет низкоуровневый конвейер трансформации сырых данных транспорта (фаза DATA). Если хук возвращает измененный TransportResponse, он передается дальше по цепочке.
|
|
54
|
+
* @en Executes low-level transport data transformation pipeline (DATA phase). If a hook returns a modified TransportResponse, it is passed along the chain.
|
|
55
|
+
* @param hooks - Array of response data hooks.
|
|
56
|
+
* @param res - Current transport response.
|
|
57
|
+
* @param ctx - Plugin context.
|
|
58
|
+
* @returns The (possibly transformed) transport response, either directly or wrapped in a promise.
|
|
38
59
|
*/
|
|
39
60
|
export declare function executeResponseDataPipeline(hooks: readonly HookRecord<Required<HyperPlugin>["onResponseData"]>[], res: TransportResponse, ctx: PluginContext): Promise<TransportResponse> | TransportResponse;
|
|
40
61
|
/**
|
|
41
|
-
* @ru Выполняет конвейер пост-ответа. Разделен на мутаторы (последовательно) и сайд-эффекты (в фоне).
|
|
42
|
-
*
|
|
43
|
-
* @
|
|
62
|
+
* @ru Выполняет конвейер пост-ответа. Разделен на мутаторы (последовательно) и сайд-эффекты (в фоне). Оптимизирован для минимизации выделения памяти под замыкания логгера.
|
|
63
|
+
* @en Executes the post-response pipeline. Split into mutators (sequential) and side-effects (background). Optimized to minimize memory allocations for logger closures.
|
|
64
|
+
* @param mutators - Hooks that mutate the response (executed sequentially).
|
|
65
|
+
* @param sideEffects - Hooks that run in background, errors are logged but do not break the main flow.
|
|
66
|
+
* @param res - HTTP response object.
|
|
67
|
+
* @param req - Internal request object.
|
|
68
|
+
* @param ctx - Plugin context.
|
|
69
|
+
* @param logger - Optional logger for side-effect errors.
|
|
70
|
+
* @returns A promise if any mutator returns a promise, otherwise void.
|
|
44
71
|
*/
|
|
45
72
|
export declare function executeResponsePipeline(mutators: readonly HookRecord<Required<HyperPlugin>["onResponse"]>[], sideEffects: readonly HookRecord<Required<HyperPlugin>["onResponse"]>[], res: HttpResponse<unknown>, req: InternalRequest, ctx: PluginContext, logger?: HttpClientOptions["logger"]): Promise<void> | void;
|
|
46
73
|
/**
|
|
47
74
|
* @ru Выполняет конвейер перехвата ошибок. Первый вернувший HttpResponse плагин прерывает панику.
|
|
48
|
-
* @en Executes the error interception pipeline.
|
|
75
|
+
* @en Executes the error interception pipeline. The first plugin that returns HttpResponse stops the panic.
|
|
76
|
+
* @param hooks - Array of error hooks.
|
|
77
|
+
* @param error - The error that occurred.
|
|
78
|
+
* @param req - Internal request object.
|
|
79
|
+
* @param ctx - Plugin context.
|
|
80
|
+
* @returns A response if recovered, null otherwise, or a promise.
|
|
49
81
|
*/
|
|
50
82
|
export declare function executeErrorPipeline(hooks: readonly HookRecord<Required<HyperPlugin>["onError"]>[], error: HyperttpError, req: InternalRequest, ctx: PluginContext): Promise<HttpResponse<unknown> | null> | HttpResponse<unknown> | null | void;
|
|
51
83
|
//# sourceMappingURL=pipeline.d.ts.map
|