@passcod/faith 0.0.2
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 +547 -0
- package/index.d.ts +109 -0
- package/index.js +585 -0
- package/package.json +76 -0
- package/wrapper.d.ts +119 -0
- package/wrapper.js +320 -0
package/README.md
ADDED
|
@@ -0,0 +1,547 @@
|
|
|
1
|
+
# fáith - Rust-powered fetch API for Node.js
|
|
2
|
+
|
|
3
|
+
/ˈɸaːθj/ — pronounced FATH, like FATHER without the ER. This is an old irish word with the same
|
|
4
|
+
root as "fetch", meaning _poet_, _soothsayer_, _seer_, and later, _prophet_.
|
|
5
|
+
|
|
6
|
+
Fáith is of course a pun with _faith_, and is meant to be a _faithful_ implementation of the fetch
|
|
7
|
+
API for Node.js, but using a Rust-based network stack instead of undici + libuv.
|
|
8
|
+
|
|
9
|
+
Most `fetch` implementations for Node.js are based on the Node.js TCP stack (via libuv) and cannot
|
|
10
|
+
easily work around its limitations. The native fetch implementation, `undici`, explicitly targets
|
|
11
|
+
HTTP/1.1, and doesn't support HTTP/2+, among many other complaints.
|
|
12
|
+
|
|
13
|
+
Fáith tries to bring a Node.js fetch that is closer to the browser's fetch, notably by having
|
|
14
|
+
transparent support for HTTP/2 and HTTP/3, IPv6 and IPv4 using the "Happy Eyeballs" algorithm, an
|
|
15
|
+
HTTP cache and a cookie jar, a DNS cache, and actual support for `half` and `full` duplex modes.
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install @passcod/faith
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Usage
|
|
24
|
+
|
|
25
|
+
### Basic fetch
|
|
26
|
+
|
|
27
|
+
```javascript
|
|
28
|
+
import { fetch } from '@passcod/faith';
|
|
29
|
+
|
|
30
|
+
async function example() {
|
|
31
|
+
const response = await fetch('https://httpbin.org/get');
|
|
32
|
+
console.log(response.status); // 200
|
|
33
|
+
console.log(response.ok); // true
|
|
34
|
+
|
|
35
|
+
const data = response.json();
|
|
36
|
+
console.log(data.url); // https://httpbin.org/get
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Fetch with options
|
|
41
|
+
|
|
42
|
+
```javascript
|
|
43
|
+
const response = await fetch('https://httpbin.org/post', {
|
|
44
|
+
method: 'POST',
|
|
45
|
+
headers: {
|
|
46
|
+
'Content-Type': 'application/json',
|
|
47
|
+
'X-Custom-Header': 'value'
|
|
48
|
+
},
|
|
49
|
+
body: JSON.stringify({ message: 'Hello' }),
|
|
50
|
+
timeout: 30 // seconds
|
|
51
|
+
});
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
# API Reference
|
|
55
|
+
|
|
56
|
+
Conforms to the [fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API).
|
|
57
|
+
|
|
58
|
+
In the following documentation, italics are parts that are *identical to how native fetch works*
|
|
59
|
+
(as per MDN), and non-italics document where behaviour varies and is specific to fáith (unless
|
|
60
|
+
otherwise specified).
|
|
61
|
+
|
|
62
|
+
## `fetch()`
|
|
63
|
+
|
|
64
|
+
### Syntax
|
|
65
|
+
|
|
66
|
+
```javascript
|
|
67
|
+
import { fetch } from '@passcod/faith';
|
|
68
|
+
fetch(resource);
|
|
69
|
+
fetch(resource, options);
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Parameters
|
|
73
|
+
|
|
74
|
+
#### `resource`
|
|
75
|
+
|
|
76
|
+
*This defines the resource that you wish to fetch. This can either be:*
|
|
77
|
+
|
|
78
|
+
- *A string or any other object with a stringifier — including a `URL` object — that provides the
|
|
79
|
+
URL of the resource you want to fetch.* The URL must be absolute and include a scheme.
|
|
80
|
+
|
|
81
|
+
- *A `Request` object.*
|
|
82
|
+
|
|
83
|
+
#### `options` (Optional)
|
|
84
|
+
|
|
85
|
+
*A `RequestInit` object containing any custom settings that you want to apply to the request.* In
|
|
86
|
+
practice the `RequestInit` class does not exist in browsers or Node.js, and so this is always a
|
|
87
|
+
"plain object" or "dictionary". The fields supported by Fáith are documented below.
|
|
88
|
+
|
|
89
|
+
### Return value
|
|
90
|
+
|
|
91
|
+
*A `Promise` that resolves to a `Response` object.*
|
|
92
|
+
|
|
93
|
+
In `half` duplex mode (the default), the promise resolves when the request body has been fully sent
|
|
94
|
+
and the response headers have been received. In `full` duplex mode (supported by Fáith but not yet
|
|
95
|
+
browsers), the promise resolves as soon as response headers have been received, even if the request
|
|
96
|
+
body has not yet finished sending. Most HTTP servers will not send response headers until they've
|
|
97
|
+
finished receiving the body so this distinction doesn't matter, but some do, and it is possible to
|
|
98
|
+
take advantage of this behaviour with `full` duplex mode for decreased latency in specific cases.
|
|
99
|
+
You may even be able to vary the request body stream based on the response body stream.
|
|
100
|
+
|
|
101
|
+
## `Request`
|
|
102
|
+
|
|
103
|
+
Fáith does not implement its own `Request` object. Instead, you can pass a Web API `Request` object
|
|
104
|
+
to `fetch()`, and it will internally be converted to the right options.
|
|
105
|
+
|
|
106
|
+
## `RequestInit` object
|
|
107
|
+
|
|
108
|
+
*The `RequestInit` dictionary of the Fetch API represents the set of options that can be used to
|
|
109
|
+
configure a fetch request.*
|
|
110
|
+
|
|
111
|
+
*You can pass a `RequestInit` object into the `Request()` constructor, or directly into the
|
|
112
|
+
`fetch()` function call.* Note that Fáith has additional options available, and those will not
|
|
113
|
+
survive a trip through `Request`. Prefer to supply `RequestInit` directly to `fetch()`.
|
|
114
|
+
|
|
115
|
+
*You can also construct a `Request` with a `RequestInit`, and pass the `Request` to a `fetch()`
|
|
116
|
+
call along with another `RequestInit`. If you do this, and the same option is set in both places,
|
|
117
|
+
then the value passed directly into `fetch()` is used.*
|
|
118
|
+
|
|
119
|
+
Note that you can include options that Fáith does not support; they will simply be ignored.
|
|
120
|
+
|
|
121
|
+
### `agent`
|
|
122
|
+
|
|
123
|
+
This is custom to Fáith.
|
|
124
|
+
|
|
125
|
+
You can create an `Agent`, and pass it here to have the request executed by the `Agent`. See the
|
|
126
|
+
documentation for the `Agent` options you can set with this, and the agent data you can access.
|
|
127
|
+
Notably an agent has a DNS cache, and may be configured to handle cookies and/or an HTTP cache.
|
|
128
|
+
|
|
129
|
+
When not provided, a global default `Agent` is created on first use.
|
|
130
|
+
|
|
131
|
+
### `attributionReporting`
|
|
132
|
+
|
|
133
|
+
Fáith deliberately does not implement this.
|
|
134
|
+
|
|
135
|
+
### `body`
|
|
136
|
+
|
|
137
|
+
*The request body contains content to send to the server, for example in a `POST` or `PUT` request.
|
|
138
|
+
It is specified as an instance of any of the following types:*
|
|
139
|
+
|
|
140
|
+
- *a string*
|
|
141
|
+
- *`ArrayBuffer`*
|
|
142
|
+
- *`Blob`*
|
|
143
|
+
- *`DataView`*
|
|
144
|
+
- *`File`*
|
|
145
|
+
- *`FormData`*
|
|
146
|
+
- *`TypedArray`*
|
|
147
|
+
- *`URLSearchParams`* Not yet implemented.
|
|
148
|
+
- *`ReadableStream`* Note that Fáith currently reads this into memory before sending the request.
|
|
149
|
+
|
|
150
|
+
*If `body` is a `ReadableStream`, the `duplex` option must also be set.*
|
|
151
|
+
|
|
152
|
+
### `browsingTopics`
|
|
153
|
+
|
|
154
|
+
Fáith deliberately does not implement this.
|
|
155
|
+
|
|
156
|
+
### `cache`
|
|
157
|
+
|
|
158
|
+
Fáith does not respect this option on the `RequestInit` dictionary. Instead, the option is present
|
|
159
|
+
on `Agent` and applies to all requests made with that `Agent`.
|
|
160
|
+
|
|
161
|
+
### `credentials`
|
|
162
|
+
|
|
163
|
+
*Controls whether or not the browser sends credentials with the request, as well as whether any
|
|
164
|
+
`Set-Cookie` response headers are respected. Credentials are cookies, ~~TLS client certificates,~~
|
|
165
|
+
or authentication headers containing a username and password. This option may be any one of the
|
|
166
|
+
following values:*
|
|
167
|
+
|
|
168
|
+
- *`omit`: Never send credentials in the request or include credentials in the response.*
|
|
169
|
+
- ~~`same-origin`~~: Fáith does not implement this, as there is no concept of "origin" on the server.
|
|
170
|
+
- *`include`: *Always include credentials,* ~~even for cross-origin requests.~~
|
|
171
|
+
|
|
172
|
+
Fáith ignores the `Access-Control-Allow-Credentials` and `Access-Control-Allow-Origin` headers.
|
|
173
|
+
|
|
174
|
+
Fáith currently does not `omit` the TLS client certificate when the request's `Agent` has one
|
|
175
|
+
configured. This is an upstream limitation.
|
|
176
|
+
|
|
177
|
+
If the request's `Agent` has cookies enabled, new cookies from the response will be added to the
|
|
178
|
+
cookie jar, even as Fáith strips them from the request and response headers returned to the user.
|
|
179
|
+
This is an upstream limitation.
|
|
180
|
+
|
|
181
|
+
Defaults to `include` (browsers default to `same-origin`).
|
|
182
|
+
|
|
183
|
+
### `duplex`
|
|
184
|
+
|
|
185
|
+
*Controls duplex behavior of the request. If this is present it must have the value `half`, meaning
|
|
186
|
+
that Fáith will send the entire request before processing the response.*
|
|
187
|
+
|
|
188
|
+
*This option must be present when `body` is a `ReadableStream`.*
|
|
189
|
+
|
|
190
|
+
### `headers`
|
|
191
|
+
|
|
192
|
+
*Any headers you want to add to your request, contained within a `Headers` object or an object
|
|
193
|
+
literal whose keys are the names of headers and whose values are the header values.*
|
|
194
|
+
|
|
195
|
+
Fáith allows all request headers to be set (unlike browsers, which [forbid][1] a number of them).
|
|
196
|
+
|
|
197
|
+
[1]: https://developer.mozilla.org/en-US/docs/Glossary/Forbidden_request_header
|
|
198
|
+
|
|
199
|
+
### `integrity`
|
|
200
|
+
|
|
201
|
+
Not implemented yet.
|
|
202
|
+
|
|
203
|
+
*Contains the subresource integrity value of the request.*
|
|
204
|
+
|
|
205
|
+
*The format of this option is `<hash-algo>-<hash-source>` where:*
|
|
206
|
+
|
|
207
|
+
- *`<hash-algo>` is one of the following values: `sha256`, `sha384`, or `sha512`*
|
|
208
|
+
- *`<hash-source>` is the Base64-encoding of the result of hashing the resource with the specified
|
|
209
|
+
hash algorithm.*
|
|
210
|
+
|
|
211
|
+
Fáith only checks the integrity when using `bytes()`, `json()`, `text()`, `arrayBuffer()`, and
|
|
212
|
+
`blob()`. Verification when reading through the `body` stream is not currently supported.
|
|
213
|
+
|
|
214
|
+
Note that browsers will throw at the `fetch()` call when integrity fails, but Fáith will only throw
|
|
215
|
+
when the above methods are called, as until then the body contents are not available.
|
|
216
|
+
|
|
217
|
+
### `keepalive`
|
|
218
|
+
|
|
219
|
+
Not supported.
|
|
220
|
+
|
|
221
|
+
Note that this is different from `Connection: keep-alive`; Fáith connections are pooled within each
|
|
222
|
+
single `Agent`, so subsequent requests to the same endpoint are faster until the pooled connection
|
|
223
|
+
times out. The `keepalive` option in browsers is instead a way to send a `fetch()` right before the
|
|
224
|
+
page is unloaded, for tracking or analytics purposes. This concept does not exist in Node.js.
|
|
225
|
+
|
|
226
|
+
### `method`
|
|
227
|
+
|
|
228
|
+
*The request method. Defaults to `GET`.*
|
|
229
|
+
|
|
230
|
+
### `mode`
|
|
231
|
+
|
|
232
|
+
Fáith deliberately does not implement this, as there is no CORS/origin.
|
|
233
|
+
|
|
234
|
+
### `priority`
|
|
235
|
+
|
|
236
|
+
Not supported.
|
|
237
|
+
|
|
238
|
+
### `redirect`
|
|
239
|
+
|
|
240
|
+
Fáith does not respect this option on the `RequestInit` dictionary. Instead, the option is present
|
|
241
|
+
on `Agent` and applies to all requests made with that `Agent`.
|
|
242
|
+
|
|
243
|
+
### `referrer`
|
|
244
|
+
|
|
245
|
+
Fáith deliberately does not implement this, as there is no origin.
|
|
246
|
+
|
|
247
|
+
However, Fáith does set the `Referer` header when redirecting automatically.
|
|
248
|
+
|
|
249
|
+
### `referrerPolicy`
|
|
250
|
+
|
|
251
|
+
Fáith deliberately does not implement this, as there is no origin.
|
|
252
|
+
|
|
253
|
+
However, Fáith does set the `Referer` header when redirecting automatically.
|
|
254
|
+
|
|
255
|
+
### `signal`
|
|
256
|
+
|
|
257
|
+
*An `AbortSignal`. If this option is set, the request can be canceled by calling `abort()` on the
|
|
258
|
+
corresponding `AbortController`.*
|
|
259
|
+
|
|
260
|
+
### `timeout`
|
|
261
|
+
|
|
262
|
+
Custom to Fáith. Cancels the request after this many milliseconds.
|
|
263
|
+
|
|
264
|
+
This will give a different error to using `signal` with a timeout, which might be preferable in
|
|
265
|
+
some cases. It also has a slightly different internal behaviour: `signal` may abort the request
|
|
266
|
+
only until the response headers have been received, while `timeout` will apply through the entire
|
|
267
|
+
response receipt.
|
|
268
|
+
|
|
269
|
+
## `Response`
|
|
270
|
+
|
|
271
|
+
*The `Response` interface of the Fetch API represents the response to a request.*
|
|
272
|
+
|
|
273
|
+
Fáith does not allow its `Response` object to be constructed. If you need to, you may use the
|
|
274
|
+
`webResponse()` method to convert one into a Web API `Response` object; note the caveats.
|
|
275
|
+
|
|
276
|
+
### `Response.body`
|
|
277
|
+
|
|
278
|
+
*The `body` read-only property of the `Response` interface is a `ReadableStream` of the body
|
|
279
|
+
contents,* or `null` for any actual HTTP response that has no body, such as `HEAD` requests and
|
|
280
|
+
`204 No Content` responses.
|
|
281
|
+
|
|
282
|
+
Note that browsers currently do not return `null` for those responses, but the spec requires it.
|
|
283
|
+
Fáith chooses to respect the spec rather than the browsers in this case.
|
|
284
|
+
|
|
285
|
+
### `Response.bodyUsed`
|
|
286
|
+
|
|
287
|
+
*The `bodyUsed` read-only property of the `Response` interface is a boolean value that indicates
|
|
288
|
+
whether the body has been read yet.*
|
|
289
|
+
|
|
290
|
+
In Fáith, this indicates whether the body stream has ever been read from or canceled, as defined
|
|
291
|
+
[in the spec](https://streams.spec.whatwg.org/#is-readable-stream-disturbed). Note that accessing
|
|
292
|
+
the `.body` property counts as a read, even if you don't actually consume any bytes of content.
|
|
293
|
+
|
|
294
|
+
### `Response.headers`
|
|
295
|
+
|
|
296
|
+
*The `headers` read-only property of the `Response` interface contains the `Headers` object
|
|
297
|
+
associated with the response.*
|
|
298
|
+
|
|
299
|
+
Note that Fáith does not provide a custom `Headers` class; instead the Web API `Headers` structure
|
|
300
|
+
is used directly and constructed by Fáith when needed.
|
|
301
|
+
|
|
302
|
+
### `Response.ok`
|
|
303
|
+
|
|
304
|
+
*The `ok` read-only property of the `Response` interface contains a boolean stating whether the
|
|
305
|
+
response was successful (status in the range 200-299) or not.*
|
|
306
|
+
|
|
307
|
+
### `Response.redirected`
|
|
308
|
+
|
|
309
|
+
*The `redirected` read-only property of the `Response` interface indicates whether or not the
|
|
310
|
+
response is the result of a request you made which was redirected.*
|
|
311
|
+
|
|
312
|
+
*Note that by the time you read this property, the redirect will already have happened, and you
|
|
313
|
+
cannot prevent it by aborting the fetch at this point.*
|
|
314
|
+
|
|
315
|
+
### `Response.status`
|
|
316
|
+
|
|
317
|
+
*The `status` read-only property of the `Response` interface contains the HTTP status codes of the
|
|
318
|
+
response. For example, 200 for success, 404 if the resource could not be found.*
|
|
319
|
+
|
|
320
|
+
*A value is `0` is returned for a response whose `type` is `opaque`, `opaqueredirect`, or `error`.*
|
|
321
|
+
|
|
322
|
+
### `Response.statusText`
|
|
323
|
+
|
|
324
|
+
*The `statusText` read-only property of the `Response` interface contains the status message
|
|
325
|
+
corresponding to the HTTP status code in `Response.status`. For example, this would be `OK` for a
|
|
326
|
+
status code `200`, `Continue` for `100`, `Not Found` for `404`.*
|
|
327
|
+
|
|
328
|
+
In HTTP/1, servers can send custom status text. This is returned here. In HTTP/2 and HTTP/3, custom
|
|
329
|
+
status text is not supported at all, and the `statusText` property is either empty or simulated
|
|
330
|
+
from well-known status codes.
|
|
331
|
+
|
|
332
|
+
### `Response.type`
|
|
333
|
+
|
|
334
|
+
*The `type` read-only property of the `Response` interface contains the type of the response. The
|
|
335
|
+
type determines whether scripts are able to access the response body and headers.*
|
|
336
|
+
|
|
337
|
+
In Fáith, this is always set to `basic`.
|
|
338
|
+
|
|
339
|
+
### `Response.url`
|
|
340
|
+
|
|
341
|
+
*The `url` read-only property of the `Response` interface contains the URL of the response. The
|
|
342
|
+
value of the `url` property will be the final URL obtained after any redirects.*
|
|
343
|
+
|
|
344
|
+
### `Response.version`
|
|
345
|
+
|
|
346
|
+
The `version` read-only property of the `Response` interface contains the HTTP version of the
|
|
347
|
+
response. The value will be the final HTTP version after any redirects and protocol upgrades.
|
|
348
|
+
|
|
349
|
+
This is custom to Fáith.
|
|
350
|
+
|
|
351
|
+
### `Response.arrayBuffer()`
|
|
352
|
+
|
|
353
|
+
*The `arrayBuffer()` method of the `Response` interface takes a `Response` stream and reads it to
|
|
354
|
+
completion. It returns a promise that resolves with an `ArrayBuffer`.*
|
|
355
|
+
|
|
356
|
+
### `Response.blob()`
|
|
357
|
+
|
|
358
|
+
*The `blob()` method of the `Response` interface takes a `Response` stream and reads it to
|
|
359
|
+
completion. It returns a promise that resolves with a `Blob`.*
|
|
360
|
+
|
|
361
|
+
*The `type` of the `Blob` is set to the value of the `Content-Type` response header.*
|
|
362
|
+
|
|
363
|
+
### `Response.bytes()`
|
|
364
|
+
|
|
365
|
+
*The `bytes()` method of the `Response` interface takes a `Response` stream and reads it to
|
|
366
|
+
completion. It returns a promise that resolves with a `Uint8Array`.*
|
|
367
|
+
|
|
368
|
+
In Fáith, this returns a Node.js `Buffer`, which can be used as (and is a subclass of) a `Uint8Array`.
|
|
369
|
+
|
|
370
|
+
### `Response.clone()`
|
|
371
|
+
|
|
372
|
+
*The `clone()` method of the `Response` interface creates a clone of a response object, identical
|
|
373
|
+
in every way, but stored in a different variable.*
|
|
374
|
+
|
|
375
|
+
*`clone()` throws* an `Error` *if the response body has already been used.*
|
|
376
|
+
|
|
377
|
+
(In-spec, this should throw a `TypeError`, but for technical reasons this is not possible with Fáith.)
|
|
378
|
+
|
|
379
|
+
### `Response.formData()`
|
|
380
|
+
|
|
381
|
+
Fáith deliberately does not implement this.
|
|
382
|
+
|
|
383
|
+
### `Response.json()`
|
|
384
|
+
|
|
385
|
+
*The `json()` method of the `Response` interface takes a `Response` stream and reads it to
|
|
386
|
+
completion. It returns a promise which resolves with the result of parsing the body text as
|
|
387
|
+
`JSON`.*
|
|
388
|
+
|
|
389
|
+
*Note that despite the method being named `json()`, the result is not JSON but is instead the
|
|
390
|
+
result of taking JSON as input and parsing it to produce a JavaScript object.*
|
|
391
|
+
|
|
392
|
+
Further note that, at least in Fáith, this method first reads the entire response body as bytes,
|
|
393
|
+
and then parses that as JSON. This can use up to double the amount of memory. If you need more
|
|
394
|
+
efficient access, consider handling the response body as a stream.
|
|
395
|
+
|
|
396
|
+
### `Response.text()`
|
|
397
|
+
|
|
398
|
+
*The `text()` method of the `Response` interface takes a `Response` stream and reads it to
|
|
399
|
+
completion. It returns a promise that resolves with a `String`. The response is always decoded
|
|
400
|
+
using UTF-8.*
|
|
401
|
+
|
|
402
|
+
### `Response.webResponse()`
|
|
403
|
+
|
|
404
|
+
This is entirely custom to Fáith. It returns a Web API `Response` instead of Fáith's custom
|
|
405
|
+
`Response` class. However, it's not possible to construct a Web API `Response` that has all the
|
|
406
|
+
properties of a Fáith Response (or of another Web Response, for that matter). So this method only
|
|
407
|
+
returns a Response from:
|
|
408
|
+
|
|
409
|
+
- the `body` stream
|
|
410
|
+
- the `status`, `statusCode`, and `headers` properties
|
|
411
|
+
|
|
412
|
+
Note that if `json()`, `bytes()`, etc has been called on the original response, the body stream
|
|
413
|
+
of the new Web `Response` will be empty or inaccessible. If the body stream of the original
|
|
414
|
+
response has been partially read, only the remaining bytes will be available in the new `Response`.
|
|
415
|
+
|
|
416
|
+
## `Agent`
|
|
417
|
+
|
|
418
|
+
The `Agent` interface of the Fáith API represents an instance of an HTTP client. Each `Agent` has
|
|
419
|
+
its own options, connection pool, caches, etc. There are also conveniences such as `headers` for
|
|
420
|
+
setting default headers on all requests done with the agent, and statistics collected by the agent.
|
|
421
|
+
|
|
422
|
+
Re-using connections between requests is a significant performance improvement: not only because
|
|
423
|
+
the TCP and TLS handshake is only performed once across many different requests, but also because
|
|
424
|
+
the DNS lookup doesn't need to occur for subsequent requests on the same connection. Depending on
|
|
425
|
+
DNS technology (DoH and DoT add a whole separate handshake to the process) and overall latency,
|
|
426
|
+
this can not only speed up requests on average, but also reduce system load.
|
|
427
|
+
|
|
428
|
+
For this reason, and also because in browsers this behaviour is standard, **all** requests with
|
|
429
|
+
Fáith use an `Agent`. For `fetch()` calls that don't specify one explicitly, a global agent with
|
|
430
|
+
default options is created on first use.
|
|
431
|
+
|
|
432
|
+
### Syntax
|
|
433
|
+
|
|
434
|
+
```javascript
|
|
435
|
+
new Agent()
|
|
436
|
+
new Agent(options)
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
### `cache`
|
|
440
|
+
### `cookies: bool`
|
|
441
|
+
|
|
442
|
+
Enable a persistent cookie store for the agent. Cookies received in responses will be preserved and
|
|
443
|
+
included in additional requests.
|
|
444
|
+
|
|
445
|
+
Default: `false`.
|
|
446
|
+
|
|
447
|
+
You may use `agent.getCookie(url: string)` and `agent.addCookie(url: string, value: string)` to add
|
|
448
|
+
and retrieve cookies from the store.
|
|
449
|
+
|
|
450
|
+
### `dns`
|
|
451
|
+
### `headers: Array<{ name: string, value: string, sensitive?: bool }>`
|
|
452
|
+
|
|
453
|
+
Sets the default headers for every request.
|
|
454
|
+
|
|
455
|
+
If header names or values are invalid, they are silently omitted.
|
|
456
|
+
Sensitive headers (e.g. `Authorization`) should be marked.
|
|
457
|
+
|
|
458
|
+
Default: none.
|
|
459
|
+
|
|
460
|
+
### `http3`
|
|
461
|
+
#### `congestion`
|
|
462
|
+
### `pool`
|
|
463
|
+
#### `maxIdlePerHost`
|
|
464
|
+
#### `idleTimeout`
|
|
465
|
+
### `redirect`
|
|
466
|
+
### `retry`
|
|
467
|
+
### `timeout`
|
|
468
|
+
#### `connect`
|
|
469
|
+
#### `read`
|
|
470
|
+
#### `total`
|
|
471
|
+
### `tls`
|
|
472
|
+
#### `earlyData`
|
|
473
|
+
#### `identity`
|
|
474
|
+
#### `required`
|
|
475
|
+
|
|
476
|
+
### `userAgent`
|
|
477
|
+
|
|
478
|
+
Custom user agent string.
|
|
479
|
+
|
|
480
|
+
Default: `Faith/{version} reqwest/{version}`.
|
|
481
|
+
|
|
482
|
+
You may use the `USER_AGENT` constant if you wish to prepend your own agent to the default, e.g.
|
|
483
|
+
|
|
484
|
+
```javascript
|
|
485
|
+
import { Agent, USER_AGENT } from '@passcod/faith';
|
|
486
|
+
const agent = new Agent({
|
|
487
|
+
userAgent: `YourApp/1.2.3 ${USER_AGENT}`,
|
|
488
|
+
});
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
### `addCookie(url: string, cookie: string)`
|
|
492
|
+
|
|
493
|
+
Add a cookie into the agent.
|
|
494
|
+
|
|
495
|
+
Does nothing if:
|
|
496
|
+
- the cookie store is disabled
|
|
497
|
+
- the url is malformed
|
|
498
|
+
|
|
499
|
+
### `getCookie(url: string): string | null`
|
|
500
|
+
|
|
501
|
+
Retrieve a cookie from the store.
|
|
502
|
+
|
|
503
|
+
Returns `null` if:
|
|
504
|
+
- there's no cookie at this url
|
|
505
|
+
- the cookie store is disabled
|
|
506
|
+
- the url is malformed
|
|
507
|
+
- the cookie cannot be represented as a string
|
|
508
|
+
|
|
509
|
+
### `stats(): object`
|
|
510
|
+
|
|
511
|
+
Returns statistics gathered by this agent:
|
|
512
|
+
|
|
513
|
+
- `requestsSent`
|
|
514
|
+
- `responsesReceived`
|
|
515
|
+
|
|
516
|
+
## Error mapping
|
|
517
|
+
|
|
518
|
+
Fáith produces fine-grained errors, but maps them to a few javascript error types for fetch
|
|
519
|
+
compatibility. The `.code` property on errors thrown from Fáith is set to a stable name for each
|
|
520
|
+
error kind, documented in this comprehensive mapping:
|
|
521
|
+
|
|
522
|
+
- JS `AbortError`:
|
|
523
|
+
- `Aborted` — request was aborted using `signal`
|
|
524
|
+
- `Timeout` — request timed out
|
|
525
|
+
- JS `NetworkError`:
|
|
526
|
+
- `Network` — network error
|
|
527
|
+
- JS `SyntaxError`:
|
|
528
|
+
- `JsonParse` — JSON parse error for `response.json()`
|
|
529
|
+
- `Utf8Parse` — UTF8 decoding error for `response.text()`
|
|
530
|
+
- JS `TypeError`:
|
|
531
|
+
- `InvalidHeader` — invalid header name or value
|
|
532
|
+
- `InvalidMethod` — invalid HTTP method
|
|
533
|
+
- `InvalidUrl` — invalid URL string
|
|
534
|
+
- `ResponseAlreadyDisturbed` — body already read (mutually exclusive operations)
|
|
535
|
+
- `ResponseBodyNotAvailable` — body is null or not available
|
|
536
|
+
- JS generic `Error`:
|
|
537
|
+
- `BodyStream` — internal stream handling error
|
|
538
|
+
- `RuntimeThread` — failed to start or schedule threads on the internal tokio runtime
|
|
539
|
+
|
|
540
|
+
The library exports an `ERROR_CODES` object which has every error code the library throws, and
|
|
541
|
+
every error thrown also has a `code` property that is set to one of those codes. So you can
|
|
542
|
+
accurately respond to the exact error kind by checking its code and matching against the right
|
|
543
|
+
constant from `ERROR_CODES`, instead of doing string matching on the error message, or coarse
|
|
544
|
+
`instance of` matching.
|
|
545
|
+
|
|
546
|
+
Due to technical limitations, when reading a body stream, reads might fail, but that error
|
|
547
|
+
will not have a `.code` property.
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/* auto-generated by NAPI-RS */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
export declare class Agent {
|
|
4
|
+
constructor(options?: AgentOptions | undefined | null)
|
|
5
|
+
addCookie(url: string, cookie: string): void
|
|
6
|
+
getCookie(url: string): string | null
|
|
7
|
+
stats(): AgentStats
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export declare class AgentStats {
|
|
11
|
+
requestsSent: number
|
|
12
|
+
responsesReceived: number
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export declare class FaithResponse {
|
|
16
|
+
get headers(): Array<[string, string]>
|
|
17
|
+
get ok(): boolean
|
|
18
|
+
get redirected(): boolean
|
|
19
|
+
get status(): number
|
|
20
|
+
get statusText(): string
|
|
21
|
+
get type(): string
|
|
22
|
+
get url(): string
|
|
23
|
+
get version(): string
|
|
24
|
+
/** Check if the response body has been disturbed (read) */
|
|
25
|
+
get bodyUsed(): boolean
|
|
26
|
+
/** Get the response body as a ReadableStream */
|
|
27
|
+
get body(): ReadableStream<Buffer> | null
|
|
28
|
+
/**
|
|
29
|
+
* Get response body as bytes
|
|
30
|
+
*
|
|
31
|
+
* This may use up to 2x the amount of memory that the response body takes
|
|
32
|
+
* when the Response is cloned() and will create a full copy of the data.
|
|
33
|
+
*/
|
|
34
|
+
bytes(): Async<Buffer>
|
|
35
|
+
/** Convert response body to text (UTF-8) */
|
|
36
|
+
text(): Async<string>
|
|
37
|
+
/** Parse response body as JSON */
|
|
38
|
+
json(): Async<any>
|
|
39
|
+
/**
|
|
40
|
+
* Create a clone of the response
|
|
41
|
+
*
|
|
42
|
+
* Specially, this doesn't set the disturbed flag, so that `body()` or other such
|
|
43
|
+
* methods can work afterwards. However, it will throw if the body has already
|
|
44
|
+
* been read from.
|
|
45
|
+
*
|
|
46
|
+
* Clones will cache in memory the section of the response body that is read
|
|
47
|
+
* from one clone and not yet consumed by all others. In the worst case, you can
|
|
48
|
+
* end up with a copy of the entire response body if you end up not consuming one
|
|
49
|
+
* of the clones.
|
|
50
|
+
*/
|
|
51
|
+
clone(): FaithResponse
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export interface AgentOptions {
|
|
55
|
+
cookies?: boolean
|
|
56
|
+
headers?: Array<Header>
|
|
57
|
+
userAgent?: string
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export declare const enum CredentialsOption {
|
|
61
|
+
Omit = 'omit',
|
|
62
|
+
SameOrigin = 'same-origin',
|
|
63
|
+
Include = 'include'
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export declare const enum DuplexOption {
|
|
67
|
+
Half = 'half'
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export declare function errorCodes(): Array<string>
|
|
71
|
+
|
|
72
|
+
export const FAITH_VERSION: string
|
|
73
|
+
|
|
74
|
+
export declare const enum FaithErrorKind {
|
|
75
|
+
Aborted = 'Aborted',
|
|
76
|
+
BodyStream = 'BodyStream',
|
|
77
|
+
InvalidHeader = 'InvalidHeader',
|
|
78
|
+
InvalidMethod = 'InvalidMethod',
|
|
79
|
+
InvalidUrl = 'InvalidUrl',
|
|
80
|
+
JsonParse = 'JsonParse',
|
|
81
|
+
Network = 'Network',
|
|
82
|
+
ResponseAlreadyDisturbed = 'ResponseAlreadyDisturbed',
|
|
83
|
+
ResponseBodyNotAvailable = 'ResponseBodyNotAvailable',
|
|
84
|
+
RuntimeThread = 'RuntimeThread',
|
|
85
|
+
Timeout = 'Timeout',
|
|
86
|
+
Utf8Parse = 'Utf8Parse'
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export declare function faithFetch(url: string, options: FaithOptionsAndBody, signal?: AbortSignal | undefined | null): Async<FaithResponse>
|
|
90
|
+
|
|
91
|
+
export interface FaithOptionsAndBody {
|
|
92
|
+
method?: string
|
|
93
|
+
headers?: Array<[string, string]>
|
|
94
|
+
body?: string | Buffer | Uint8Array
|
|
95
|
+
timeout?: number
|
|
96
|
+
credentials?: CredentialsOption
|
|
97
|
+
duplex?: DuplexOption
|
|
98
|
+
agent: Agent
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export interface Header {
|
|
102
|
+
name: string
|
|
103
|
+
value: string
|
|
104
|
+
sensitive?: boolean
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export const REQWEST_VERSION: string
|
|
108
|
+
|
|
109
|
+
export const USER_AGENT: string
|