@passcod/faith 0.0.2 → 0.0.5
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 +319 -78
- package/index.d.ts +568 -32
- package/index.js +57 -52
- package/package.json +17 -14
- package/wrapper.d.ts +356 -95
- package/wrapper.js +298 -275
- package/wrapper.mjs +32 -0
package/wrapper.js
CHANGED
|
@@ -13,137 +13,149 @@ const { faithFetch } = native;
|
|
|
13
13
|
// Generate ERROR_CODES const enum from native error codes
|
|
14
14
|
// e.g. { InvalidHeader: "InvalidHeader", InvalidMethod: "InvalidMethod", ... }
|
|
15
15
|
const ERROR_CODES = native.errorCodes().reduce((acc, code) => {
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
acc[code] = code;
|
|
17
|
+
return acc;
|
|
18
18
|
}, {});
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
21
|
* Response class that provides spec-compliant Fetch API
|
|
22
22
|
*/
|
|
23
23
|
class Response {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
24
|
+
/** @type {import('./index').FaithResponse} */
|
|
25
|
+
#nativeResponse;
|
|
26
|
+
|
|
27
|
+
constructor(nativeResponse) {
|
|
28
|
+
this.#nativeResponse = nativeResponse;
|
|
29
|
+
|
|
30
|
+
const nativeProto = Object.getPrototypeOf(this.#nativeResponse);
|
|
31
|
+
const descriptors = Object.getOwnPropertyDescriptors(nativeProto);
|
|
32
|
+
|
|
33
|
+
for (const [key, descriptor] of Object.entries(descriptors)) {
|
|
34
|
+
if (descriptor.get) {
|
|
35
|
+
Object.defineProperty(this, key, {
|
|
36
|
+
get: () => this.#nativeResponse[key],
|
|
37
|
+
enumerable: true,
|
|
38
|
+
configurable: true,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
get headers() {
|
|
45
|
+
const headers = new Headers();
|
|
46
|
+
const headerPairs = this.#nativeResponse.headers();
|
|
47
|
+
if (Array.isArray(headerPairs)) {
|
|
48
|
+
for (const [name, value] of headerPairs) {
|
|
49
|
+
headers.append(name, value);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return headers;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
get trailers() {
|
|
56
|
+
return (async () => {
|
|
57
|
+
const headerPairs = await this.#nativeResponse.trailers();
|
|
58
|
+
if (!Array.isArray(headerPairs)) {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const headers = new Headers();
|
|
63
|
+
for (const [name, value] of headerPairs) {
|
|
64
|
+
headers.append(name, value);
|
|
65
|
+
}
|
|
66
|
+
return headers;
|
|
67
|
+
})();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
get body() {
|
|
71
|
+
return this.#nativeResponse.body();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Convert response body to text (UTF-8)
|
|
76
|
+
* @returns {Promise<string>}
|
|
77
|
+
*/
|
|
78
|
+
async text() {
|
|
79
|
+
return await this.#nativeResponse.text();
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Get response body as bytes
|
|
84
|
+
* @returns {Promise<Uint8Array>}
|
|
85
|
+
*/
|
|
86
|
+
async bytes() {
|
|
87
|
+
return await this.#nativeResponse.bytes();
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Alias for bytes() that returns ArrayBuffer
|
|
92
|
+
* @returns {Promise<ArrayBuffer>}
|
|
93
|
+
*/
|
|
94
|
+
async arrayBuffer() {
|
|
95
|
+
const buffer = await this.#nativeResponse.bytes();
|
|
96
|
+
return buffer.buffer;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Parse response body as JSON
|
|
101
|
+
* @returns {Promise<any>}
|
|
102
|
+
*/
|
|
103
|
+
async json() {
|
|
104
|
+
return await this.#nativeResponse.json();
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Get response body as Blob
|
|
109
|
+
* @returns {Promise<Blob>}
|
|
110
|
+
*/
|
|
111
|
+
async blob() {
|
|
112
|
+
const bytes = await this.#nativeResponse.bytes();
|
|
113
|
+
const contentType = this.headers.get("content-type") || "";
|
|
114
|
+
return new Blob([bytes], { type: contentType });
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/** Not supported. Will throw. */
|
|
118
|
+
async formData() {
|
|
119
|
+
throw new Error("not supported");
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Create a clone of the Response object
|
|
124
|
+
* @returns {Response} A new Response object with the same properties
|
|
125
|
+
* @throws {Error} If response body has already been read
|
|
126
|
+
*/
|
|
127
|
+
clone() {
|
|
128
|
+
return new Response(this.#nativeResponse.clone());
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Convert to a Web API Response object
|
|
133
|
+
* @returns {Response} Web API Response object
|
|
134
|
+
* @throws {Error} If response body has been disturbed or Response constructor is not available
|
|
135
|
+
*/
|
|
136
|
+
webResponse() {
|
|
137
|
+
// Check if Web API Response constructor is available
|
|
138
|
+
if (typeof globalThis.Response !== "function") {
|
|
139
|
+
throw new Error(
|
|
140
|
+
"Web API Response constructor not available in this environment",
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Create and return a Web API Response object
|
|
145
|
+
return new globalThis.Response(this.body, {
|
|
146
|
+
status: this.status,
|
|
147
|
+
statusText: this.statusText,
|
|
148
|
+
headers: this.headers,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
131
151
|
}
|
|
132
152
|
|
|
133
153
|
let defaultAgent;
|
|
134
154
|
|
|
135
155
|
/**
|
|
136
156
|
* Fetch function wrapper
|
|
137
|
-
* @param {string|Request|URL|
|
|
138
|
-
* @param {
|
|
139
|
-
* @param {string} [options.method] - HTTP method
|
|
140
|
-
* @param {Object|Headers} [options.headers] - HTTP headers (Headers object or plain object with {name: value} pairs).
|
|
141
|
-
* Converted to array of tuples for the native binding.
|
|
142
|
-
* @param {Buffer|Array<number>|string|ArrayBuffer|Uint8Array|ReadableStream} [options.body] - Request body
|
|
143
|
-
* @param {number} [options.timeout] - Timeout in milliseconds
|
|
144
|
-
* @param {string} [options.credentials] - Credentials mode: "omit", "same-origin", or "include" (default)
|
|
145
|
-
* @param {string} [options.duplex] - Duplex mode: "half" (required when body is a ReadableStream)
|
|
146
|
-
* @param {AbortSignal} [options.signal] - AbortSignal to cancel the request
|
|
157
|
+
* @param {string|Request|URL|{ toString(): string }} resource - The URL to fetch, a Request object, or an object with stringifier
|
|
158
|
+
* @param {FetchOptions|Request} [options] - Fetch options (when resource is a Request, options override Request properties)
|
|
147
159
|
* @returns {Promise<Response>}
|
|
148
160
|
*
|
|
149
161
|
* When a Request object is provided, all its properties (method, headers, body, mode, credentials,
|
|
@@ -158,163 +170,174 @@ let defaultAgent;
|
|
|
158
170
|
* - null/undefined: treated as no headers
|
|
159
171
|
* - Invalid types: throws TypeError
|
|
160
172
|
*/
|
|
161
|
-
async function fetch(
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
173
|
+
async function fetch(resource, options = {}) {
|
|
174
|
+
let url;
|
|
175
|
+
let nativeOptions;
|
|
176
|
+
|
|
177
|
+
// Handle Request object as resource
|
|
178
|
+
if (
|
|
179
|
+
typeof resource === "object" &&
|
|
180
|
+
resource !== null &&
|
|
181
|
+
typeof resource.url === "string"
|
|
182
|
+
) {
|
|
183
|
+
// Extract url separately
|
|
184
|
+
url = resource.url;
|
|
185
|
+
|
|
186
|
+
// Copy all properties from Request object except url and bodyUsed
|
|
187
|
+
const requestOptions = {};
|
|
188
|
+
for (const key in resource) {
|
|
189
|
+
if (key !== "url" && key !== "bodyUsed") {
|
|
190
|
+
const value = resource[key];
|
|
191
|
+
if (value !== undefined && value !== null) {
|
|
192
|
+
requestOptions[key] = value;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Handle body specially - Request.body is a ReadableStream that needs to be consumed
|
|
198
|
+
if (requestOptions.body !== undefined && requestOptions.body !== null) {
|
|
199
|
+
if (typeof resource.arrayBuffer === "function") {
|
|
200
|
+
requestOptions.body = await resource.arrayBuffer();
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// Merge Request properties with options, options take precedence
|
|
205
|
+
nativeOptions = { ...requestOptions, ...options };
|
|
206
|
+
} else if (typeof resource === "string") {
|
|
207
|
+
url = resource;
|
|
208
|
+
nativeOptions = { ...options };
|
|
209
|
+
} else if (resource && typeof resource.toString === "function") {
|
|
210
|
+
// Handle objects with stringifier (like URL objects)
|
|
211
|
+
url = resource.toString();
|
|
212
|
+
nativeOptions = { ...options };
|
|
213
|
+
} else {
|
|
214
|
+
throw new TypeError(
|
|
215
|
+
"First argument must be a string URL, Request object, or an object with a stringifier",
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Convert headers to native format
|
|
220
|
+
// This is the inverse of what Response does: Request headers go from
|
|
221
|
+
// Headers/Object -> Array<[string, string]>, while Response headers go from
|
|
222
|
+
// Array<[string, string]> -> Headers object
|
|
223
|
+
if (nativeOptions.headers !== undefined && nativeOptions.headers !== null) {
|
|
224
|
+
if (nativeOptions.headers instanceof Headers) {
|
|
225
|
+
// Convert Headers object to array of tuples
|
|
226
|
+
const headersArray = [];
|
|
227
|
+
nativeOptions.headers.forEach((value, name) => {
|
|
228
|
+
headersArray.push([name, value]);
|
|
229
|
+
});
|
|
230
|
+
nativeOptions.headers = headersArray;
|
|
231
|
+
} else if (
|
|
232
|
+
typeof nativeOptions.headers === "object" &&
|
|
233
|
+
!Array.isArray(nativeOptions.headers)
|
|
234
|
+
) {
|
|
235
|
+
// Convert plain object to array of tuples
|
|
236
|
+
const headersArray = [];
|
|
237
|
+
for (const [name, value] of Object.entries(nativeOptions.headers)) {
|
|
238
|
+
headersArray.push([name, value]);
|
|
239
|
+
}
|
|
240
|
+
nativeOptions.headers = headersArray;
|
|
241
|
+
} else {
|
|
242
|
+
throw new TypeError(
|
|
243
|
+
"headers must be a Headers object or a plain object",
|
|
244
|
+
);
|
|
245
|
+
}
|
|
246
|
+
} else if (nativeOptions.headers === null) {
|
|
247
|
+
// Convert null to undefined so Rust treats it as None
|
|
248
|
+
delete nativeOptions.headers;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// Convert body to Buffer if needed
|
|
252
|
+
// Native binding handles: string, Buffer, Uint8Array
|
|
253
|
+
// We convert: ArrayBuffer, Array<number>, ReadableStream
|
|
254
|
+
// Validate ReadableStream bodies require duplex option
|
|
255
|
+
if (nativeOptions.body !== undefined && nativeOptions.body !== null) {
|
|
256
|
+
// Check if body is a ReadableStream
|
|
257
|
+
if (
|
|
258
|
+
typeof nativeOptions.body === "object" &&
|
|
259
|
+
typeof nativeOptions.body.getReader === "function"
|
|
260
|
+
) {
|
|
261
|
+
// ReadableStream body requires duplex option
|
|
262
|
+
if (!nativeOptions.duplex) {
|
|
263
|
+
throw new TypeError(
|
|
264
|
+
"RequestInit's body is a ReadableStream and duplex option is not set",
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// Consume the ReadableStream into a Buffer
|
|
269
|
+
const reader = nativeOptions.body.getReader();
|
|
270
|
+
const chunks = [];
|
|
271
|
+
try {
|
|
272
|
+
while (true) {
|
|
273
|
+
const { done, value } = await reader.read();
|
|
274
|
+
if (done) break;
|
|
275
|
+
chunks.push(value);
|
|
276
|
+
}
|
|
277
|
+
} finally {
|
|
278
|
+
reader.releaseLock();
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// Concatenate all chunks into a single Buffer
|
|
282
|
+
const totalLength = chunks.reduce(
|
|
283
|
+
(acc, chunk) => acc + chunk.length,
|
|
284
|
+
0,
|
|
285
|
+
);
|
|
286
|
+
const result = new Uint8Array(totalLength);
|
|
287
|
+
let offset = 0;
|
|
288
|
+
for (const chunk of chunks) {
|
|
289
|
+
result.set(chunk, offset);
|
|
290
|
+
offset += chunk.length;
|
|
291
|
+
}
|
|
292
|
+
nativeOptions.body = Buffer.from(result);
|
|
293
|
+
} else if (nativeOptions.body instanceof ArrayBuffer) {
|
|
294
|
+
nativeOptions.body = Buffer.from(nativeOptions.body);
|
|
295
|
+
} else if (Array.isArray(nativeOptions.body)) {
|
|
296
|
+
nativeOptions.body = Buffer.from(nativeOptions.body);
|
|
297
|
+
}
|
|
298
|
+
} else if (nativeOptions.body === null) {
|
|
299
|
+
// Remove null body
|
|
300
|
+
delete nativeOptions.body;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// Attach to the default agent if none is provided
|
|
304
|
+
if (!nativeOptions.agent) {
|
|
305
|
+
if (!defaultAgent) {
|
|
306
|
+
defaultAgent = new native.Agent();
|
|
307
|
+
}
|
|
308
|
+
nativeOptions.agent = defaultAgent;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// Extract signal to pass as separate parameter
|
|
312
|
+
const signal = nativeOptions.signal;
|
|
313
|
+
delete nativeOptions.signal;
|
|
314
|
+
|
|
315
|
+
// Check if signal is already aborted
|
|
316
|
+
if (signal && signal.aborted) {
|
|
317
|
+
const error = new Error(
|
|
318
|
+
"Aborted: the request was aborted before it could start",
|
|
319
|
+
);
|
|
320
|
+
error.name = "AbortError";
|
|
321
|
+
error.code = ERROR_CODES.Aborted;
|
|
322
|
+
throw error;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
const nativeResponse = await faithFetch(url, nativeOptions, signal);
|
|
326
|
+
return new Response(nativeResponse);
|
|
310
327
|
}
|
|
311
328
|
|
|
312
329
|
module.exports = {
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
330
|
+
Agent: native.Agent,
|
|
331
|
+
CacheMode: native.CacheMode,
|
|
332
|
+
CacheStore: native.CacheStore,
|
|
333
|
+
Credentials: native.CredentialsOption,
|
|
334
|
+
Duplex: native.DuplexOption,
|
|
335
|
+
ERROR_CODES,
|
|
336
|
+
FAITH_VERSION: native.FAITH_VERSION,
|
|
337
|
+
fetch,
|
|
338
|
+
Http3Congestion: native.Http3Congestion,
|
|
339
|
+
Redirect: native.Redirect,
|
|
340
|
+
REQWEST_VERSION: native.REQWEST_VERSION,
|
|
341
|
+
Response,
|
|
342
|
+
USER_AGENT: native.USER_AGENT,
|
|
320
343
|
};
|
package/wrapper.mjs
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import faith from "./wrapper.js";
|
|
2
|
+
const {
|
|
3
|
+
Agent,
|
|
4
|
+
CacheMode,
|
|
5
|
+
CacheStore,
|
|
6
|
+
Credentials,
|
|
7
|
+
Duplex,
|
|
8
|
+
ERROR_CODES,
|
|
9
|
+
FAITH_VERSION,
|
|
10
|
+
fetch,
|
|
11
|
+
Http3Congestion,
|
|
12
|
+
Redirect,
|
|
13
|
+
REQWEST_VERSION,
|
|
14
|
+
Response,
|
|
15
|
+
USER_AGENT,
|
|
16
|
+
} = faith;
|
|
17
|
+
|
|
18
|
+
export {
|
|
19
|
+
Agent,
|
|
20
|
+
CacheMode,
|
|
21
|
+
CacheStore,
|
|
22
|
+
Credentials,
|
|
23
|
+
Duplex,
|
|
24
|
+
ERROR_CODES,
|
|
25
|
+
FAITH_VERSION,
|
|
26
|
+
fetch,
|
|
27
|
+
Http3Congestion,
|
|
28
|
+
Redirect,
|
|
29
|
+
REQWEST_VERSION,
|
|
30
|
+
Response,
|
|
31
|
+
USER_AGENT,
|
|
32
|
+
};
|