@gjsify/fetch 0.3.15 → 0.3.17

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/lib/esm/body.js CHANGED
@@ -1,349 +1 @@
1
- import { Blob } from "./utils/blob-from.js";
2
- import { FetchBaseError } from "./errors/base.js";
3
- import { FetchError } from "./errors/fetch-error.js";
4
- import { isBlob, isURLSearchParameters } from "./utils/is.js";
5
- import { URLSearchParams } from "@gjsify/url";
6
- import { Buffer } from "node:buffer";
7
- import { PassThrough, Readable, Stream as Stream$1, pipeline } from "node:stream";
8
- import { FormData, formDataToBlob } from "@gjsify/formdata";
9
-
10
- //#region src/body.ts
11
- const pipeline$1 = (source, dest) => new Promise((resolve, reject) => {
12
- pipeline(source, dest, (err) => {
13
- if (err) reject(err);
14
- else resolve();
15
- });
16
- });
17
- const INTERNALS = Symbol("Body internals");
18
- function isAnyArrayBuffer(val) {
19
- return val instanceof ArrayBuffer || typeof SharedArrayBuffer !== "undefined" && val instanceof SharedArrayBuffer;
20
- }
21
- function isBoxedPrimitive(val) {
22
- return val instanceof String || val instanceof Number || val instanceof Boolean || typeof Symbol !== "undefined" && val instanceof Symbol || typeof BigInt !== "undefined" && val instanceof BigInt;
23
- }
24
- /**
25
- * Body mixin
26
- *
27
- * Ref: https://fetch.spec.whatwg.org/#body
28
- *
29
- * @param body Readable stream
30
- * @param opts Response options
31
- */
32
- var Body = class {
33
- [INTERNALS] = {
34
- body: null,
35
- stream: null,
36
- boundary: "",
37
- disturbed: false,
38
- error: null
39
- };
40
- size = 0;
41
- constructor(body, options = { size: 0 }) {
42
- this.size = options.size || 0;
43
- if (body === null || body === undefined) {
44
- this[INTERNALS].body = null;
45
- } else if (isURLSearchParameters(body)) {
46
- this[INTERNALS].body = Buffer.from(body.toString());
47
- } else if (isBlob(body)) {
48
- this[INTERNALS].body = body;
49
- } else if (Buffer.isBuffer(body)) {
50
- this[INTERNALS].body = body;
51
- } else if (isAnyArrayBuffer(body)) {
52
- this[INTERNALS].body = Buffer.from(body);
53
- } else if (ArrayBuffer.isView(body)) {
54
- this[INTERNALS].body = Buffer.from(body.buffer, body.byteOffset, body.byteLength);
55
- } else if (body instanceof Readable) {
56
- this[INTERNALS].body = body;
57
- } else if (typeof ReadableStream !== "undefined" && body instanceof ReadableStream) {
58
- this[INTERNALS].body = readableStreamToReadable(body);
59
- } else if (body instanceof FormData) {
60
- const blob = formDataToBlob(body);
61
- this[INTERNALS].body = blob;
62
- this[INTERNALS].boundary = blob.type?.split("boundary=")?.[1] ?? "";
63
- } else if (typeof body === "string") {
64
- this[INTERNALS].body = Buffer.from(body);
65
- } else if (body instanceof URLSearchParams) {
66
- this[INTERNALS].body = Buffer.from(body.toString());
67
- } else {
68
- console.warn(`Unknown body type "${typeof body}", try to parse the body to string!`);
69
- this[INTERNALS].body = Buffer.from(String(body));
70
- }
71
- const b = this[INTERNALS].body;
72
- if (Buffer.isBuffer(b)) {
73
- this[INTERNALS].stream = Readable.from(b);
74
- } else if (isBlob(b)) {
75
- this[INTERNALS].stream = Readable.from(blobToAsyncIterable(b));
76
- } else if (b instanceof Readable) {
77
- this[INTERNALS].stream = b;
78
- }
79
- if (b instanceof Stream$1) {
80
- b.on("error", (error_) => {
81
- const error = error_ instanceof FetchBaseError ? error_ : new FetchError(`Invalid response body while trying to fetch ${this.url}: ${error_.message}`, "system", error_);
82
- this[INTERNALS].error = error;
83
- });
84
- }
85
- }
86
- get body() {
87
- const stream = this[INTERNALS].stream;
88
- if (!stream) return null;
89
- if (typeof ReadableStream !== "undefined") {
90
- let closed = false;
91
- return new ReadableStream({
92
- start(controller) {
93
- stream.on("data", (chunk) => {
94
- if (closed) return;
95
- try {
96
- controller.enqueue(chunk instanceof Uint8Array ? chunk : new Uint8Array(chunk));
97
- } catch {}
98
- });
99
- stream.on("end", () => {
100
- if (closed) return;
101
- closed = true;
102
- try {
103
- controller.close();
104
- } catch {}
105
- });
106
- stream.on("error", (err) => {
107
- if (closed) return;
108
- closed = true;
109
- try {
110
- controller.error(err);
111
- } catch {}
112
- });
113
- },
114
- cancel() {
115
- closed = true;
116
- stream.destroy();
117
- }
118
- });
119
- }
120
- return null;
121
- }
122
- get _stream() {
123
- return this[INTERNALS].stream;
124
- }
125
- /** Return the raw body buffer without consuming the stream (used by Request._send). */
126
- get _rawBodyBuffer() {
127
- const b = this[INTERNALS].body;
128
- if (b === null) return null;
129
- if (Buffer.isBuffer(b)) return b;
130
- if (b instanceof Uint8Array) return Buffer.from(b.buffer, b.byteOffset, b.byteLength);
131
- return null;
132
- }
133
- get bodyUsed() {
134
- return this[INTERNALS].disturbed;
135
- }
136
- /**
137
- * Decode response as ArrayBuffer
138
- */
139
- async arrayBuffer() {
140
- const { buffer, byteOffset, byteLength } = await consumeBody(this);
141
- return buffer.slice(byteOffset, byteOffset + byteLength);
142
- }
143
- async formData() {
144
- const ct = this.headers?.get("content-type");
145
- if (ct?.startsWith("application/x-www-form-urlencoded")) {
146
- const formData = new FormData();
147
- const parameters = new URLSearchParams(await this.text());
148
- for (const [name, value] of parameters) {
149
- formData.append(name, value);
150
- }
151
- return formData;
152
- }
153
- const { toFormData } = await import("./utils/multipart-parser.js");
154
- return toFormData(this.body, ct);
155
- }
156
- /**
157
- * Return raw response as Blob
158
- */
159
- async blob() {
160
- const ct = this.headers?.get("content-type") || this[INTERNALS].body && this[INTERNALS].body.type || "";
161
- const buf = await this.arrayBuffer();
162
- return new Blob([buf], { type: ct });
163
- }
164
- /**
165
- * Decode response as json
166
- */
167
- async json() {
168
- const text = await this.text();
169
- return JSON.parse(text);
170
- }
171
- /**
172
- * Decode response as text
173
- */
174
- async text() {
175
- const buffer = await consumeBody(this);
176
- return new TextDecoder().decode(buffer);
177
- }
178
- };
179
- Object.defineProperties(Body.prototype, {
180
- body: { enumerable: true },
181
- bodyUsed: { enumerable: true },
182
- arrayBuffer: { enumerable: true },
183
- blob: { enumerable: true },
184
- json: { enumerable: true },
185
- text: { enumerable: true }
186
- });
187
- /**
188
- * Consume and convert an entire Body to a Buffer.
189
- */
190
- async function consumeBody(data) {
191
- if (data[INTERNALS].disturbed) {
192
- throw new TypeError(`body used already for: ${data.url}`);
193
- }
194
- data[INTERNALS].disturbed = true;
195
- if (data[INTERNALS].error) {
196
- throw data[INTERNALS].error;
197
- }
198
- const { _stream: body } = data;
199
- if (body === null) {
200
- return Buffer.alloc(0);
201
- }
202
- if (!(body instanceof Stream$1)) {
203
- return Buffer.alloc(0);
204
- }
205
- const accum = [];
206
- let accumBytes = 0;
207
- try {
208
- for await (const chunk of body) {
209
- if (data.size > 0 && accumBytes + chunk.length > data.size) {
210
- const error = new FetchError(`content size at ${data.url} over limit: ${data.size}`, "max-size");
211
- body.destroy(error);
212
- throw error;
213
- }
214
- accumBytes += chunk.length;
215
- accum.push(chunk);
216
- }
217
- } catch (error) {
218
- const err = error instanceof Error ? error : new Error(String(error));
219
- const error_ = error instanceof FetchBaseError ? error : new FetchError(`Invalid response body while trying to fetch ${data.url}: ${err.message}`, "system", err);
220
- throw error_;
221
- }
222
- try {
223
- if (accum.every((c) => typeof c === "string")) {
224
- return Buffer.from(accum.join(""));
225
- }
226
- return Buffer.concat(accum, accumBytes);
227
- } catch (error) {
228
- const err = error instanceof Error ? error : new Error(String(error));
229
- throw new FetchError(`Could not create Buffer from response body for ${data.url}: ${err.message}`, "system", err);
230
- }
231
- }
232
- /**
233
- * Clone body given Res/Req instance
234
- */
235
- const clone = (instance, highWaterMark) => {
236
- let p1;
237
- let p2;
238
- let { body } = instance[INTERNALS];
239
- if (instance.bodyUsed) {
240
- throw new Error("cannot clone body after it is used");
241
- }
242
- if (body instanceof Stream$1 && typeof body.getBoundary !== "function") {
243
- p1 = new PassThrough({ highWaterMark });
244
- p2 = new PassThrough({ highWaterMark });
245
- body.pipe(p1);
246
- body.pipe(p2);
247
- instance[INTERNALS].stream = p1;
248
- body = p2;
249
- }
250
- return body;
251
- };
252
- /**
253
- * Extract a Content-Type value from a body.
254
- */
255
- const extractContentType = (body, request) => {
256
- if (body === null) {
257
- return null;
258
- }
259
- if (typeof body === "string") {
260
- return "text/plain;charset=UTF-8";
261
- }
262
- if (isURLSearchParameters(body)) {
263
- return "application/x-www-form-urlencoded;charset=UTF-8";
264
- }
265
- if (isBlob(body)) {
266
- return body.type || null;
267
- }
268
- if (Buffer.isBuffer(body) || isAnyArrayBuffer(body) || ArrayBuffer.isView(body)) {
269
- return null;
270
- }
271
- if (body instanceof FormData) {
272
- return `multipart/form-data; boundary=${request[INTERNALS].boundary}`;
273
- }
274
- if (body instanceof Stream$1) {
275
- return null;
276
- }
277
- return "text/plain;charset=UTF-8";
278
- };
279
- /**
280
- * Get total bytes of a body.
281
- */
282
- const getTotalBytes = (request) => {
283
- const { body } = request[INTERNALS];
284
- if (body === null) {
285
- return 0;
286
- }
287
- if (isBlob(body)) {
288
- return body.size;
289
- }
290
- if (Buffer.isBuffer(body)) {
291
- return body.length;
292
- }
293
- if (body && typeof body.getLengthSync === "function") {
294
- const streamBody = body;
295
- return streamBody.hasKnownLength && streamBody.hasKnownLength() ? streamBody.getLengthSync() : null;
296
- }
297
- return null;
298
- };
299
- /**
300
- * Write a Body to a Node.js WritableStream.
301
- */
302
- const writeToStream = async (dest, { body }) => {
303
- if (body === null) {
304
- dest.end();
305
- } else {
306
- await pipeline$1(body, dest);
307
- }
308
- };
309
- /**
310
- * Convert a Web ReadableStream to a Node.js Readable.
311
- */
312
- function readableStreamToReadable(webStream) {
313
- const reader = webStream.getReader();
314
- return new Readable({
315
- async read() {
316
- try {
317
- const { done, value } = await reader.read();
318
- if (done) {
319
- this.push(null);
320
- } else {
321
- this.push(Buffer.from(value));
322
- }
323
- } catch (err) {
324
- this.destroy(err);
325
- }
326
- },
327
- destroy(_err, callback) {
328
- reader.cancel().then(() => callback(null), callback);
329
- }
330
- });
331
- }
332
- /**
333
- * Convert a Blob to an async iterable for Readable.from().
334
- */
335
- async function* blobToAsyncIterable(blob) {
336
- if (typeof blob.stream === "function") {
337
- const reader = blob.stream().getReader();
338
- while (true) {
339
- const { done, value } = await reader.read();
340
- if (done) break;
341
- yield value;
342
- }
343
- } else {
344
- yield new Uint8Array(await blob.arrayBuffer());
345
- }
346
- }
347
-
348
- //#endregion
349
- export { clone, Body as default, extractContentType, getTotalBytes, writeToStream };
1
+ import{Blob as e}from"./utils/blob-from.js";import{FetchBaseError as t}from"./errors/base.js";import{FetchError as n}from"./errors/fetch-error.js";import{isBlob as r,isURLSearchParameters as i}from"./utils/is.js";import{URLSearchParams as a}from"@gjsify/url";import{Buffer as o}from"node:buffer";import{PassThrough as s,Readable as c,Stream as l,pipeline as u}from"node:stream";import{FormData as d,formDataToBlob as f}from"@gjsify/formdata";const p=(e,t)=>new Promise((n,r)=>{u(e,t,e=>{e?r(e):n()})}),m=Symbol(`Body internals`);function h(e){return e instanceof ArrayBuffer||typeof SharedArrayBuffer<`u`&&e instanceof SharedArrayBuffer}var g=class{[m]={body:null,stream:null,boundary:``,disturbed:!1,error:null};size=0;constructor(e,s={size:0}){if(this.size=s.size||0,e==null)this[m].body=null;else if(i(e))this[m].body=o.from(e.toString());else if(r(e))this[m].body=e;else if(o.isBuffer(e))this[m].body=e;else if(h(e))this[m].body=o.from(e);else if(ArrayBuffer.isView(e))this[m].body=o.from(e.buffer,e.byteOffset,e.byteLength);else if(e instanceof c)this[m].body=e;else if(typeof ReadableStream<`u`&&e instanceof ReadableStream)this[m].body=S(e);else if(e instanceof d){let t=f(e);this[m].body=t,this[m].boundary=t.type?.split(`boundary=`)?.[1]??``}else typeof e==`string`?this[m].body=o.from(e):e instanceof a?this[m].body=o.from(e.toString()):(console.warn(`Unknown body type "${typeof e}", try to parse the body to string!`),this[m].body=o.from(String(e)));let u=this[m].body;o.isBuffer(u)?this[m].stream=c.from(u):r(u)?this[m].stream=c.from(C(u)):u instanceof c&&(this[m].stream=u),u instanceof l&&u.on(`error`,e=>{let r=e instanceof t?e:new n(`Invalid response body while trying to fetch ${this.url}: ${e.message}`,`system`,e);this[m].error=r})}get body(){let e=this[m].stream;if(!e)return null;if(typeof ReadableStream<`u`){let t=!1;return new ReadableStream({start(n){e.on(`data`,e=>{if(!t)try{n.enqueue(e instanceof Uint8Array?e:new Uint8Array(e))}catch{}}),e.on(`end`,()=>{if(!t){t=!0;try{n.close()}catch{}}}),e.on(`error`,e=>{if(!t){t=!0;try{n.error(e)}catch{}}})},cancel(){t=!0,e.destroy()}})}return null}get _stream(){return this[m].stream}get _rawBodyBuffer(){let e=this[m].body;return e===null?null:o.isBuffer(e)?e:e instanceof Uint8Array?o.from(e.buffer,e.byteOffset,e.byteLength):null}get bodyUsed(){return this[m].disturbed}async arrayBuffer(){let{buffer:e,byteOffset:t,byteLength:n}=await _(this);return e.slice(t,t+n)}async formData(){let e=this.headers?.get(`content-type`);if(e?.startsWith(`application/x-www-form-urlencoded`)){let e=new d,t=new a(await this.text());for(let[n,r]of t)e.append(n,r);return e}let{toFormData:t}=await import(`./utils/multipart-parser.js`);return t(this.body,e)}async blob(){let t=this.headers?.get(`content-type`)||this[m].body&&this[m].body.type||``;return new e([await this.arrayBuffer()],{type:t})}async json(){let e=await this.text();return JSON.parse(e)}async text(){let e=await _(this);return new TextDecoder().decode(e)}};Object.defineProperties(g.prototype,{body:{enumerable:!0},bodyUsed:{enumerable:!0},arrayBuffer:{enumerable:!0},blob:{enumerable:!0},json:{enumerable:!0},text:{enumerable:!0}});async function _(e){if(e[m].disturbed)throw TypeError(`body used already for: ${e.url}`);if(e[m].disturbed=!0,e[m].error)throw e[m].error;let{_stream:r}=e;if(r===null||!(r instanceof l))return o.alloc(0);let i=[],a=0;try{for await(let t of r){if(e.size>0&&a+t.length>e.size){let t=new n(`content size at ${e.url} over limit: ${e.size}`,`max-size`);throw r.destroy(t),t}a+=t.length,i.push(t)}}catch(r){let i=r instanceof Error?r:Error(String(r));throw r instanceof t?r:new n(`Invalid response body while trying to fetch ${e.url}: ${i.message}`,`system`,i)}try{return i.every(e=>typeof e==`string`)?o.from(i.join(``)):o.concat(i,a)}catch(t){let r=t instanceof Error?t:Error(String(t));throw new n(`Could not create Buffer from response body for ${e.url}: ${r.message}`,`system`,r)}}const v=(e,t)=>{let n,r,{body:i}=e[m];if(e.bodyUsed)throw Error(`cannot clone body after it is used`);return i instanceof l&&typeof i.getBoundary!=`function`&&(n=new s({highWaterMark:t}),r=new s({highWaterMark:t}),i.pipe(n),i.pipe(r),e[m].stream=n,i=r),i},y=(e,t)=>e===null?null:typeof e==`string`?`text/plain;charset=UTF-8`:i(e)?`application/x-www-form-urlencoded;charset=UTF-8`:r(e)?e.type||null:o.isBuffer(e)||h(e)||ArrayBuffer.isView(e)?null:e instanceof d?`multipart/form-data; boundary=${t[m].boundary}`:e instanceof l?null:`text/plain;charset=UTF-8`,b=e=>{let{body:t}=e[m];if(t===null)return 0;if(r(t))return t.size;if(o.isBuffer(t))return t.length;if(t&&typeof t.getLengthSync==`function`){let e=t;return e.hasKnownLength&&e.hasKnownLength()?e.getLengthSync():null}return null},x=async(e,{body:t})=>{t===null?e.end():await p(t,e)};function S(e){let t=e.getReader();return new c({async read(){try{let{done:e,value:n}=await t.read();e?this.push(null):this.push(o.from(n))}catch(e){this.destroy(e)}},destroy(e,n){t.cancel().then(()=>n(null),n)}})}async function*C(e){if(typeof e.stream==`function`){let t=e.stream().getReader();for(;;){let{done:e,value:n}=await t.read();if(e)break;yield n}}else yield new Uint8Array(await e.arrayBuffer())}export{v as clone,g as default,y as extractContentType,b as getTotalBytes,x as writeToStream};
@@ -1,14 +1 @@
1
- import { FetchBaseError } from "./base.js";
2
-
3
- //#region src/errors/abort-error.ts
4
- /**
5
- * AbortError interface for cancelled requests
6
- */
7
- var AbortError = class extends FetchBaseError {
8
- constructor(message, type = "aborted") {
9
- super(message, type);
10
- }
11
- };
12
-
13
- //#endregion
14
- export { AbortError };
1
+ import{FetchBaseError as e}from"./base.js";var t=class extends e{constructor(e,t=`aborted`){super(e,t)}};export{t as AbortError};
@@ -1,20 +1 @@
1
- //#region src/errors/base.ts
2
- var FetchBaseError = class extends Error {
3
- type;
4
- constructor(message, type) {
5
- super(message);
6
- if (typeof Error.captureStackTrace === "function") {
7
- Error.captureStackTrace(this, this.constructor);
8
- }
9
- this.type = type;
10
- }
11
- get name() {
12
- return this.constructor.name;
13
- }
14
- get [Symbol.toStringTag]() {
15
- return this.constructor.name;
16
- }
17
- };
18
-
19
- //#endregion
20
- export { FetchBaseError };
1
+ var e=class extends Error{type;constructor(e,t){super(e),typeof Error.captureStackTrace==`function`&&Error.captureStackTrace(this,this.constructor),this.type=t}get name(){return this.constructor.name}get[Symbol.toStringTag](){return this.constructor.name}};export{e as FetchBaseError};
@@ -1,26 +1 @@
1
- import { FetchBaseError } from "./base.js";
2
-
3
- //#region src/errors/fetch-error.ts
4
- /**
5
- * FetchError interface for operational errors
6
- */
7
- var FetchError = class extends FetchBaseError {
8
- code;
9
- errno;
10
- erroredSysCall;
11
- /**
12
- * @param message Error message for human
13
- * @param type Error type for machine
14
- * @param systemError For Node.js system error
15
- */
16
- constructor(message, type, systemError) {
17
- super(message, type);
18
- if (systemError) {
19
- this.code = this.errno = systemError.code;
20
- this.erroredSysCall = systemError.syscall;
21
- }
22
- }
23
- };
24
-
25
- //#endregion
26
- export { FetchError };
1
+ import{FetchBaseError as e}from"./base.js";var t=class extends e{code;errno;erroredSysCall;constructor(e,t,n){super(e,t),n&&(this.code=this.errno=n.code,this.erroredSysCall=n.syscall)}};export{t as FetchError};
@@ -1,193 +1 @@
1
- import Soup from "@girs/soup-3.0";
2
- import { validateHeaderName, validateHeaderValue } from "@gjsify/http/validators";
3
-
4
- //#region src/headers.ts
5
- const _headers = Symbol("Headers.headers");
6
- function isBoxedPrimitive(val) {
7
- return val instanceof String || val instanceof Number || val instanceof Boolean || typeof Symbol !== "undefined" && val instanceof Symbol || typeof BigInt !== "undefined" && val instanceof BigInt;
8
- }
9
- var Headers = class Headers {
10
- [_headers];
11
- constructor(init) {
12
- this[_headers] = new Map();
13
- if (init == null) {
14
- return;
15
- }
16
- if (init instanceof Headers) {
17
- for (const [name, values] of init[_headers]) {
18
- this[_headers].set(name, [...values]);
19
- }
20
- return;
21
- }
22
- if (typeof init === "object" && !isBoxedPrimitive(init)) {
23
- const method = init[Symbol.iterator];
24
- if (method == null) {
25
- for (const [name, value] of Object.entries(init)) {
26
- validateHeaderName(name);
27
- validateHeaderValue(name, String(value));
28
- this.append(name, String(value));
29
- }
30
- } else {
31
- if (typeof method !== "function") {
32
- throw new TypeError("Header pairs must be iterable");
33
- }
34
- for (const pair of init) {
35
- if (typeof pair !== "object" || isBoxedPrimitive(pair)) {
36
- throw new TypeError("Each header pair must be an iterable object");
37
- }
38
- const arr = [...pair];
39
- if (arr.length !== 2) {
40
- throw new TypeError("Each header pair must be a name/value tuple");
41
- }
42
- validateHeaderName(arr[0]);
43
- validateHeaderValue(arr[0], String(arr[1]));
44
- this.append(arr[0], String(arr[1]));
45
- }
46
- }
47
- } else {
48
- throw new TypeError("Failed to construct 'Headers': The provided value is not of type " + "'(sequence<sequence<ByteString>> or record<ByteString, ByteString>)'");
49
- }
50
- }
51
- append(name, value) {
52
- validateHeaderName(name);
53
- validateHeaderValue(name, value);
54
- const lowerName = String(name).toLowerCase();
55
- const strValue = String(value);
56
- const existing = this[_headers].get(lowerName);
57
- if (existing) {
58
- existing.push(strValue);
59
- } else {
60
- this[_headers].set(lowerName, [strValue]);
61
- }
62
- }
63
- set(name, value) {
64
- validateHeaderName(name);
65
- validateHeaderValue(name, value);
66
- const lowerName = String(name).toLowerCase();
67
- this[_headers].set(lowerName, [String(value)]);
68
- }
69
- delete(name) {
70
- this[_headers].delete(String(name).toLowerCase());
71
- }
72
- has(name) {
73
- return this[_headers].has(String(name).toLowerCase());
74
- }
75
- get(name) {
76
- const values = this[_headers].get(String(name).toLowerCase());
77
- if (!values || values.length === 0) {
78
- return null;
79
- }
80
- let value = values.join(", ");
81
- if (/^content-encoding$/i.test(name)) {
82
- value = value.toLowerCase();
83
- }
84
- return value;
85
- }
86
- getAll(name) {
87
- return this[_headers].get(String(name).toLowerCase()) ?? [];
88
- }
89
- getSetCookie() {
90
- return this[_headers].get("set-cookie") ?? [];
91
- }
92
- forEach(callback, thisArg) {
93
- for (const name of this.keys()) {
94
- Reflect.apply(callback, thisArg, [
95
- this.get(name),
96
- name,
97
- this
98
- ]);
99
- }
100
- }
101
- *keys() {
102
- const sorted = [...this[_headers].keys()].sort();
103
- const seen = new Set();
104
- for (const key of sorted) {
105
- if (!seen.has(key)) {
106
- seen.add(key);
107
- yield key;
108
- }
109
- }
110
- }
111
- *values() {
112
- for (const name of this.keys()) {
113
- yield this.get(name);
114
- }
115
- }
116
- *entries() {
117
- for (const name of this.keys()) {
118
- yield [name, this.get(name)];
119
- }
120
- }
121
- [Symbol.iterator]() {
122
- return this.entries();
123
- }
124
- get [Symbol.toStringTag]() {
125
- return "Headers";
126
- }
127
- toString() {
128
- return Object.prototype.toString.call(this);
129
- }
130
- /**
131
- * Node-fetch non-spec method: return all headers and their values as arrays.
132
- */
133
- raw() {
134
- const result = {};
135
- for (const name of this.keys()) {
136
- result[name] = this.getAll(name);
137
- }
138
- return result;
139
- }
140
- /**
141
- * Append all headers to a Soup.Message for sending.
142
- */
143
- _appendToSoupMessage(message, type = Soup.MessageHeadersType.REQUEST) {
144
- const soupHeaders = message ? message.get_request_headers() : new Soup.MessageHeaders(type);
145
- for (const [name, value] of this.entries()) {
146
- soupHeaders.append(name, value);
147
- }
148
- return soupHeaders;
149
- }
150
- /**
151
- * Create a Headers instance from a Soup.Message's headers.
152
- */
153
- static _newFromSoupMessage(message, type = Soup.MessageHeadersType.RESPONSE) {
154
- const headers = new Headers();
155
- let soupHeaders;
156
- if (type === Soup.MessageHeadersType.RESPONSE) {
157
- soupHeaders = message.get_response_headers();
158
- } else {
159
- soupHeaders = message.get_request_headers();
160
- }
161
- soupHeaders.foreach((name, value) => {
162
- headers.append(name, value);
163
- });
164
- return headers;
165
- }
166
- /**
167
- * For better console.log(headers)
168
- */
169
- [Symbol.for("nodejs.util.inspect.custom")]() {
170
- const result = {};
171
- for (const key of this.keys()) {
172
- const values = this.getAll(key);
173
- if (key === "host") {
174
- result[key] = values[0];
175
- } else {
176
- result[key] = values.length > 1 ? values : values[0];
177
- }
178
- }
179
- return result;
180
- }
181
- };
182
- Object.defineProperties(Headers.prototype, [
183
- "get",
184
- "entries",
185
- "forEach",
186
- "values"
187
- ].reduce((result, property) => {
188
- result[property] = { enumerable: true };
189
- return result;
190
- }, {}));
191
-
192
- //#endregion
193
- export { Headers as default };
1
+ import e from"@girs/soup-3.0";import{validateHeaderName as t,validateHeaderValue as n}from"@gjsify/http/validators";const r=Symbol(`Headers.headers`);function i(e){return e instanceof String||e instanceof Number||e instanceof Boolean||typeof Symbol<`u`&&e instanceof Symbol||typeof BigInt<`u`&&e instanceof BigInt}var a=class a{[r];constructor(e){if(this[r]=new Map,e!=null){if(e instanceof a){for(let[t,n]of e[r])this[r].set(t,[...n]);return}if(typeof e==`object`&&!i(e)){let r=e[Symbol.iterator];if(r==null)for(let[r,i]of Object.entries(e))t(r),n(r,String(i)),this.append(r,String(i));else{if(typeof r!=`function`)throw TypeError(`Header pairs must be iterable`);for(let r of e){if(typeof r!=`object`||i(r))throw TypeError(`Each header pair must be an iterable object`);let e=[...r];if(e.length!==2)throw TypeError(`Each header pair must be a name/value tuple`);t(e[0]),n(e[0],String(e[1])),this.append(e[0],String(e[1]))}}}else throw TypeError(`Failed to construct 'Headers': The provided value is not of type '(sequence<sequence<ByteString>> or record<ByteString, ByteString>)'`)}}append(e,i){t(e),n(e,i);let a=String(e).toLowerCase(),o=String(i),s=this[r].get(a);s?s.push(o):this[r].set(a,[o])}set(e,i){t(e),n(e,i);let a=String(e).toLowerCase();this[r].set(a,[String(i)])}delete(e){this[r].delete(String(e).toLowerCase())}has(e){return this[r].has(String(e).toLowerCase())}get(e){let t=this[r].get(String(e).toLowerCase());if(!t||t.length===0)return null;let n=t.join(`, `);return/^content-encoding$/i.test(e)&&(n=n.toLowerCase()),n}getAll(e){return this[r].get(String(e).toLowerCase())??[]}getSetCookie(){return this[r].get(`set-cookie`)??[]}forEach(e,t){for(let n of this.keys())Reflect.apply(e,t,[this.get(n),n,this])}*keys(){let e=[...this[r].keys()].sort(),t=new Set;for(let n of e)t.has(n)||(t.add(n),yield n)}*values(){for(let e of this.keys())yield this.get(e)}*entries(){for(let e of this.keys())yield[e,this.get(e)]}[Symbol.iterator](){return this.entries()}get[Symbol.toStringTag](){return`Headers`}toString(){return Object.prototype.toString.call(this)}raw(){let e={};for(let t of this.keys())e[t]=this.getAll(t);return e}_appendToSoupMessage(t,n=e.MessageHeadersType.REQUEST){let r=t?t.get_request_headers():new e.MessageHeaders(n);for(let[e,t]of this.entries())r.append(e,t);return r}static _newFromSoupMessage(t,n=e.MessageHeadersType.RESPONSE){let r=new a,i;return i=n===e.MessageHeadersType.RESPONSE?t.get_response_headers():t.get_request_headers(),i.foreach((e,t)=>{r.append(e,t)}),r}[Symbol.for(`nodejs.util.inspect.custom`)](){let e={};for(let t of this.keys()){let n=this.getAll(t);t===`host`?e[t]=n[0]:e[t]=n.length>1?n:n[0]}return e}};Object.defineProperties(a.prototype,[`get`,`entries`,`forEach`,`values`].reduce((e,t)=>(e[t]={enumerable:!0},e),{}));export{a as default};