mirror of
https://github.com/dawidd6/action-send-mail.git
synced 2026-01-31 19:38:27 +07:00
Run npm ci --ignore-scripts to update dependencies (#254)
* Initial plan * Run npm ci --ignore-scripts to update dependencies Co-authored-by: dawidd6 <9713907+dawidd6@users.noreply.github.com> * Convert CommonJS to ESM (#255) * Initial plan * Convert CommonJS imports to ESM Co-authored-by: dawidd6 <9713907+dawidd6@users.noreply.github.com> * Use node: protocol prefix for built-in modules Co-authored-by: dawidd6 <9713907+dawidd6@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: dawidd6 <9713907+dawidd6@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: dawidd6 <9713907+dawidd6@users.noreply.github.com>
This commit is contained in:
27
node_modules/undici/docs/api/Fetch.md
generated
vendored
27
node_modules/undici/docs/api/Fetch.md
generated
vendored
@@ -1,27 +0,0 @@
|
||||
# Fetch
|
||||
|
||||
Undici exposes a fetch() method starts the process of fetching a resource from the network.
|
||||
|
||||
Documentation and examples can be found on [MDN](https://developer.mozilla.org/en-US/docs/Web/API/fetch).
|
||||
|
||||
## File
|
||||
|
||||
This API is implemented as per the standard, you can find documentation on [MDN](https://developer.mozilla.org/en-US/docs/Web/API/File)
|
||||
|
||||
In Node versions v18.13.0 and above and v19.2.0 and above, undici will default to using Node's [File](https://nodejs.org/api/buffer.html#class-file) class. In versions where it's not available, it will default to the undici one.
|
||||
|
||||
## FormData
|
||||
|
||||
This API is implemented as per the standard, you can find documentation on [MDN](https://developer.mozilla.org/en-US/docs/Web/API/FormData)
|
||||
|
||||
## Response
|
||||
|
||||
This API is implemented as per the standard, you can find documentation on [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Response)
|
||||
|
||||
## Request
|
||||
|
||||
This API is implemented as per the standard, you can find documentation on [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Request)
|
||||
|
||||
## Header
|
||||
|
||||
This API is implemented as per the standard, you can find documentation on [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Headers)
|
||||
BIN
node_modules/undici/docs/assets/lifecycle-diagram.png
generated
vendored
BIN
node_modules/undici/docs/assets/lifecycle-diagram.png
generated
vendored
Binary file not shown.
|
Before Width: | Height: | Size: 46 KiB |
0
node_modules/undici/docs/api/Agent.md → node_modules/undici/docs/docs/api/Agent.md
generated
vendored
0
node_modules/undici/docs/api/Agent.md → node_modules/undici/docs/docs/api/Agent.md
generated
vendored
@@ -50,7 +50,7 @@ Arguments:
|
||||
|
||||
### `BalancedPool.removeUpstream(upstream)`
|
||||
|
||||
Removes an upstream that was previously addded.
|
||||
Removes an upstream that was previously added.
|
||||
|
||||
### `BalancedPool.close([callback])`
|
||||
|
||||
7
node_modules/undici/docs/api/Client.md → node_modules/undici/docs/docs/api/Client.md
generated
vendored
7
node_modules/undici/docs/api/Client.md → node_modules/undici/docs/docs/api/Client.md
generated
vendored
@@ -19,17 +19,18 @@ Returns: `Client`
|
||||
|
||||
> ⚠️ Warning: The `H2` support is experimental.
|
||||
|
||||
* **bodyTimeout** `number | null` (optional) - Default: `300e3` - The timeout after which a request will time out, in milliseconds. Monitors time between receiving body data. Use `0` to disable it entirely. Defaults to 300 seconds.
|
||||
* **bodyTimeout** `number | null` (optional) - Default: `300e3` - The timeout after which a request will time out, in milliseconds. Monitors time between receiving body data. Use `0` to disable it entirely. Defaults to 300 seconds. Please note the `timeout` will be reset if you keep writing data to the scoket everytime.
|
||||
* **headersTimeout** `number | null` (optional) - Default: `300e3` - The amount of time, in milliseconds, the parser will wait to receive the complete HTTP headers while not sending the request. Defaults to 300 seconds.
|
||||
* **keepAliveMaxTimeout** `number | null` (optional) - Default: `600e3` - The maximum allowed `keepAliveTimeout`, in milliseconds, when overridden by *keep-alive* hints from the server. Defaults to 10 minutes.
|
||||
* **keepAliveTimeout** `number | null` (optional) - Default: `4e3` - The timeout, in milliseconds, after which a socket without active requests will time out. Monitors time between activity on a connected socket. This value may be overridden by *keep-alive* hints from the server. See [MDN: HTTP - Headers - Keep-Alive directives](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Keep-Alive#directives) for more details. Defaults to 4 seconds.
|
||||
* **keepAliveTimeoutThreshold** `number | null` (optional) - Default: `1e3` - A number of milliseconds subtracted from server *keep-alive* hints when overriding `keepAliveTimeout` to account for timing inaccuracies caused by e.g. transport latency. Defaults to 1 second.
|
||||
* **keepAliveTimeoutThreshold** `number | null` (optional) - Default: `2e3` - A number of milliseconds subtracted from server *keep-alive* hints when overriding `keepAliveTimeout` to account for timing inaccuracies caused by e.g. transport latency. Defaults to 2 seconds.
|
||||
* **maxHeaderSize** `number | null` (optional) - Default: `--max-http-header-size` or `16384` - The maximum length of request headers in bytes. Defaults to Node.js' --max-http-header-size or 16KiB.
|
||||
* **maxResponseSize** `number | null` (optional) - Default: `-1` - The maximum length of response body in bytes. Set to `-1` to disable.
|
||||
* **pipelining** `number | null` (optional) - Default: `1` - The amount of concurrent requests to be sent over the single TCP/TLS connection according to [RFC7230](https://tools.ietf.org/html/rfc7230#section-6.3.2). Carefully consider your workload and environment before enabling concurrent requests as pipelining may reduce performance if used incorrectly. Pipelining is sensitive to network stack settings as well as head of line blocking caused by e.g. long running requests. Set to `0` to disable keep-alive connections.
|
||||
* **connect** `ConnectOptions | Function | null` (optional) - Default: `null`.
|
||||
* **strictContentLength** `Boolean` (optional) - Default: `true` - Whether to treat request content length mismatches as errors. If true, an error is thrown when the request content-length header doesn't match the length of the request body.
|
||||
* **interceptors** `{ Client: DispatchInterceptor[] }` - Default: `[RedirectInterceptor]` - A list of interceptors that are applied to the dispatch method. Additional logic can be applied (such as, but not limited to: 302 status code handling, authentication, cookies, compression and caching). Note that the behavior of interceptors is Experimental and might change at any given time.
|
||||
<!-- TODO: Remove once we drop its support -->
|
||||
* **interceptors** `{ Client: DispatchInterceptor[] }` - Default: `[RedirectInterceptor]` - A list of interceptors that are applied to the dispatch method. Additional logic can be applied (such as, but not limited to: 302 status code handling, authentication, cookies, compression and caching). Note that the behavior of interceptors is Experimental and might change at any given time. **Note: this is deprecated in favor of [Dispatcher#compose](./Dispatcher.md#dispatcher). Support will be droped in next major.**
|
||||
* **autoSelectFamily**: `boolean` (optional) - Default: depends on local Node version, on Node 18.13.0 and above is `false`. Enables a family autodetection algorithm that loosely implements section 5 of [RFC 8305](https://tools.ietf.org/html/rfc8305#section-5). See [here](https://nodejs.org/api/net.html#socketconnectoptions-connectlistener) for more details. This option is ignored if not supported by the current Node version.
|
||||
* **autoSelectFamilyAttemptTimeout**: `number` - Default: depends on local Node version, on Node 18.13.0 and above is `250`. The amount of time in milliseconds to wait for a connection attempt to finish before trying the next address when using the `autoSelectFamily` option. See [here](https://nodejs.org/api/net.html#socketconnectoptions-connectlistener) for more details.
|
||||
* **allowH2**: `boolean` - Default: `false`. Enables support for H2 if the server has assigned bigger priority to it through ALPN negotiation.
|
||||
62
node_modules/undici/docs/docs/api/Debug.md
generated
vendored
Normal file
62
node_modules/undici/docs/docs/api/Debug.md
generated
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
# Debug
|
||||
|
||||
Undici (and subsenquently `fetch` and `websocket`) exposes a debug statement that can be enabled by setting `NODE_DEBUG` within the environment.
|
||||
|
||||
The flags availabile are:
|
||||
|
||||
## `undici`
|
||||
|
||||
This flag enables debug statements for the core undici library.
|
||||
|
||||
```sh
|
||||
NODE_DEBUG=undici node script.js
|
||||
|
||||
UNDICI 16241: connecting to nodejs.org using https:h1
|
||||
UNDICI 16241: connecting to nodejs.org using https:h1
|
||||
UNDICI 16241: connected to nodejs.org using https:h1
|
||||
UNDICI 16241: sending request to GET https://nodejs.org//
|
||||
UNDICI 16241: received response to GET https://nodejs.org// - HTTP 307
|
||||
UNDICI 16241: connecting to nodejs.org using https:h1
|
||||
UNDICI 16241: trailers received from GET https://nodejs.org//
|
||||
UNDICI 16241: connected to nodejs.org using https:h1
|
||||
UNDICI 16241: sending request to GET https://nodejs.org//en
|
||||
UNDICI 16241: received response to GET https://nodejs.org//en - HTTP 200
|
||||
UNDICI 16241: trailers received from GET https://nodejs.org//en
|
||||
```
|
||||
|
||||
## `fetch`
|
||||
|
||||
This flag enables debug statements for the `fetch` API.
|
||||
|
||||
> **Note**: statements are pretty similar to the ones in the `undici` flag, but scoped to `fetch`
|
||||
|
||||
```sh
|
||||
NODE_DEBUG=fetch node script.js
|
||||
|
||||
FETCH 16241: connecting to nodejs.org using https:h1
|
||||
FETCH 16241: connecting to nodejs.org using https:h1
|
||||
FETCH 16241: connected to nodejs.org using https:h1
|
||||
FETCH 16241: sending request to GET https://nodejs.org//
|
||||
FETCH 16241: received response to GET https://nodejs.org// - HTTP 307
|
||||
FETCH 16241: connecting to nodejs.org using https:h1
|
||||
FETCH 16241: trailers received from GET https://nodejs.org//
|
||||
FETCH 16241: connected to nodejs.org using https:h1
|
||||
FETCH 16241: sending request to GET https://nodejs.org//en
|
||||
FETCH 16241: received response to GET https://nodejs.org//en - HTTP 200
|
||||
FETCH 16241: trailers received from GET https://nodejs.org//en
|
||||
```
|
||||
|
||||
## `websocket`
|
||||
|
||||
This flag enables debug statements for the `Websocket` API.
|
||||
|
||||
> **Note**: statements can overlap with `UNDICI` ones if `undici` or `fetch` flag has been enabled as well.
|
||||
|
||||
```sh
|
||||
NODE_DEBUG=websocket node script.js
|
||||
|
||||
WEBSOCKET 18309: connecting to echo.websocket.org using https:h1
|
||||
WEBSOCKET 18309: connected to echo.websocket.org using https:h1
|
||||
WEBSOCKET 18309: sending request to GET https://echo.websocket.org//
|
||||
WEBSOCKET 18309: connection opened <ip_address>
|
||||
```
|
||||
@@ -19,9 +19,9 @@ diagnosticsChannel.channel('undici:request:create').subscribe(({ request }) => {
|
||||
console.log('completed', request.completed)
|
||||
console.log('method', request.method)
|
||||
console.log('path', request.path)
|
||||
console.log('headers') // raw text, e.g: 'bar: bar\r\n'
|
||||
console.log('headers') // array of strings, e.g: ['foo', 'bar']
|
||||
request.addHeader('hello', 'world')
|
||||
console.log('headers', request.headers) // e.g. 'bar: bar\r\nhello: world\r\n'
|
||||
console.log('headers', request.headers) // e.g. ['foo', 'bar', 'hello', 'world']
|
||||
})
|
||||
```
|
||||
|
||||
@@ -105,7 +105,7 @@ You can not assume that this event is related to any specific request.
|
||||
import diagnosticsChannel from 'diagnostics_channel'
|
||||
|
||||
diagnosticsChannel.channel('undici:client:beforeConnect').subscribe(({ connectParams, connector }) => {
|
||||
// const { host, hostname, protocol, port, servername } = connectParams
|
||||
// const { host, hostname, protocol, port, servername, version } = connectParams
|
||||
// connector is a function that creates the socket
|
||||
})
|
||||
```
|
||||
@@ -118,7 +118,7 @@ This message is published after a connection is established.
|
||||
import diagnosticsChannel from 'diagnostics_channel'
|
||||
|
||||
diagnosticsChannel.channel('undici:client:connected').subscribe(({ socket, connectParams, connector }) => {
|
||||
// const { host, hostname, protocol, port, servername } = connectParams
|
||||
// const { host, hostname, protocol, port, servername, version } = connectParams
|
||||
// connector is a function that creates the socket
|
||||
})
|
||||
```
|
||||
@@ -131,7 +131,7 @@ This message is published if it did not succeed to create new connection
|
||||
import diagnosticsChannel from 'diagnostics_channel'
|
||||
|
||||
diagnosticsChannel.channel('undici:client:connectError').subscribe(({ error, socket, connectParams, connector }) => {
|
||||
// const { host, hostname, protocol, port, servername } = connectParams
|
||||
// const { host, hostname, protocol, port, servername, version } = connectParams
|
||||
// connector is a function that creates the socket
|
||||
console.log(`Connect failed with ${error.message}`)
|
||||
})
|
||||
476
node_modules/undici/docs/api/Dispatcher.md → node_modules/undici/docs/docs/api/Dispatcher.md
generated
vendored
476
node_modules/undici/docs/api/Dispatcher.md → node_modules/undici/docs/docs/api/Dispatcher.md
generated
vendored
@@ -209,6 +209,7 @@ Returns: `Boolean` - `false` if dispatcher is busy and further dispatch calls wo
|
||||
* **onConnect** `(abort: () => void, context: object) => void` - Invoked before request is dispatched on socket. May be invoked multiple times when a request is retried when the request at the head of the pipeline fails.
|
||||
* **onError** `(error: Error) => void` - Invoked when an error has occurred. May not throw.
|
||||
* **onUpgrade** `(statusCode: number, headers: Buffer[], socket: Duplex) => void` (optional) - Invoked when request is upgraded. Required if `DispatchOptions.upgrade` is defined or `DispatchOptions.method === 'CONNECT'`.
|
||||
* **onResponseStarted** `() => void` (optional) - Invoked when response is received, before headers have been read.
|
||||
* **onHeaders** `(statusCode: number, headers: Buffer[], resume: () => void, statusText: string) => boolean` - Invoked when statusCode and headers have been received. May be invoked multiple times due to 1xx informational headers. Not required for `upgrade` requests.
|
||||
* **onData** `(chunk: Buffer) => boolean` - Invoked when response payload data is received. Not required for `upgrade` requests.
|
||||
* **onComplete** `(trailers: Buffer[]) => void` - Invoked when response payload and trailers have been received and the request has completed. Not required for `upgrade` requests.
|
||||
@@ -487,11 +488,13 @@ The `RequestOptions.method` property should not be value `'CONNECT'`.
|
||||
|
||||
`body` contains the following additional [body mixin](https://fetch.spec.whatwg.org/#body-mixin) methods and properties:
|
||||
|
||||
- `text()`
|
||||
- `json()`
|
||||
- `arrayBuffer()`
|
||||
- `body`
|
||||
- `bodyUsed`
|
||||
* [`.arrayBuffer()`](https://fetch.spec.whatwg.org/#dom-body-arraybuffer)
|
||||
* [`.blob()`](https://fetch.spec.whatwg.org/#dom-body-blob)
|
||||
* [`.bytes()`](https://fetch.spec.whatwg.org/#dom-body-bytes)
|
||||
* [`.json()`](https://fetch.spec.whatwg.org/#dom-body-json)
|
||||
* [`.text()`](https://fetch.spec.whatwg.org/#dom-body-text)
|
||||
* `body`
|
||||
* `bodyUsed`
|
||||
|
||||
`body` can not be consumed twice. For example, calling `text()` after `json()` throws `TypeError`.
|
||||
|
||||
@@ -816,6 +819,421 @@ try {
|
||||
}
|
||||
```
|
||||
|
||||
### `Dispatcher.compose(interceptors[, interceptor])`
|
||||
|
||||
Compose a new dispatcher from the current dispatcher and the given interceptors.
|
||||
|
||||
> _Notes_:
|
||||
> - The order of the interceptors matters. The first interceptor will be the first to be called.
|
||||
> - It is important to note that the `interceptor` function should return a function that follows the `Dispatcher.dispatch` signature.
|
||||
> - Any fork of the chain of `interceptors` can lead to unexpected results.
|
||||
|
||||
Arguments:
|
||||
|
||||
* **interceptors** `Interceptor[interceptor[]]`: It is an array of `Interceptor` functions passed as only argument, or several interceptors passed as separate arguments.
|
||||
|
||||
Returns: `Dispatcher`.
|
||||
|
||||
#### Parameter: `Interceptor`
|
||||
|
||||
A function that takes a `dispatch` method and returns a `dispatch`-like function.
|
||||
|
||||
#### Example 1 - Basic Compose
|
||||
|
||||
```js
|
||||
const { Client, RedirectHandler } = require('undici')
|
||||
|
||||
const redirectInterceptor = dispatch => {
|
||||
return (opts, handler) => {
|
||||
const { maxRedirections } = opts
|
||||
|
||||
if (!maxRedirections) {
|
||||
return dispatch(opts, handler)
|
||||
}
|
||||
|
||||
const redirectHandler = new RedirectHandler(
|
||||
dispatch,
|
||||
maxRedirections,
|
||||
opts,
|
||||
handler
|
||||
)
|
||||
opts = { ...opts, maxRedirections: 0 } // Stop sub dispatcher from also redirecting.
|
||||
return dispatch(opts, redirectHandler)
|
||||
}
|
||||
}
|
||||
|
||||
const client = new Client('http://localhost:3000')
|
||||
.compose(redirectInterceptor)
|
||||
|
||||
await client.request({ path: '/', method: 'GET' })
|
||||
```
|
||||
|
||||
#### Example 2 - Chained Compose
|
||||
|
||||
```js
|
||||
const { Client, RedirectHandler, RetryHandler } = require('undici')
|
||||
|
||||
const redirectInterceptor = dispatch => {
|
||||
return (opts, handler) => {
|
||||
const { maxRedirections } = opts
|
||||
|
||||
if (!maxRedirections) {
|
||||
return dispatch(opts, handler)
|
||||
}
|
||||
|
||||
const redirectHandler = new RedirectHandler(
|
||||
dispatch,
|
||||
maxRedirections,
|
||||
opts,
|
||||
handler
|
||||
)
|
||||
opts = { ...opts, maxRedirections: 0 }
|
||||
return dispatch(opts, redirectHandler)
|
||||
}
|
||||
}
|
||||
|
||||
const retryInterceptor = dispatch => {
|
||||
return function retryInterceptor (opts, handler) {
|
||||
return dispatch(
|
||||
opts,
|
||||
new RetryHandler(opts, {
|
||||
handler,
|
||||
dispatch
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const client = new Client('http://localhost:3000')
|
||||
.compose(redirectInterceptor)
|
||||
.compose(retryInterceptor)
|
||||
|
||||
await client.request({ path: '/', method: 'GET' })
|
||||
```
|
||||
|
||||
#### Pre-built interceptors
|
||||
|
||||
##### `redirect`
|
||||
|
||||
The `redirect` interceptor allows you to customize the way your dispatcher handles redirects.
|
||||
|
||||
It accepts the same arguments as the [`RedirectHandler` constructor](./RedirectHandler.md).
|
||||
|
||||
**Example - Basic Redirect Interceptor**
|
||||
|
||||
```js
|
||||
const { Client, interceptors } = require("undici");
|
||||
const { redirect } = interceptors;
|
||||
|
||||
const client = new Client("http://example.com").compose(
|
||||
redirect({ maxRedirections: 3, throwOnMaxRedirects: true })
|
||||
);
|
||||
client.request({ path: "/" })
|
||||
```
|
||||
|
||||
##### `retry`
|
||||
|
||||
The `retry` interceptor allows you to customize the way your dispatcher handles retries.
|
||||
|
||||
It accepts the same arguments as the [`RetryHandler` constructor](./RetryHandler.md).
|
||||
|
||||
**Example - Basic Redirect Interceptor**
|
||||
|
||||
```js
|
||||
const { Client, interceptors } = require("undici");
|
||||
const { retry } = interceptors;
|
||||
|
||||
const client = new Client("http://example.com").compose(
|
||||
retry({
|
||||
maxRetries: 3,
|
||||
minTimeout: 1000,
|
||||
maxTimeout: 10000,
|
||||
timeoutFactor: 2,
|
||||
retryAfter: true,
|
||||
})
|
||||
);
|
||||
```
|
||||
|
||||
##### `dump`
|
||||
|
||||
The `dump` interceptor enables you to dump the response body from a request upon a given limit.
|
||||
|
||||
**Options**
|
||||
- `maxSize` - The maximum size (in bytes) of the response body to dump. If the size of the request's body exceeds this value then the connection will be closed. Default: `1048576`.
|
||||
|
||||
> The `Dispatcher#options` also gets extended with the options `dumpMaxSize`, `abortOnDumped`, and `waitForTrailers` which can be used to configure the interceptor at a request-per-request basis.
|
||||
|
||||
**Example - Basic Dump Interceptor**
|
||||
|
||||
```js
|
||||
const { Client, interceptors } = require("undici");
|
||||
const { dump } = interceptors;
|
||||
|
||||
const client = new Client("http://example.com").compose(
|
||||
dump({
|
||||
maxSize: 1024,
|
||||
})
|
||||
);
|
||||
|
||||
// or
|
||||
client.dispatch(
|
||||
{
|
||||
path: "/",
|
||||
method: "GET",
|
||||
dumpMaxSize: 1024,
|
||||
},
|
||||
handler
|
||||
);
|
||||
```
|
||||
|
||||
##### `dns`
|
||||
|
||||
The `dns` interceptor enables you to cache DNS lookups for a given duration, per origin.
|
||||
|
||||
>It is well suited for scenarios where you want to cache DNS lookups to avoid the overhead of resolving the same domain multiple times
|
||||
|
||||
**Options**
|
||||
- `maxTTL` - The maximum time-to-live (in milliseconds) of the DNS cache. It should be a positive integer. Default: `10000`.
|
||||
- Set `0` to disable TTL.
|
||||
- `maxItems` - The maximum number of items to cache. It should be a positive integer. Default: `Infinity`.
|
||||
- `dualStack` - Whether to resolve both IPv4 and IPv6 addresses. Default: `true`.
|
||||
- It will also attempt a happy-eyeballs-like approach to connect to the available addresses in case of a connection failure.
|
||||
- `affinity` - Whether to use IPv4 or IPv6 addresses. Default: `4`.
|
||||
- It can be either `'4` or `6`.
|
||||
- It will only take effect if `dualStack` is `false`.
|
||||
- `lookup: (hostname: string, options: LookupOptions, callback: (err: NodeJS.ErrnoException | null, addresses: DNSInterceptorRecord[]) => void) => void` - Custom lookup function. Default: `dns.lookup`.
|
||||
- For more info see [dns.lookup](https://nodejs.org/api/dns.html#dns_dns_lookup_hostname_options_callback).
|
||||
- `pick: (origin: URL, records: DNSInterceptorRecords, affinity: 4 | 6) => DNSInterceptorRecord` - Custom pick function. Default: `RoundRobin`.
|
||||
- The function should return a single record from the records array.
|
||||
- By default a simplified version of Round Robin is used.
|
||||
- The `records` property can be mutated to store the state of the balancing algorithm.
|
||||
|
||||
> The `Dispatcher#options` also gets extended with the options `dns.affinity`, `dns.dualStack`, `dns.lookup` and `dns.pick` which can be used to configure the interceptor at a request-per-request basis.
|
||||
|
||||
|
||||
**DNSInterceptorRecord**
|
||||
It represents a DNS record.
|
||||
- `family` - (`number`) The IP family of the address. It can be either `4` or `6`.
|
||||
- `address` - (`string`) The IP address.
|
||||
|
||||
**DNSInterceptorOriginRecords**
|
||||
It represents a map of DNS IP addresses records for a single origin.
|
||||
- `4.ips` - (`DNSInterceptorRecord[] | null`) The IPv4 addresses.
|
||||
- `6.ips` - (`DNSInterceptorRecord[] | null`) The IPv6 addresses.
|
||||
|
||||
**Example - Basic DNS Interceptor**
|
||||
|
||||
```js
|
||||
const { Client, interceptors } = require("undici");
|
||||
const { dns } = interceptors;
|
||||
|
||||
const client = new Agent().compose([
|
||||
dns({ ...opts })
|
||||
])
|
||||
|
||||
const response = await client.request({
|
||||
origin: `http://localhost:3030`,
|
||||
...requestOpts
|
||||
})
|
||||
```
|
||||
|
||||
##### `Response Error Interceptor`
|
||||
|
||||
**Introduction**
|
||||
|
||||
The Response Error Interceptor is designed to handle HTTP response errors efficiently. It intercepts responses and throws detailed errors for responses with status codes indicating failure (4xx, 5xx). This interceptor enhances error handling by providing structured error information, including response headers, data, and status codes.
|
||||
|
||||
**ResponseError Class**
|
||||
|
||||
The `ResponseError` class extends the `UndiciError` class and encapsulates detailed error information. It captures the response status code, headers, and data, providing a structured way to handle errors.
|
||||
|
||||
**Definition**
|
||||
|
||||
```js
|
||||
class ResponseError extends UndiciError {
|
||||
constructor (message, code, { headers, data }) {
|
||||
super(message);
|
||||
this.name = 'ResponseError';
|
||||
this.message = message || 'Response error';
|
||||
this.code = 'UND_ERR_RESPONSE';
|
||||
this.statusCode = code;
|
||||
this.data = data;
|
||||
this.headers = headers;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Interceptor Handler**
|
||||
|
||||
The interceptor's handler class extends `DecoratorHandler` and overrides methods to capture response details and handle errors based on the response status code.
|
||||
|
||||
**Methods**
|
||||
|
||||
- **onConnect**: Initializes response properties.
|
||||
- **onHeaders**: Captures headers and status code. Decodes body if content type is `application/json` or `text/plain`.
|
||||
- **onData**: Appends chunks to the body if status code indicates an error.
|
||||
- **onComplete**: Finalizes error handling, constructs a `ResponseError`, and invokes the `onError` method.
|
||||
- **onError**: Propagates errors to the handler.
|
||||
|
||||
**Definition**
|
||||
|
||||
```js
|
||||
class Handler extends DecoratorHandler {
|
||||
// Private properties
|
||||
#handler;
|
||||
#statusCode;
|
||||
#contentType;
|
||||
#decoder;
|
||||
#headers;
|
||||
#body;
|
||||
|
||||
constructor (opts, { handler }) {
|
||||
super(handler);
|
||||
this.#handler = handler;
|
||||
}
|
||||
|
||||
onConnect (abort) {
|
||||
this.#statusCode = 0;
|
||||
this.#contentType = null;
|
||||
this.#decoder = null;
|
||||
this.#headers = null;
|
||||
this.#body = '';
|
||||
return this.#handler.onConnect(abort);
|
||||
}
|
||||
|
||||
onHeaders (statusCode, rawHeaders, resume, statusMessage, headers = parseHeaders(rawHeaders)) {
|
||||
this.#statusCode = statusCode;
|
||||
this.#headers = headers;
|
||||
this.#contentType = headers['content-type'];
|
||||
|
||||
if (this.#statusCode < 400) {
|
||||
return this.#handler.onHeaders(statusCode, rawHeaders, resume, statusMessage, headers);
|
||||
}
|
||||
|
||||
if (this.#contentType === 'application/json' || this.#contentType === 'text/plain') {
|
||||
this.#decoder = new TextDecoder('utf-8');
|
||||
}
|
||||
}
|
||||
|
||||
onData (chunk) {
|
||||
if (this.#statusCode < 400) {
|
||||
return this.#handler.onData(chunk);
|
||||
}
|
||||
this.#body += this.#decoder?.decode(chunk, { stream: true }) ?? '';
|
||||
}
|
||||
|
||||
onComplete (rawTrailers) {
|
||||
if (this.#statusCode >= 400) {
|
||||
this.#body += this.#decoder?.decode(undefined, { stream: false }) ?? '';
|
||||
if (this.#contentType === 'application/json') {
|
||||
try {
|
||||
this.#body = JSON.parse(this.#body);
|
||||
} catch {
|
||||
// Do nothing...
|
||||
}
|
||||
}
|
||||
|
||||
let err;
|
||||
const stackTraceLimit = Error.stackTraceLimit;
|
||||
Error.stackTraceLimit = 0;
|
||||
try {
|
||||
err = new ResponseError('Response Error', this.#statusCode, this.#headers, this.#body);
|
||||
} finally {
|
||||
Error.stackTraceLimit = stackTraceLimit;
|
||||
}
|
||||
|
||||
this.#handler.onError(err);
|
||||
} else {
|
||||
this.#handler.onComplete(rawTrailers);
|
||||
}
|
||||
}
|
||||
|
||||
onError (err) {
|
||||
this.#handler.onError(err);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = (dispatch) => (opts, handler) => opts.throwOnError
|
||||
? dispatch(opts, new Handler(opts, { handler }))
|
||||
: dispatch(opts, handler);
|
||||
```
|
||||
|
||||
**Tests**
|
||||
|
||||
Unit tests ensure the interceptor functions correctly, handling both error and non-error responses appropriately.
|
||||
|
||||
**Example Tests**
|
||||
|
||||
- **No Error if `throwOnError` is False**:
|
||||
|
||||
```js
|
||||
test('should not error if request is not meant to throw error', async (t) => {
|
||||
const opts = { throwOnError: false };
|
||||
const handler = { onError: () => {}, onData: () => {}, onComplete: () => {} };
|
||||
const interceptor = createResponseErrorInterceptor((opts, handler) => handler.onComplete());
|
||||
assert.doesNotThrow(() => interceptor(opts, handler));
|
||||
});
|
||||
```
|
||||
|
||||
- **Error if Status Code is in Specified Error Codes**:
|
||||
|
||||
```js
|
||||
test('should error if request status code is in the specified error codes', async (t) => {
|
||||
const opts = { throwOnError: true, statusCodes: [500] };
|
||||
const response = { statusCode: 500 };
|
||||
let capturedError;
|
||||
const handler = {
|
||||
onError: (err) => { capturedError = err; },
|
||||
onData: () => {},
|
||||
onComplete: () => {}
|
||||
};
|
||||
|
||||
const interceptor = createResponseErrorInterceptor((opts, handler) => {
|
||||
if (opts.throwOnError && opts.statusCodes.includes(response.statusCode)) {
|
||||
handler.onError(new Error('Response Error'));
|
||||
} else {
|
||||
handler.onComplete();
|
||||
}
|
||||
});
|
||||
|
||||
interceptor({ ...opts, response }, handler);
|
||||
|
||||
await new Promise(resolve => setImmediate(resolve));
|
||||
|
||||
assert(capturedError, 'Expected error to be captured but it was not.');
|
||||
assert.strictEqual(capturedError.message, 'Response Error');
|
||||
assert.strictEqual(response.statusCode, 500);
|
||||
});
|
||||
```
|
||||
|
||||
- **No Error if Status Code is Not in Specified Error Codes**:
|
||||
|
||||
```js
|
||||
test('should not error if request status code is not in the specified error codes', async (t) => {
|
||||
const opts = { throwOnError: true, statusCodes: [500] };
|
||||
const response = { statusCode: 404 };
|
||||
const handler = {
|
||||
onError: () => {},
|
||||
onData: () => {},
|
||||
onComplete: () => {}
|
||||
};
|
||||
|
||||
const interceptor = createResponseErrorInterceptor((opts, handler) => {
|
||||
if (opts.throwOnError && opts.statusCodes.includes(response.statusCode)) {
|
||||
handler.onError(new Error('Response Error'));
|
||||
} else {
|
||||
handler.onComplete();
|
||||
}
|
||||
});
|
||||
|
||||
assert.doesNotThrow(() => interceptor({ ...opts, response }, handler));
|
||||
});
|
||||
```
|
||||
|
||||
**Conclusion**
|
||||
|
||||
The Response Error Interceptor provides a robust mechanism for handling HTTP response errors by capturing detailed error information and propagating it through a structured `ResponseError` class. This enhancement improves error handling and debugging capabilities in applications using the interceptor.
|
||||
|
||||
## Instance Events
|
||||
|
||||
### Event: `'connect'`
|
||||
@@ -833,6 +1251,12 @@ Parameters:
|
||||
* **targets** `Array<Dispatcher>`
|
||||
* **error** `Error`
|
||||
|
||||
Emitted when the dispatcher has been disconnected from the origin.
|
||||
|
||||
> **Note**: For HTTP/2, this event is also emitted when the dispatcher has received the [GOAWAY Frame](https://webconcepts.info/concepts/http2-frame-type/0x7) with an Error with the message `HTTP/2: "GOAWAY" frame received` and the code `UND_ERR_INFO`.
|
||||
> Due to nature of the protocol of using binary frames, it is possible that requests gets hanging as a frame can be received between the `HEADER` and `DATA` frames.
|
||||
> It is recommended to handle this event and close the dispatcher to create a new HTTP/2 session.
|
||||
|
||||
### Event: `'connectionError'`
|
||||
|
||||
Parameters:
|
||||
@@ -854,10 +1278,12 @@ Emitted when dispatcher is no longer busy.
|
||||
|
||||
## Parameter: `UndiciHeaders`
|
||||
|
||||
* `Record<string, string | string[] | undefined> | string[] | null`
|
||||
|
||||
Header arguments such as `options.headers` in [`Client.dispatch`](Client.md#clientdispatchoptions-handlers) can be specified in two forms; either as an object specified by the `Record<string, string | string[] | undefined>` (`IncomingHttpHeaders`) type, or an array of strings. An array representation of a header list must have an even length or an `InvalidArgumentError` will be thrown.
|
||||
* `Record<string, string | string[] | undefined> | string[] | Iterable<[string, string | string[] | undefined]> | null`
|
||||
|
||||
Header arguments such as `options.headers` in [`Client.dispatch`](Client.md#clientdispatchoptions-handlers) can be specified in three forms:
|
||||
* As an object specified by the `Record<string, string | string[] | undefined>` (`IncomingHttpHeaders`) type.
|
||||
* As an array of strings. An array representation of a header list must have an even length, or an `InvalidArgumentError` will be thrown.
|
||||
* As an iterable that can encompass `Headers`, `Map`, or a custom iterator returning key-value pairs.
|
||||
Keys are lowercase and values are not modified.
|
||||
|
||||
Response headers will derive a `host` from the `url` of the [Client](Client.md#class-client) instance if no `host` header was previously specified.
|
||||
@@ -885,3 +1311,37 @@ Response headers will derive a `host` from the `url` of the [Client](Client.md#c
|
||||
'accept', '*/*'
|
||||
]
|
||||
```
|
||||
|
||||
### Example 3 - Iterable
|
||||
|
||||
```js
|
||||
new Headers({
|
||||
'content-length': '123',
|
||||
'content-type': 'text/plain',
|
||||
connection: 'keep-alive',
|
||||
host: 'mysite.com',
|
||||
accept: '*/*'
|
||||
})
|
||||
```
|
||||
or
|
||||
```js
|
||||
new Map([
|
||||
['content-length', '123'],
|
||||
['content-type', 'text/plain'],
|
||||
['connection', 'keep-alive'],
|
||||
['host', 'mysite.com'],
|
||||
['accept', '*/*']
|
||||
])
|
||||
```
|
||||
or
|
||||
```js
|
||||
{
|
||||
*[Symbol.iterator] () {
|
||||
yield ['content-length', '123']
|
||||
yield ['content-type', 'text/plain']
|
||||
yield ['connection', 'keep-alive']
|
||||
yield ['host', 'mysite.com']
|
||||
yield ['accept', '*/*']
|
||||
}
|
||||
}
|
||||
```
|
||||
162
node_modules/undici/docs/docs/api/EnvHttpProxyAgent.md
generated
vendored
Normal file
162
node_modules/undici/docs/docs/api/EnvHttpProxyAgent.md
generated
vendored
Normal file
@@ -0,0 +1,162 @@
|
||||
# Class: EnvHttpProxyAgent
|
||||
|
||||
Stability: Experimental.
|
||||
|
||||
Extends: `undici.Dispatcher`
|
||||
|
||||
EnvHttpProxyAgent automatically reads the proxy configuration from the environment variables `http_proxy`, `https_proxy`, and `no_proxy` and sets up the proxy agents accordingly. When `http_proxy` and `https_proxy` are set, `http_proxy` is used for HTTP requests and `https_proxy` is used for HTTPS requests. If only `http_proxy` is set, `http_proxy` is used for both HTTP and HTTPS requests. If only `https_proxy` is set, it is only used for HTTPS requests.
|
||||
|
||||
`no_proxy` is a comma or space-separated list of hostnames that should not be proxied. The list may contain leading wildcard characters (`*`). If `no_proxy` is set, the EnvHttpProxyAgent will bypass the proxy for requests to hosts that match the list. If `no_proxy` is set to `"*"`, the EnvHttpProxyAgent will bypass the proxy for all requests.
|
||||
|
||||
Uppercase environment variables are also supported: `HTTP_PROXY`, `HTTPS_PROXY`, and `NO_PROXY`. However, if both the lowercase and uppercase environment variables are set, the uppercase environment variables will be ignored.
|
||||
|
||||
## `new EnvHttpProxyAgent([options])`
|
||||
|
||||
Arguments:
|
||||
|
||||
* **options** `EnvHttpProxyAgentOptions` (optional) - extends the `Agent` options.
|
||||
|
||||
Returns: `EnvHttpProxyAgent`
|
||||
|
||||
### Parameter: `EnvHttpProxyAgentOptions`
|
||||
|
||||
Extends: [`AgentOptions`](Agent.md#parameter-agentoptions)
|
||||
|
||||
* **httpProxy** `string` (optional) - When set, it will override the `HTTP_PROXY` environment variable.
|
||||
* **httpsProxy** `string` (optional) - When set, it will override the `HTTPS_PROXY` environment variable.
|
||||
* **noProxy** `string` (optional) - When set, it will override the `NO_PROXY` environment variable.
|
||||
|
||||
Examples:
|
||||
|
||||
```js
|
||||
import { EnvHttpProxyAgent } from 'undici'
|
||||
|
||||
const envHttpProxyAgent = new EnvHttpProxyAgent()
|
||||
// or
|
||||
const envHttpProxyAgent = new EnvHttpProxyAgent({ httpProxy: 'my.proxy.server:8080', httpsProxy: 'my.proxy.server:8443', noProxy: 'localhost' })
|
||||
```
|
||||
|
||||
#### Example - EnvHttpProxyAgent instantiation
|
||||
|
||||
This will instantiate the EnvHttpProxyAgent. It will not do anything until registered as the agent to use with requests.
|
||||
|
||||
```js
|
||||
import { EnvHttpProxyAgent } from 'undici'
|
||||
|
||||
const envHttpProxyAgent = new EnvHttpProxyAgent()
|
||||
```
|
||||
|
||||
#### Example - Basic Proxy Fetch with global agent dispatcher
|
||||
|
||||
```js
|
||||
import { setGlobalDispatcher, fetch, EnvHttpProxyAgent } from 'undici'
|
||||
|
||||
const envHttpProxyAgent = new EnvHttpProxyAgent()
|
||||
setGlobalDispatcher(envHttpProxyAgent)
|
||||
|
||||
const { status, json } = await fetch('http://localhost:3000/foo')
|
||||
|
||||
console.log('response received', status) // response received 200
|
||||
|
||||
const data = await json() // data { foo: "bar" }
|
||||
```
|
||||
|
||||
#### Example - Basic Proxy Request with global agent dispatcher
|
||||
|
||||
```js
|
||||
import { setGlobalDispatcher, request, EnvHttpProxyAgent } from 'undici'
|
||||
|
||||
const envHttpProxyAgent = new EnvHttpProxyAgent()
|
||||
setGlobalDispatcher(envHttpProxyAgent)
|
||||
|
||||
const { statusCode, body } = await request('http://localhost:3000/foo')
|
||||
|
||||
console.log('response received', statusCode) // response received 200
|
||||
|
||||
for await (const data of body) {
|
||||
console.log('data', data.toString('utf8')) // data foo
|
||||
}
|
||||
```
|
||||
|
||||
#### Example - Basic Proxy Request with local agent dispatcher
|
||||
|
||||
```js
|
||||
import { EnvHttpProxyAgent, request } from 'undici'
|
||||
|
||||
const envHttpProxyAgent = new EnvHttpProxyAgent()
|
||||
|
||||
const {
|
||||
statusCode,
|
||||
body
|
||||
} = await request('http://localhost:3000/foo', { dispatcher: envHttpProxyAgent })
|
||||
|
||||
console.log('response received', statusCode) // response received 200
|
||||
|
||||
for await (const data of body) {
|
||||
console.log('data', data.toString('utf8')) // data foo
|
||||
}
|
||||
```
|
||||
|
||||
#### Example - Basic Proxy Fetch with local agent dispatcher
|
||||
|
||||
```js
|
||||
import { EnvHttpProxyAgent, fetch } from 'undici'
|
||||
|
||||
const envHttpProxyAgent = new EnvHttpProxyAgent()
|
||||
|
||||
const {
|
||||
status,
|
||||
json
|
||||
} = await fetch('http://localhost:3000/foo', { dispatcher: envHttpProxyAgent })
|
||||
|
||||
console.log('response received', status) // response received 200
|
||||
|
||||
const data = await json() // data { foo: "bar" }
|
||||
```
|
||||
|
||||
## Instance Methods
|
||||
|
||||
### `EnvHttpProxyAgent.close([callback])`
|
||||
|
||||
Implements [`Dispatcher.close([callback])`](Dispatcher.md#dispatcherclosecallback-promise).
|
||||
|
||||
### `EnvHttpProxyAgent.destroy([error, callback])`
|
||||
|
||||
Implements [`Dispatcher.destroy([error, callback])`](Dispatcher.md#dispatcherdestroyerror-callback-promise).
|
||||
|
||||
### `EnvHttpProxyAgent.dispatch(options, handler: AgentDispatchOptions)`
|
||||
|
||||
Implements [`Dispatcher.dispatch(options, handler)`](Dispatcher.md#dispatcherdispatchoptions-handler).
|
||||
|
||||
#### Parameter: `AgentDispatchOptions`
|
||||
|
||||
Extends: [`DispatchOptions`](Dispatcher.md#parameter-dispatchoptions)
|
||||
|
||||
* **origin** `string | URL`
|
||||
* **maxRedirections** `Integer`.
|
||||
|
||||
Implements [`Dispatcher.destroy([error, callback])`](Dispatcher.md#dispatcherdestroyerror-callback-promise).
|
||||
|
||||
### `EnvHttpProxyAgent.connect(options[, callback])`
|
||||
|
||||
See [`Dispatcher.connect(options[, callback])`](Dispatcher.md#dispatcherconnectoptions-callback).
|
||||
|
||||
### `EnvHttpProxyAgent.dispatch(options, handler)`
|
||||
|
||||
Implements [`Dispatcher.dispatch(options, handler)`](Dispatcher.md#dispatcherdispatchoptions-handler).
|
||||
|
||||
### `EnvHttpProxyAgent.pipeline(options, handler)`
|
||||
|
||||
See [`Dispatcher.pipeline(options, handler)`](Dispatcher.md#dispatcherpipelineoptions-handler).
|
||||
|
||||
### `EnvHttpProxyAgent.request(options[, callback])`
|
||||
|
||||
See [`Dispatcher.request(options [, callback])`](Dispatcher.md#dispatcherrequestoptions-callback).
|
||||
|
||||
### `EnvHttpProxyAgent.stream(options, factory[, callback])`
|
||||
|
||||
See [`Dispatcher.stream(options, factory[, callback])`](Dispatcher.md#dispatcherstreamoptions-factory-callback).
|
||||
|
||||
### `EnvHttpProxyAgent.upgrade(options[, callback])`
|
||||
|
||||
See [`Dispatcher.upgrade(options[, callback])`](Dispatcher.md#dispatcherupgradeoptions-callback).
|
||||
1
node_modules/undici/docs/api/Errors.md → node_modules/undici/docs/docs/api/Errors.md
generated
vendored
1
node_modules/undici/docs/api/Errors.md → node_modules/undici/docs/docs/api/Errors.md
generated
vendored
@@ -26,6 +26,7 @@ import { errors } from 'undici'
|
||||
| `ResponseContentLengthMismatchError` | `UND_ERR_RES_CONTENT_LENGTH_MISMATCH` | response body does not match content-length header |
|
||||
| `InformationalError` | `UND_ERR_INFO` | expected error with reason |
|
||||
| `ResponseExceededMaxSizeError` | `UND_ERR_RES_EXCEEDED_MAX_SIZE` | response body exceed the max size allowed |
|
||||
| `SecureProxyConnectionError` | `UND_ERR_PRX_TLS` | tls connection to a proxy failed |
|
||||
|
||||
### `SocketError`
|
||||
|
||||
45
node_modules/undici/docs/docs/api/EventSource.md
generated
vendored
Normal file
45
node_modules/undici/docs/docs/api/EventSource.md
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
# EventSource
|
||||
|
||||
> ⚠️ Warning: the EventSource API is experimental.
|
||||
|
||||
Undici exposes a WHATWG spec-compliant implementation of [EventSource](https://developer.mozilla.org/en-US/docs/Web/API/EventSource)
|
||||
for [Server-Sent Events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events).
|
||||
|
||||
## Instantiating EventSource
|
||||
|
||||
Undici exports a EventSource class. You can instantiate the EventSource as
|
||||
follows:
|
||||
|
||||
```mjs
|
||||
import { EventSource } from 'undici'
|
||||
|
||||
const eventSource = new EventSource('http://localhost:3000')
|
||||
eventSource.onmessage = (event) => {
|
||||
console.log(event.data)
|
||||
}
|
||||
```
|
||||
|
||||
## Using a custom Dispatcher
|
||||
|
||||
undici allows you to set your own Dispatcher in the EventSource constructor.
|
||||
|
||||
An example which allows you to modify the request headers is:
|
||||
|
||||
```mjs
|
||||
import { EventSource, Agent } from 'undici'
|
||||
|
||||
class CustomHeaderAgent extends Agent {
|
||||
dispatch (opts) {
|
||||
opts.headers['x-custom-header'] = 'hello world'
|
||||
return super.dispatch(...arguments)
|
||||
}
|
||||
}
|
||||
|
||||
const eventSource = new EventSource('http://localhost:3000', {
|
||||
dispatcher: new CustomHeaderAgent()
|
||||
})
|
||||
|
||||
```
|
||||
|
||||
More information about the EventSource API can be found on
|
||||
[MDN](https://developer.mozilla.org/en-US/docs/Web/API/EventSource).
|
||||
52
node_modules/undici/docs/docs/api/Fetch.md
generated
vendored
Normal file
52
node_modules/undici/docs/docs/api/Fetch.md
generated
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
# Fetch
|
||||
|
||||
Undici exposes a fetch() method starts the process of fetching a resource from the network.
|
||||
|
||||
Documentation and examples can be found on [MDN](https://developer.mozilla.org/en-US/docs/Web/API/fetch).
|
||||
|
||||
## FormData
|
||||
|
||||
This API is implemented as per the standard, you can find documentation on [MDN](https://developer.mozilla.org/en-US/docs/Web/API/FormData).
|
||||
|
||||
If any parameters are passed to the FormData constructor other than `undefined`, an error will be thrown. Other parameters are ignored.
|
||||
|
||||
## Response
|
||||
|
||||
This API is implemented as per the standard, you can find documentation on [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Response)
|
||||
|
||||
## Request
|
||||
|
||||
This API is implemented as per the standard, you can find documentation on [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Request)
|
||||
|
||||
## Header
|
||||
|
||||
This API is implemented as per the standard, you can find documentation on [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Headers)
|
||||
|
||||
# Body Mixins
|
||||
|
||||
`Response` and `Request` body inherit body mixin methods. These methods include:
|
||||
|
||||
- [`.arrayBuffer()`](https://fetch.spec.whatwg.org/#dom-body-arraybuffer)
|
||||
- [`.blob()`](https://fetch.spec.whatwg.org/#dom-body-blob)
|
||||
- [`.bytes()`](https://fetch.spec.whatwg.org/#dom-body-bytes)
|
||||
- [`.formData()`](https://fetch.spec.whatwg.org/#dom-body-formdata)
|
||||
- [`.json()`](https://fetch.spec.whatwg.org/#dom-body-json)
|
||||
- [`.text()`](https://fetch.spec.whatwg.org/#dom-body-text)
|
||||
|
||||
There is an ongoing discussion regarding `.formData()` and its usefulness and performance in server environments. It is recommended to use a dedicated library for parsing `multipart/form-data` bodies, such as [Busboy](https://www.npmjs.com/package/busboy) or [@fastify/busboy](https://www.npmjs.com/package/@fastify/busboy).
|
||||
|
||||
These libraries can be interfaced with fetch with the following example code:
|
||||
|
||||
```mjs
|
||||
import { Busboy } from '@fastify/busboy'
|
||||
import { Readable } from 'node:stream'
|
||||
|
||||
const response = await fetch('...')
|
||||
const busboy = new Busboy({
|
||||
headers: {
|
||||
'content-type': response.headers.get('content-type')
|
||||
}
|
||||
})
|
||||
|
||||
Readable.fromWeb(response.body).pipe(busboy)
|
||||
```
|
||||
0
node_modules/undici/docs/api/Pool.md → node_modules/undici/docs/docs/api/Pool.md
generated
vendored
0
node_modules/undici/docs/api/Pool.md → node_modules/undici/docs/docs/api/Pool.md
generated
vendored
@@ -16,12 +16,15 @@ Returns: `ProxyAgent`
|
||||
|
||||
Extends: [`AgentOptions`](Agent.md#parameter-agentoptions)
|
||||
|
||||
* **uri** `string` (required) - It can be passed either by a string or a object containing `uri` as string.
|
||||
* **uri** `string | URL` (required) - The URI of the proxy server. This can be provided as a string, as an instance of the URL class, or as an object with a `uri` property of type string.
|
||||
If the `uri` is provided as a string or `uri` is an object with an `uri` property of type string, then it will be parsed into a `URL` object according to the [WHATWG URL Specification](https://url.spec.whatwg.org).
|
||||
For detailed information on the parsing process and potential validation errors, please refer to the ["Writing" section](https://url.spec.whatwg.org/#writing) of the WHATWG URL Specification.
|
||||
* **token** `string` (optional) - It can be passed by a string of token for authentication.
|
||||
* **auth** `string` (**deprecated**) - Use token.
|
||||
* **clientFactory** `(origin: URL, opts: Object) => Dispatcher` (optional) - Default: `(origin, opts) => new Pool(origin, opts)`
|
||||
* **requestTls** `BuildOptions` (optional) - Options object passed when creating the underlying socket via the connector builder for the request. See [TLS](https://nodejs.org/api/tls.html#tlsconnectoptions-callback).
|
||||
* **proxyTls** `BuildOptions` (optional) - Options object passed when creating the underlying socket via the connector builder for the proxy server. See [TLS](https://nodejs.org/api/tls.html#tlsconnectoptions-callback).
|
||||
* **requestTls** `BuildOptions` (optional) - Options object passed when creating the underlying socket via the connector builder for the request. It extends from [`Client#ConnectOptions`](/docs/docs/api/Client.md#parameter-connectoptions).
|
||||
* **proxyTls** `BuildOptions` (optional) - Options object passed when creating the underlying socket via the connector builder for the proxy server. It extends from [`Client#ConnectOptions`](/docs/docs/api/Client.md#parameter-connectoptions).
|
||||
* **proxyTunnel** `boolean` (optional) - For connections involving secure protocols, Undici will always establish a tunnel via the HTTP2 CONNECT extension. If proxyTunnel is set to true, this will occur for unsecured proxy/endpoint connections as well. Currently, there is no way to facilitate HTTP1 IP tunneling as described in https://www.rfc-editor.org/rfc/rfc9484.html#name-http-11-request. If proxyTunnel is set to false (the default), ProxyAgent connections where both the Proxy and Endpoint are unsecured will issue all requests to the Proxy, and prefix the endpoint request path with the endpoint origin address.
|
||||
|
||||
Examples:
|
||||
|
||||
@@ -30,6 +33,8 @@ import { ProxyAgent } from 'undici'
|
||||
|
||||
const proxyAgent = new ProxyAgent('my.proxy.server')
|
||||
// or
|
||||
const proxyAgent = new ProxyAgent(new URL('my.proxy.server'))
|
||||
// or
|
||||
const proxyAgent = new ProxyAgent({ uri: 'my.proxy.server' })
|
||||
```
|
||||
|
||||
96
node_modules/undici/docs/docs/api/RedirectHandler.md
generated
vendored
Normal file
96
node_modules/undici/docs/docs/api/RedirectHandler.md
generated
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
# Class: RedirectHandler
|
||||
|
||||
A class that handles redirection logic for HTTP requests.
|
||||
|
||||
## `new RedirectHandler(dispatch, maxRedirections, opts, handler, redirectionLimitReached)`
|
||||
|
||||
Arguments:
|
||||
|
||||
- **dispatch** `function` - The dispatch function to be called after every retry.
|
||||
- **maxRedirections** `number` - Maximum number of redirections allowed.
|
||||
- **opts** `object` - Options for handling redirection.
|
||||
- **handler** `object` - An object containing handlers for different stages of the request lifecycle.
|
||||
- **redirectionLimitReached** `boolean` (default: `false`) - A flag that the implementer can provide to enable or disable the feature. If set to `false`, it indicates that the caller doesn't want to use the feature and prefers the old behavior.
|
||||
|
||||
Returns: `RedirectHandler`
|
||||
|
||||
### Parameters
|
||||
|
||||
- **dispatch** `(options: Dispatch.DispatchOptions, handlers: Dispatch.DispatchHandlers) => Promise<Dispatch.DispatchResponse>` (required) - Dispatch function to be called after every redirection.
|
||||
- **maxRedirections** `number` (required) - Maximum number of redirections allowed.
|
||||
- **opts** `object` (required) - Options for handling redirection.
|
||||
- **handler** `object` (required) - Handlers for different stages of the request lifecycle.
|
||||
- **redirectionLimitReached** `boolean` (default: `false`) - A flag that the implementer can provide to enable or disable the feature. If set to `false`, it indicates that the caller doesn't want to use the feature and prefers the old behavior.
|
||||
|
||||
### Properties
|
||||
|
||||
- **location** `string` - The current redirection location.
|
||||
- **abort** `function` - The abort function.
|
||||
- **opts** `object` - The options for handling redirection.
|
||||
- **maxRedirections** `number` - Maximum number of redirections allowed.
|
||||
- **handler** `object` - Handlers for different stages of the request lifecycle.
|
||||
- **history** `Array` - An array representing the history of URLs during redirection.
|
||||
- **redirectionLimitReached** `boolean` - Indicates whether the redirection limit has been reached.
|
||||
|
||||
### Methods
|
||||
|
||||
#### `onConnect(abort)`
|
||||
|
||||
Called when the connection is established.
|
||||
|
||||
Parameters:
|
||||
|
||||
- **abort** `function` - The abort function.
|
||||
|
||||
#### `onUpgrade(statusCode, headers, socket)`
|
||||
|
||||
Called when an upgrade is requested.
|
||||
|
||||
Parameters:
|
||||
|
||||
- **statusCode** `number` - The HTTP status code.
|
||||
- **headers** `object` - The headers received in the response.
|
||||
- **socket** `object` - The socket object.
|
||||
|
||||
#### `onError(error)`
|
||||
|
||||
Called when an error occurs.
|
||||
|
||||
Parameters:
|
||||
|
||||
- **error** `Error` - The error that occurred.
|
||||
|
||||
#### `onHeaders(statusCode, headers, resume, statusText)`
|
||||
|
||||
Called when headers are received.
|
||||
|
||||
Parameters:
|
||||
|
||||
- **statusCode** `number` - The HTTP status code.
|
||||
- **headers** `object` - The headers received in the response.
|
||||
- **resume** `function` - The resume function.
|
||||
- **statusText** `string` - The status text.
|
||||
|
||||
#### `onData(chunk)`
|
||||
|
||||
Called when data is received.
|
||||
|
||||
Parameters:
|
||||
|
||||
- **chunk** `Buffer` - The data chunk received.
|
||||
|
||||
#### `onComplete(trailers)`
|
||||
|
||||
Called when the request is complete.
|
||||
|
||||
Parameters:
|
||||
|
||||
- **trailers** `object` - The trailers received.
|
||||
|
||||
#### `onBodySent(chunk)`
|
||||
|
||||
Called when the request body is sent.
|
||||
|
||||
Parameters:
|
||||
|
||||
- **chunk** `Buffer` - The chunk of the request body sent.
|
||||
45
node_modules/undici/docs/docs/api/RetryAgent.md
generated
vendored
Normal file
45
node_modules/undici/docs/docs/api/RetryAgent.md
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
# Class: RetryAgent
|
||||
|
||||
Extends: `undici.Dispatcher`
|
||||
|
||||
A `undici.Dispatcher` that allows to automatically retry a request.
|
||||
Wraps a `undici.RetryHandler`.
|
||||
|
||||
## `new RetryAgent(dispatcher, [options])`
|
||||
|
||||
Arguments:
|
||||
|
||||
* **dispatcher** `undici.Dispatcher` (required) - the dispatcher to wrap
|
||||
* **options** `RetryHandlerOptions` (optional) - the options
|
||||
|
||||
Returns: `ProxyAgent`
|
||||
|
||||
### Parameter: `RetryHandlerOptions`
|
||||
|
||||
- **retry** `(err: Error, context: RetryContext, callback: (err?: Error | null) => void) => void` (optional) - Function to be called after every retry. It should pass error if no more retries should be performed.
|
||||
- **maxRetries** `number` (optional) - Maximum number of retries. Default: `5`
|
||||
- **maxTimeout** `number` (optional) - Maximum number of milliseconds to wait before retrying. Default: `30000` (30 seconds)
|
||||
- **minTimeout** `number` (optional) - Minimum number of milliseconds to wait before retrying. Default: `500` (half a second)
|
||||
- **timeoutFactor** `number` (optional) - Factor to multiply the timeout by for each retry attempt. Default: `2`
|
||||
- **retryAfter** `boolean` (optional) - It enables automatic retry after the `Retry-After` header is received. Default: `true`
|
||||
-
|
||||
- **methods** `string[]` (optional) - Array of HTTP methods to retry. Default: `['GET', 'PUT', 'HEAD', 'OPTIONS', 'DELETE']`
|
||||
- **statusCodes** `number[]` (optional) - Array of HTTP status codes to retry. Default: `[429, 500, 502, 503, 504]`
|
||||
- **errorCodes** `string[]` (optional) - Array of Error codes to retry. Default: `['ECONNRESET', 'ECONNREFUSED', 'ENOTFOUND', 'ENETDOWN','ENETUNREACH', 'EHOSTDOWN', 'UND_ERR_SOCKET']`
|
||||
|
||||
**`RetryContext`**
|
||||
|
||||
- `state`: `RetryState` - Current retry state. It can be mutated.
|
||||
- `opts`: `Dispatch.DispatchOptions & RetryOptions` - Options passed to the retry handler.
|
||||
|
||||
Example:
|
||||
|
||||
```js
|
||||
import { Agent, RetryAgent } from 'undici'
|
||||
|
||||
const agent = new RetryAgent(new Agent())
|
||||
|
||||
const res = await agent.request('http://example.com')
|
||||
console.log(res.statuCode)
|
||||
console.log(await res.body.text())
|
||||
```
|
||||
@@ -19,7 +19,7 @@ Extends: [`Dispatch.DispatchOptions`](Dispatcher.md#parameter-dispatchoptions).
|
||||
|
||||
#### `RetryOptions`
|
||||
|
||||
- **retry** `(err: Error, context: RetryContext, callback: (err?: Error | null) => void) => void` (optional) - Function to be called after every retry. It should pass error if no more retries should be performed.
|
||||
- **retry** `(err: Error, context: RetryContext, callback: (err?: Error | null) => void) => number | null` (optional) - Function to be called after every retry. It should pass error if no more retries should be performed.
|
||||
- **maxRetries** `number` (optional) - Maximum number of retries. Default: `5`
|
||||
- **maxTimeout** `number` (optional) - Maximum number of milliseconds to wait before retrying. Default: `30000` (30 seconds)
|
||||
- **minTimeout** `number` (optional) - Minimum number of milliseconds to wait before retrying. Default: `500` (half a second)
|
||||
@@ -28,18 +28,27 @@ Extends: [`Dispatch.DispatchOptions`](Dispatcher.md#parameter-dispatchoptions).
|
||||
-
|
||||
- **methods** `string[]` (optional) - Array of HTTP methods to retry. Default: `['GET', 'PUT', 'HEAD', 'OPTIONS', 'DELETE']`
|
||||
- **statusCodes** `number[]` (optional) - Array of HTTP status codes to retry. Default: `[429, 500, 502, 503, 504]`
|
||||
- **errorCodes** `string[]` (optional) - Array of Error codes to retry. Default: `['ECONNRESET', 'ECONNREFUSED', 'ENOTFOUND', 'ENETDOWN','ENETUNREACH', 'EHOSTDOWN',
|
||||
- **errorCodes** `string[]` (optional) - Array of Error codes to retry. Default: `['ECONNRESET', 'ECONNREFUSED', 'ENOTFOUND', 'ENETDOWN','ENETUNREACH', 'EHOSTDOWN', 'UND_ERR_SOCKET']`
|
||||
|
||||
**`RetryContext`**
|
||||
|
||||
- `state`: `RetryState` - Current retry state. It can be mutated.
|
||||
- `opts`: `Dispatch.DispatchOptions & RetryOptions` - Options passed to the retry handler.
|
||||
|
||||
**`RetryState`**
|
||||
|
||||
It represents the retry state for a given request.
|
||||
|
||||
- `counter`: `number` - Current retry attempt.
|
||||
|
||||
### Parameter `RetryHandlers`
|
||||
|
||||
- **dispatch** `(options: Dispatch.DispatchOptions, handlers: Dispatch.DispatchHandlers) => Promise<Dispatch.DispatchResponse>` (required) - Dispatch function to be called after every retry.
|
||||
- **handler** Extends [`Dispatch.DispatchHandlers`](Dispatcher.md#dispatcherdispatchoptions-handler) (required) - Handler function to be called after the request is successful or the retries are exhausted.
|
||||
|
||||
>__Note__: The `RetryHandler` does not retry over stateful bodies (e.g. streams, AsyncIterable) as those, once consumed, are left in an state that cannot be reutilized. For these situations the `RetryHandler` will identify
|
||||
>the body as stateful and will not retry the request rejecting with the error `UND_ERR_REQ_RETRY`.
|
||||
|
||||
Examples:
|
||||
|
||||
```js
|
||||
25
node_modules/undici/docs/docs/api/Util.md
generated
vendored
Normal file
25
node_modules/undici/docs/docs/api/Util.md
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
# Util
|
||||
|
||||
Utility API for third-party implementations of the dispatcher API.
|
||||
|
||||
## `parseHeaders(headers, [obj])`
|
||||
|
||||
Receives a header object and returns the parsed value.
|
||||
|
||||
Arguments:
|
||||
|
||||
- **headers** `(Buffer | string | (Buffer | string)[])[]` (required) - Header object.
|
||||
|
||||
- **obj** `Record<string, string | string[]>` (optional) - Object to specify a proxy object. The parsed value is assigned to this object. But, if **headers** is an object, it is not used.
|
||||
|
||||
Returns: `Record<string, string | string[]>` If **obj** is specified, it is equivalent to **obj**.
|
||||
|
||||
## `headerNameToString(value)`
|
||||
|
||||
Retrieves a header name and returns its lowercase value.
|
||||
|
||||
Arguments:
|
||||
|
||||
- **value** `string | Buffer` (required) - Header name.
|
||||
|
||||
Returns: `string`
|
||||
@@ -21,10 +21,39 @@ An Undici [Client](Client.md) can be best described as a state machine. The foll
|
||||
* At any point in time, the *destroy* event will transition the `Client` from the **processing** state to the **destroyed** state, destroying any queued requests.
|
||||
* The **destroyed** state is a final state and the `Client` is no longer functional.
|
||||
|
||||

|
||||
A state diagram representing an Undici Client instance:
|
||||
|
||||
> The diagram was generated using Mermaid.js Live Editor. Modify the state diagram [here](https://mermaid-js.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoic3RhdGVEaWFncmFtLXYyXG4gICAgWypdIC0tPiBpZGxlXG4gICAgaWRsZSAtLT4gcGVuZGluZyA6IGNvbm5lY3RcbiAgICBpZGxlIC0tPiBkZXN0cm95ZWQgOiBkZXN0cm95L2Nsb3NlXG4gICAgXG4gICAgcGVuZGluZyAtLT4gaWRsZSA6IHRpbWVvdXRcbiAgICBwZW5kaW5nIC0tPiBkZXN0cm95ZWQgOiBkZXN0cm95XG5cbiAgICBzdGF0ZSBjbG9zZV9mb3JrIDw8Zm9yaz4-XG4gICAgcGVuZGluZyAtLT4gY2xvc2VfZm9yayA6IGNsb3NlXG4gICAgY2xvc2VfZm9yayAtLT4gcHJvY2Vzc2luZ1xuICAgIGNsb3NlX2ZvcmsgLS0-IGRlc3Ryb3llZFxuXG4gICAgcGVuZGluZyAtLT4gcHJvY2Vzc2luZyA6IHByb2Nlc3NcblxuICAgIHByb2Nlc3NpbmcgLS0-IHBlbmRpbmcgOiBrZWVwYWxpdmVcbiAgICBwcm9jZXNzaW5nIC0tPiBkZXN0cm95ZWQgOiBkb25lXG4gICAgcHJvY2Vzc2luZyAtLT4gZGVzdHJveWVkIDogZGVzdHJveVxuXG4gICAgc3RhdGUgcHJvY2Vzc2luZyB7XG4gICAgICAgIHJ1bm5pbmcgLS0-IGJ1c3kgOiBuZWVkRHJhaW5cbiAgICAgICAgYnVzeSAtLT4gcnVubmluZyA6IGRyYWluQ29tcGxldGVcbiAgICAgICAgcnVubmluZyAtLT4gWypdIDoga2VlcGFsaXZlXG4gICAgICAgIHJ1bm5pbmcgLS0-IGNsb3NpbmcgOiBjbG9zZVxuICAgICAgICBjbG9zaW5nIC0tPiBbKl0gOiBkb25lXG4gICAgICAgIFsqXSAtLT4gcnVubmluZ1xuICAgIH1cbiAgICAiLCJtZXJtYWlkIjp7InRoZW1lIjoiYmFzZSJ9LCJ1cGRhdGVFZGl0b3IiOmZhbHNlfQ)
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> idle
|
||||
idle --> pending : connect
|
||||
idle --> destroyed : destroy/close
|
||||
|
||||
pending --> idle : timeout
|
||||
pending --> destroyed : destroy
|
||||
|
||||
state close_fork <<fork>>
|
||||
pending --> close_fork : close
|
||||
close_fork --> processing
|
||||
close_fork --> destroyed
|
||||
|
||||
pending --> processing : process
|
||||
|
||||
processing --> pending : keepalive
|
||||
processing --> destroyed : done
|
||||
processing --> destroyed : destroy
|
||||
|
||||
destroyed --> [*]
|
||||
|
||||
state processing {
|
||||
[*] --> running
|
||||
running --> closing : close
|
||||
running --> busy : needDrain
|
||||
busy --> running : drainComplete
|
||||
running --> [*] : keepalive
|
||||
closing --> [*] : done
|
||||
}
|
||||
```
|
||||
## State details
|
||||
|
||||
### idle
|
||||
@@ -11,9 +11,9 @@ The server option `rejectUnauthorized: false` allows us to handle any invalid ce
|
||||
### Client Certificate Authentication
|
||||
|
||||
```js
|
||||
const { readFileSync } = require('fs')
|
||||
const { join } = require('path')
|
||||
const { createServer } = require('https')
|
||||
const { readFileSync } = require('node:fs')
|
||||
const { join } = require('node:path')
|
||||
const { createServer } = require('node:https')
|
||||
const { Client } = require('undici')
|
||||
|
||||
const serverOptions = {
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Connecting through a proxy is possible by:
|
||||
|
||||
- Using [AgentProxy](../api/ProxyAgent.md).
|
||||
- Using [ProxyAgent](../api/ProxyAgent.md).
|
||||
- Configuring `Client` or `Pool` constructor.
|
||||
|
||||
The proxy url should be passed to the `Client` or `Pool` constructor, while the upstream server url
|
||||
@@ -17,7 +17,7 @@ If you proxy requires basic authentication, you can send it via the `proxy-autho
|
||||
```js
|
||||
import { Client } from 'undici'
|
||||
import { createServer } from 'http'
|
||||
import proxy from 'proxy'
|
||||
import { createProxy } from 'proxy'
|
||||
|
||||
const server = await buildServer()
|
||||
const proxyServer = await buildProxy()
|
||||
@@ -59,7 +59,7 @@ function buildServer () {
|
||||
|
||||
function buildProxy () {
|
||||
return new Promise((resolve, reject) => {
|
||||
const server = proxy(createServer())
|
||||
const server = createProxy(createServer())
|
||||
server.listen(0, () => resolve(server))
|
||||
})
|
||||
}
|
||||
@@ -70,7 +70,7 @@ function buildProxy () {
|
||||
```js
|
||||
import { Client } from 'undici'
|
||||
import { createServer } from 'http'
|
||||
import proxy from 'proxy'
|
||||
import { createProxy } from 'proxy'
|
||||
|
||||
const server = await buildServer()
|
||||
const proxyServer = await buildProxy()
|
||||
@@ -78,8 +78,8 @@ const proxyServer = await buildProxy()
|
||||
const serverUrl = `http://localhost:${server.address().port}`
|
||||
const proxyUrl = `http://localhost:${proxyServer.address().port}`
|
||||
|
||||
proxyServer.authenticate = function (req, fn) {
|
||||
fn(null, req.headers['proxy-authorization'] === `Basic ${Buffer.from('user:pass').toString('base64')}`)
|
||||
proxyServer.authenticate = function (req) {
|
||||
return req.headers['proxy-authorization'] === `Basic ${Buffer.from('user:pass').toString('base64')}`
|
||||
}
|
||||
|
||||
server.on('request', (req, res) => {
|
||||
@@ -119,7 +119,7 @@ function buildServer () {
|
||||
|
||||
function buildProxy () {
|
||||
return new Promise((resolve, reject) => {
|
||||
const server = proxy(createServer())
|
||||
const server = createProxy(createServer())
|
||||
server.listen(0, () => resolve(server))
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user