deepv-code 1.0.182 → 1.0.183

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.
Files changed (193) hide show
  1. package/bundle/dvcode.js +635 -635
  2. package/package.json +1 -1
  3. package/bundle/assets/help/README.md +0 -113
  4. package/bundle/assets/sounds/README.md +0 -74
  5. package/bundle/node_modules/undici/LICENSE +0 -21
  6. package/bundle/node_modules/undici/README.md +0 -472
  7. package/bundle/node_modules/undici/docs/docs/api/Agent.md +0 -83
  8. package/bundle/node_modules/undici/docs/docs/api/BalancedPool.md +0 -99
  9. package/bundle/node_modules/undici/docs/docs/api/CacheStorage.md +0 -30
  10. package/bundle/node_modules/undici/docs/docs/api/CacheStore.md +0 -151
  11. package/bundle/node_modules/undici/docs/docs/api/Client.md +0 -281
  12. package/bundle/node_modules/undici/docs/docs/api/ClientStats.md +0 -27
  13. package/bundle/node_modules/undici/docs/docs/api/Connector.md +0 -115
  14. package/bundle/node_modules/undici/docs/docs/api/ContentType.md +0 -57
  15. package/bundle/node_modules/undici/docs/docs/api/Cookies.md +0 -101
  16. package/bundle/node_modules/undici/docs/docs/api/Debug.md +0 -62
  17. package/bundle/node_modules/undici/docs/docs/api/DiagnosticsChannel.md +0 -204
  18. package/bundle/node_modules/undici/docs/docs/api/Dispatcher.md +0 -1200
  19. package/bundle/node_modules/undici/docs/docs/api/EnvHttpProxyAgent.md +0 -159
  20. package/bundle/node_modules/undici/docs/docs/api/Errors.md +0 -49
  21. package/bundle/node_modules/undici/docs/docs/api/EventSource.md +0 -45
  22. package/bundle/node_modules/undici/docs/docs/api/Fetch.md +0 -52
  23. package/bundle/node_modules/undici/docs/docs/api/H2CClient.md +0 -262
  24. package/bundle/node_modules/undici/docs/docs/api/MockAgent.md +0 -603
  25. package/bundle/node_modules/undici/docs/docs/api/MockCallHistory.md +0 -197
  26. package/bundle/node_modules/undici/docs/docs/api/MockCallHistoryLog.md +0 -43
  27. package/bundle/node_modules/undici/docs/docs/api/MockClient.md +0 -77
  28. package/bundle/node_modules/undici/docs/docs/api/MockErrors.md +0 -12
  29. package/bundle/node_modules/undici/docs/docs/api/MockPool.md +0 -548
  30. package/bundle/node_modules/undici/docs/docs/api/Pool.md +0 -84
  31. package/bundle/node_modules/undici/docs/docs/api/PoolStats.md +0 -35
  32. package/bundle/node_modules/undici/docs/docs/api/ProxyAgent.md +0 -227
  33. package/bundle/node_modules/undici/docs/docs/api/RedirectHandler.md +0 -96
  34. package/bundle/node_modules/undici/docs/docs/api/RetryAgent.md +0 -45
  35. package/bundle/node_modules/undici/docs/docs/api/RetryHandler.md +0 -117
  36. package/bundle/node_modules/undici/docs/docs/api/Util.md +0 -25
  37. package/bundle/node_modules/undici/docs/docs/api/WebSocket.md +0 -85
  38. package/bundle/node_modules/undici/docs/docs/api/api-lifecycle.md +0 -91
  39. package/bundle/node_modules/undici/docs/docs/best-practices/client-certificate.md +0 -64
  40. package/bundle/node_modules/undici/docs/docs/best-practices/mocking-request.md +0 -190
  41. package/bundle/node_modules/undici/docs/docs/best-practices/proxy.md +0 -127
  42. package/bundle/node_modules/undici/docs/docs/best-practices/writing-tests.md +0 -20
  43. package/bundle/node_modules/undici/index-fetch.js +0 -35
  44. package/bundle/node_modules/undici/index.d.ts +0 -3
  45. package/bundle/node_modules/undici/index.js +0 -183
  46. package/bundle/node_modules/undici/lib/api/abort-signal.js +0 -59
  47. package/bundle/node_modules/undici/lib/api/api-connect.js +0 -110
  48. package/bundle/node_modules/undici/lib/api/api-pipeline.js +0 -252
  49. package/bundle/node_modules/undici/lib/api/api-request.js +0 -199
  50. package/bundle/node_modules/undici/lib/api/api-stream.js +0 -209
  51. package/bundle/node_modules/undici/lib/api/api-upgrade.js +0 -110
  52. package/bundle/node_modules/undici/lib/api/index.js +0 -7
  53. package/bundle/node_modules/undici/lib/api/readable.js +0 -558
  54. package/bundle/node_modules/undici/lib/api/util.js +0 -95
  55. package/bundle/node_modules/undici/lib/cache/memory-cache-store.js +0 -234
  56. package/bundle/node_modules/undici/lib/cache/sqlite-cache-store.js +0 -461
  57. package/bundle/node_modules/undici/lib/core/connect.js +0 -164
  58. package/bundle/node_modules/undici/lib/core/constants.js +0 -143
  59. package/bundle/node_modules/undici/lib/core/diagnostics.js +0 -196
  60. package/bundle/node_modules/undici/lib/core/errors.js +0 -244
  61. package/bundle/node_modules/undici/lib/core/request.js +0 -397
  62. package/bundle/node_modules/undici/lib/core/symbols.js +0 -68
  63. package/bundle/node_modules/undici/lib/core/tree.js +0 -160
  64. package/bundle/node_modules/undici/lib/core/util.js +0 -988
  65. package/bundle/node_modules/undici/lib/dispatcher/agent.js +0 -135
  66. package/bundle/node_modules/undici/lib/dispatcher/balanced-pool.js +0 -206
  67. package/bundle/node_modules/undici/lib/dispatcher/client-h1.js +0 -1615
  68. package/bundle/node_modules/undici/lib/dispatcher/client-h2.js +0 -798
  69. package/bundle/node_modules/undici/lib/dispatcher/client.js +0 -614
  70. package/bundle/node_modules/undici/lib/dispatcher/dispatcher-base.js +0 -161
  71. package/bundle/node_modules/undici/lib/dispatcher/dispatcher.js +0 -48
  72. package/bundle/node_modules/undici/lib/dispatcher/env-http-proxy-agent.js +0 -151
  73. package/bundle/node_modules/undici/lib/dispatcher/fixed-queue.js +0 -159
  74. package/bundle/node_modules/undici/lib/dispatcher/h2c-client.js +0 -122
  75. package/bundle/node_modules/undici/lib/dispatcher/pool-base.js +0 -191
  76. package/bundle/node_modules/undici/lib/dispatcher/pool.js +0 -118
  77. package/bundle/node_modules/undici/lib/dispatcher/proxy-agent.js +0 -275
  78. package/bundle/node_modules/undici/lib/dispatcher/retry-agent.js +0 -35
  79. package/bundle/node_modules/undici/lib/global.js +0 -32
  80. package/bundle/node_modules/undici/lib/handler/cache-handler.js +0 -448
  81. package/bundle/node_modules/undici/lib/handler/cache-revalidation-handler.js +0 -124
  82. package/bundle/node_modules/undici/lib/handler/decorator-handler.js +0 -67
  83. package/bundle/node_modules/undici/lib/handler/redirect-handler.js +0 -227
  84. package/bundle/node_modules/undici/lib/handler/retry-handler.js +0 -342
  85. package/bundle/node_modules/undici/lib/handler/unwrap-handler.js +0 -96
  86. package/bundle/node_modules/undici/lib/handler/wrap-handler.js +0 -95
  87. package/bundle/node_modules/undici/lib/interceptor/cache.js +0 -372
  88. package/bundle/node_modules/undici/lib/interceptor/dns.js +0 -432
  89. package/bundle/node_modules/undici/lib/interceptor/dump.js +0 -111
  90. package/bundle/node_modules/undici/lib/interceptor/redirect.js +0 -21
  91. package/bundle/node_modules/undici/lib/interceptor/response-error.js +0 -95
  92. package/bundle/node_modules/undici/lib/interceptor/retry.js +0 -19
  93. package/bundle/node_modules/undici/lib/llhttp/.gitkeep +0 -0
  94. package/bundle/node_modules/undici/lib/llhttp/constants.d.ts +0 -97
  95. package/bundle/node_modules/undici/lib/llhttp/constants.js +0 -498
  96. package/bundle/node_modules/undici/lib/llhttp/constants.js.map +0 -1
  97. package/bundle/node_modules/undici/lib/llhttp/llhttp-wasm.js +0 -15
  98. package/bundle/node_modules/undici/lib/llhttp/llhttp_simd-wasm.js +0 -15
  99. package/bundle/node_modules/undici/lib/llhttp/utils.d.ts +0 -2
  100. package/bundle/node_modules/undici/lib/llhttp/utils.js +0 -15
  101. package/bundle/node_modules/undici/lib/llhttp/utils.js.map +0 -1
  102. package/bundle/node_modules/undici/lib/mock/mock-agent.js +0 -224
  103. package/bundle/node_modules/undici/lib/mock/mock-call-history.js +0 -248
  104. package/bundle/node_modules/undici/lib/mock/mock-client.js +0 -64
  105. package/bundle/node_modules/undici/lib/mock/mock-errors.js +0 -19
  106. package/bundle/node_modules/undici/lib/mock/mock-interceptor.js +0 -209
  107. package/bundle/node_modules/undici/lib/mock/mock-pool.js +0 -64
  108. package/bundle/node_modules/undici/lib/mock/mock-symbols.js +0 -31
  109. package/bundle/node_modules/undici/lib/mock/mock-utils.js +0 -433
  110. package/bundle/node_modules/undici/lib/mock/pending-interceptors-formatter.js +0 -43
  111. package/bundle/node_modules/undici/lib/util/cache.js +0 -368
  112. package/bundle/node_modules/undici/lib/util/date.js +0 -259
  113. package/bundle/node_modules/undici/lib/util/stats.js +0 -32
  114. package/bundle/node_modules/undici/lib/util/timers.js +0 -423
  115. package/bundle/node_modules/undici/lib/web/cache/cache.js +0 -862
  116. package/bundle/node_modules/undici/lib/web/cache/cachestorage.js +0 -152
  117. package/bundle/node_modules/undici/lib/web/cache/util.js +0 -45
  118. package/bundle/node_modules/undici/lib/web/cookies/constants.js +0 -12
  119. package/bundle/node_modules/undici/lib/web/cookies/index.js +0 -199
  120. package/bundle/node_modules/undici/lib/web/cookies/parse.js +0 -322
  121. package/bundle/node_modules/undici/lib/web/cookies/util.js +0 -282
  122. package/bundle/node_modules/undici/lib/web/eventsource/eventsource-stream.js +0 -399
  123. package/bundle/node_modules/undici/lib/web/eventsource/eventsource.js +0 -484
  124. package/bundle/node_modules/undici/lib/web/eventsource/util.js +0 -37
  125. package/bundle/node_modules/undici/lib/web/fetch/LICENSE +0 -21
  126. package/bundle/node_modules/undici/lib/web/fetch/body.js +0 -532
  127. package/bundle/node_modules/undici/lib/web/fetch/constants.js +0 -131
  128. package/bundle/node_modules/undici/lib/web/fetch/data-url.js +0 -744
  129. package/bundle/node_modules/undici/lib/web/fetch/dispatcher-weakref.js +0 -46
  130. package/bundle/node_modules/undici/lib/web/fetch/formdata-parser.js +0 -501
  131. package/bundle/node_modules/undici/lib/web/fetch/formdata.js +0 -263
  132. package/bundle/node_modules/undici/lib/web/fetch/global.js +0 -40
  133. package/bundle/node_modules/undici/lib/web/fetch/headers.js +0 -719
  134. package/bundle/node_modules/undici/lib/web/fetch/index.js +0 -2258
  135. package/bundle/node_modules/undici/lib/web/fetch/request.js +0 -1099
  136. package/bundle/node_modules/undici/lib/web/fetch/response.js +0 -636
  137. package/bundle/node_modules/undici/lib/web/fetch/util.js +0 -1782
  138. package/bundle/node_modules/undici/lib/web/fetch/webidl.js +0 -740
  139. package/bundle/node_modules/undici/lib/web/websocket/connection.js +0 -325
  140. package/bundle/node_modules/undici/lib/web/websocket/constants.js +0 -126
  141. package/bundle/node_modules/undici/lib/web/websocket/events.js +0 -331
  142. package/bundle/node_modules/undici/lib/web/websocket/frame.js +0 -138
  143. package/bundle/node_modules/undici/lib/web/websocket/permessage-deflate.js +0 -70
  144. package/bundle/node_modules/undici/lib/web/websocket/receiver.js +0 -454
  145. package/bundle/node_modules/undici/lib/web/websocket/sender.js +0 -109
  146. package/bundle/node_modules/undici/lib/web/websocket/stream/websocketerror.js +0 -83
  147. package/bundle/node_modules/undici/lib/web/websocket/stream/websocketstream.js +0 -485
  148. package/bundle/node_modules/undici/lib/web/websocket/util.js +0 -338
  149. package/bundle/node_modules/undici/lib/web/websocket/websocket.js +0 -686
  150. package/bundle/node_modules/undici/package.json +0 -149
  151. package/bundle/node_modules/undici/scripts/strip-comments.js +0 -10
  152. package/bundle/node_modules/undici/types/README.md +0 -6
  153. package/bundle/node_modules/undici/types/agent.d.ts +0 -35
  154. package/bundle/node_modules/undici/types/api.d.ts +0 -43
  155. package/bundle/node_modules/undici/types/balanced-pool.d.ts +0 -29
  156. package/bundle/node_modules/undici/types/cache-interceptor.d.ts +0 -172
  157. package/bundle/node_modules/undici/types/cache.d.ts +0 -36
  158. package/bundle/node_modules/undici/types/client-stats.d.ts +0 -15
  159. package/bundle/node_modules/undici/types/client.d.ts +0 -110
  160. package/bundle/node_modules/undici/types/connector.d.ts +0 -34
  161. package/bundle/node_modules/undici/types/content-type.d.ts +0 -21
  162. package/bundle/node_modules/undici/types/cookies.d.ts +0 -30
  163. package/bundle/node_modules/undici/types/diagnostics-channel.d.ts +0 -66
  164. package/bundle/node_modules/undici/types/dispatcher.d.ts +0 -281
  165. package/bundle/node_modules/undici/types/env-http-proxy-agent.d.ts +0 -21
  166. package/bundle/node_modules/undici/types/errors.d.ts +0 -171
  167. package/bundle/node_modules/undici/types/eventsource.d.ts +0 -61
  168. package/bundle/node_modules/undici/types/fetch.d.ts +0 -210
  169. package/bundle/node_modules/undici/types/formdata.d.ts +0 -108
  170. package/bundle/node_modules/undici/types/global-dispatcher.d.ts +0 -9
  171. package/bundle/node_modules/undici/types/global-origin.d.ts +0 -7
  172. package/bundle/node_modules/undici/types/h2c-client.d.ts +0 -75
  173. package/bundle/node_modules/undici/types/handlers.d.ts +0 -15
  174. package/bundle/node_modules/undici/types/header.d.ts +0 -160
  175. package/bundle/node_modules/undici/types/index.d.ts +0 -75
  176. package/bundle/node_modules/undici/types/interceptors.d.ts +0 -34
  177. package/bundle/node_modules/undici/types/mock-agent.d.ts +0 -68
  178. package/bundle/node_modules/undici/types/mock-call-history.d.ts +0 -111
  179. package/bundle/node_modules/undici/types/mock-client.d.ts +0 -25
  180. package/bundle/node_modules/undici/types/mock-errors.d.ts +0 -12
  181. package/bundle/node_modules/undici/types/mock-interceptor.d.ts +0 -93
  182. package/bundle/node_modules/undici/types/mock-pool.d.ts +0 -25
  183. package/bundle/node_modules/undici/types/patch.d.ts +0 -29
  184. package/bundle/node_modules/undici/types/pool-stats.d.ts +0 -19
  185. package/bundle/node_modules/undici/types/pool.d.ts +0 -41
  186. package/bundle/node_modules/undici/types/proxy-agent.d.ts +0 -29
  187. package/bundle/node_modules/undici/types/readable.d.ts +0 -68
  188. package/bundle/node_modules/undici/types/retry-agent.d.ts +0 -8
  189. package/bundle/node_modules/undici/types/retry-handler.d.ts +0 -116
  190. package/bundle/node_modules/undici/types/util.d.ts +0 -18
  191. package/bundle/node_modules/undici/types/utility.d.ts +0 -7
  192. package/bundle/node_modules/undici/types/webidl.d.ts +0 -266
  193. package/bundle/node_modules/undici/types/websocket.d.ts +0 -184
@@ -1,1200 +0,0 @@
1
- # Dispatcher
2
-
3
- Extends: `events.EventEmitter`
4
-
5
- Dispatcher is the core API used to dispatch requests.
6
-
7
- Requests are not guaranteed to be dispatched in order of invocation.
8
-
9
- ## Instance Methods
10
-
11
- ### `Dispatcher.close([callback]): Promise`
12
-
13
- Closes the dispatcher and gracefully waits for enqueued requests to complete before resolving.
14
-
15
- Arguments:
16
-
17
- * **callback** `(error: Error | null, data: null) => void` (optional)
18
-
19
- Returns: `void | Promise<null>` - Only returns a `Promise` if no `callback` argument was passed
20
-
21
- ```js
22
- dispatcher.close() // -> Promise
23
- dispatcher.close(() => {}) // -> void
24
- ```
25
-
26
- #### Example - Request resolves before Client closes
27
-
28
- ```js
29
- import { createServer } from 'http'
30
- import { Client } from 'undici'
31
- import { once } from 'events'
32
-
33
- const server = createServer((request, response) => {
34
- response.end('undici')
35
- }).listen()
36
-
37
- await once(server, 'listening')
38
-
39
- const client = new Client(`http://localhost:${server.address().port}`)
40
-
41
- try {
42
- const { body } = await client.request({
43
- path: '/',
44
- method: 'GET'
45
- })
46
- body.setEncoding('utf8')
47
- body.on('data', console.log)
48
- } catch (error) {}
49
-
50
- await client.close()
51
-
52
- console.log('Client closed')
53
- server.close()
54
- ```
55
-
56
- ### `Dispatcher.connect(options[, callback])`
57
-
58
- Starts two-way communications with the requested resource using [HTTP CONNECT](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/CONNECT).
59
-
60
- Arguments:
61
-
62
- * **options** `ConnectOptions`
63
- * **callback** `(err: Error | null, data: ConnectData | null) => void` (optional)
64
-
65
- Returns: `void | Promise<ConnectData>` - Only returns a `Promise` if no `callback` argument was passed
66
-
67
- #### Parameter: `ConnectOptions`
68
-
69
- * **path** `string`
70
- * **headers** `UndiciHeaders` (optional) - Default: `null`
71
- * **signal** `AbortSignal | events.EventEmitter | null` (optional) - Default: `null`
72
- * **opaque** `unknown` (optional) - This argument parameter is passed through to `ConnectData`
73
-
74
- #### Parameter: `ConnectData`
75
-
76
- * **statusCode** `number`
77
- * **headers** `Record<string, string | string[] | undefined>`
78
- * **socket** `stream.Duplex`
79
- * **opaque** `unknown`
80
-
81
- #### Example - Connect request with echo
82
-
83
- ```js
84
- import { createServer } from 'http'
85
- import { Client } from 'undici'
86
- import { once } from 'events'
87
-
88
- const server = createServer((request, response) => {
89
- throw Error('should never get here')
90
- }).listen()
91
-
92
- server.on('connect', (req, socket, head) => {
93
- socket.write('HTTP/1.1 200 Connection established\r\n\r\n')
94
-
95
- let data = head.toString()
96
- socket.on('data', (buf) => {
97
- data += buf.toString()
98
- })
99
-
100
- socket.on('end', () => {
101
- socket.end(data)
102
- })
103
- })
104
-
105
- await once(server, 'listening')
106
-
107
- const client = new Client(`http://localhost:${server.address().port}`)
108
-
109
- try {
110
- const { socket } = await client.connect({
111
- path: '/'
112
- })
113
- const wanted = 'Body'
114
- let data = ''
115
- socket.on('data', d => { data += d })
116
- socket.on('end', () => {
117
- console.log(`Data received: ${data.toString()} | Data wanted: ${wanted}`)
118
- client.close()
119
- server.close()
120
- })
121
- socket.write(wanted)
122
- socket.end()
123
- } catch (error) { }
124
- ```
125
-
126
- ### `Dispatcher.destroy([error, callback]): Promise`
127
-
128
- Destroy the dispatcher abruptly with the given error. All the pending and running requests will be asynchronously aborted and error. Since this operation is asynchronously dispatched there might still be some progress on dispatched requests.
129
-
130
- Both arguments are optional; the method can be called in four different ways:
131
-
132
- Arguments:
133
-
134
- * **error** `Error | null` (optional)
135
- * **callback** `(error: Error | null, data: null) => void` (optional)
136
-
137
- Returns: `void | Promise<void>` - Only returns a `Promise` if no `callback` argument was passed
138
-
139
- ```js
140
- dispatcher.destroy() // -> Promise
141
- dispatcher.destroy(new Error()) // -> Promise
142
- dispatcher.destroy(() => {}) // -> void
143
- dispatcher.destroy(new Error(), () => {}) // -> void
144
- ```
145
-
146
- #### Example - Request is aborted when Client is destroyed
147
-
148
- ```js
149
- import { createServer } from 'http'
150
- import { Client } from 'undici'
151
- import { once } from 'events'
152
-
153
- const server = createServer((request, response) => {
154
- response.end()
155
- }).listen()
156
-
157
- await once(server, 'listening')
158
-
159
- const client = new Client(`http://localhost:${server.address().port}`)
160
-
161
- try {
162
- const request = client.request({
163
- path: '/',
164
- method: 'GET'
165
- })
166
- client.destroy()
167
- .then(() => {
168
- console.log('Client destroyed')
169
- server.close()
170
- })
171
- await request
172
- } catch (error) {
173
- console.error(error)
174
- }
175
- ```
176
-
177
- ### `Dispatcher.dispatch(options, handler)`
178
-
179
- This is the low level API which all the preceding APIs are implemented on top of.
180
- This API is expected to evolve through semver-major versions and is less stable than the preceding higher level APIs.
181
- It is primarily intended for library developers who implement higher level APIs on top of this.
182
-
183
- Arguments:
184
-
185
- * **options** `DispatchOptions`
186
- * **handler** `DispatchHandler`
187
-
188
- Returns: `Boolean` - `false` if dispatcher is busy and further dispatch calls won't make any progress until the `'drain'` event has been emitted.
189
-
190
- #### Parameter: `DispatchOptions`
191
-
192
- * **origin** `string | URL`
193
- * **path** `string`
194
- * **method** `string`
195
- * **reset** `boolean` (optional) - Default: `false` - If `false`, the request will attempt to create a long-living connection by sending the `connection: keep-alive` header,otherwise will attempt to close it immediately after response by sending `connection: close` within the request and closing the socket afterwards.
196
- * **body** `string | Buffer | Uint8Array | stream.Readable | Iterable | AsyncIterable | null` (optional) - Default: `null`
197
- * **headers** `UndiciHeaders` (optional) - Default: `null`.
198
- * **query** `Record<string, any> | null` (optional) - Default: `null` - Query string params to be embedded in the request URL. Note that both keys and values of query are encoded using `encodeURIComponent`. If for some reason you need to send them unencoded, embed query params into path directly instead.
199
- * **idempotent** `boolean` (optional) - Default: `true` if `method` is `'HEAD'` or `'GET'` - Whether the requests can be safely retried or not. If `false` the request won't be sent until all preceding requests in the pipeline has completed.
200
- * **blocking** `boolean` (optional) - Default: `method !== 'HEAD'` - Whether the response is expected to take a long time and would end up blocking the pipeline. When this is set to `true` further pipelining will be avoided on the same connection until headers have been received.
201
- * **upgrade** `string | null` (optional) - Default: `null` - Upgrade the request. Should be used to specify the kind of upgrade i.e. `'Websocket'`.
202
- * **bodyTimeout** `number | null` (optional) - 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.
203
- * **headersTimeout** `number | null` (optional) - 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.
204
- * **expectContinue** `boolean` (optional) - Default: `false` - For H2, it appends the expect: 100-continue header, and halts the request body until a 100-continue is received from the remote server
205
-
206
- #### Parameter: `DispatchHandler`
207
-
208
- * **onRequestStart** `(controller: DispatchController, 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.
209
- * **onRequestUpgrade** `(controller: DispatchController, statusCode: number, headers: Record<string, string | string[]>, socket: Duplex) => void` (optional) - Invoked when request is upgraded. Required if `DispatchOptions.upgrade` is defined or `DispatchOptions.method === 'CONNECT'`.
210
- * **onResponseStart** `(controller: DispatchController, statusCode: number, headers: Record<string, string | string []>, statusMessage?: string) => void` - Invoked when statusCode and headers have been received. May be invoked multiple times due to 1xx informational headers. Not required for `upgrade` requests.
211
- * **onResponseData** `(controller: DispatchController, chunk: Buffer) => void` - Invoked when response payload data is received. Not required for `upgrade` requests.
212
- * **onResponseEnd** `(controller: DispatchController, trailers: Record<string, string | string[]>) => void` - Invoked when response payload and trailers have been received and the request has completed. Not required for `upgrade` requests.
213
- * **onResponseError** `(controller: DispatchController, error: Error) => void` - Invoked when an error has occurred. May not throw.
214
-
215
- #### Example 1 - Dispatch GET request
216
-
217
- ```js
218
- import { createServer } from 'http'
219
- import { Client } from 'undici'
220
- import { once } from 'events'
221
-
222
- const server = createServer((request, response) => {
223
- response.end('Hello, World!')
224
- }).listen()
225
-
226
- await once(server, 'listening')
227
-
228
- const client = new Client(`http://localhost:${server.address().port}`)
229
-
230
- const data = []
231
-
232
- client.dispatch({
233
- path: '/',
234
- method: 'GET',
235
- headers: {
236
- 'x-foo': 'bar'
237
- }
238
- }, {
239
- onConnect: () => {
240
- console.log('Connected!')
241
- },
242
- onError: (error) => {
243
- console.error(error)
244
- },
245
- onHeaders: (statusCode, headers) => {
246
- console.log(`onHeaders | statusCode: ${statusCode} | headers: ${headers}`)
247
- },
248
- onData: (chunk) => {
249
- console.log('onData: chunk received')
250
- data.push(chunk)
251
- },
252
- onComplete: (trailers) => {
253
- console.log(`onComplete | trailers: ${trailers}`)
254
- const res = Buffer.concat(data).toString('utf8')
255
- console.log(`Data: ${res}`)
256
- client.close()
257
- server.close()
258
- }
259
- })
260
- ```
261
-
262
- #### Example 2 - Dispatch Upgrade Request
263
-
264
- ```js
265
- import { createServer } from 'http'
266
- import { Client } from 'undici'
267
- import { once } from 'events'
268
-
269
- const server = createServer((request, response) => {
270
- response.end()
271
- }).listen()
272
-
273
- await once(server, 'listening')
274
-
275
- server.on('upgrade', (request, socket, head) => {
276
- console.log('Node.js Server - upgrade event')
277
- socket.write('HTTP/1.1 101 Web Socket Protocol Handshake\r\n')
278
- socket.write('Upgrade: WebSocket\r\n')
279
- socket.write('Connection: Upgrade\r\n')
280
- socket.write('\r\n')
281
- socket.end()
282
- })
283
-
284
- const client = new Client(`http://localhost:${server.address().port}`)
285
-
286
- client.dispatch({
287
- path: '/',
288
- method: 'GET',
289
- upgrade: 'websocket'
290
- }, {
291
- onConnect: () => {
292
- console.log('Undici Client - onConnect')
293
- },
294
- onError: (error) => {
295
- console.log('onError') // shouldn't print
296
- },
297
- onUpgrade: (statusCode, headers, socket) => {
298
- console.log('Undici Client - onUpgrade')
299
- console.log(`onUpgrade Headers: ${headers}`)
300
- socket.on('data', buffer => {
301
- console.log(buffer.toString('utf8'))
302
- })
303
- socket.on('end', () => {
304
- client.close()
305
- server.close()
306
- })
307
- socket.end()
308
- }
309
- })
310
- ```
311
-
312
- #### Example 3 - Dispatch POST request
313
-
314
- ```js
315
- import { createServer } from 'http'
316
- import { Client } from 'undici'
317
- import { once } from 'events'
318
-
319
- const server = createServer((request, response) => {
320
- request.on('data', (data) => {
321
- console.log(`Request Data: ${data.toString('utf8')}`)
322
- const body = JSON.parse(data)
323
- body.message = 'World'
324
- response.end(JSON.stringify(body))
325
- })
326
- }).listen()
327
-
328
- await once(server, 'listening')
329
-
330
- const client = new Client(`http://localhost:${server.address().port}`)
331
-
332
- const data = []
333
-
334
- client.dispatch({
335
- path: '/',
336
- method: 'POST',
337
- headers: {
338
- 'content-type': 'application/json'
339
- },
340
- body: JSON.stringify({ message: 'Hello' })
341
- }, {
342
- onConnect: () => {
343
- console.log('Connected!')
344
- },
345
- onError: (error) => {
346
- console.error(error)
347
- },
348
- onHeaders: (statusCode, headers) => {
349
- console.log(`onHeaders | statusCode: ${statusCode} | headers: ${headers}`)
350
- },
351
- onData: (chunk) => {
352
- console.log('onData: chunk received')
353
- data.push(chunk)
354
- },
355
- onComplete: (trailers) => {
356
- console.log(`onComplete | trailers: ${trailers}`)
357
- const res = Buffer.concat(data).toString('utf8')
358
- console.log(`Response Data: ${res}`)
359
- client.close()
360
- server.close()
361
- }
362
- })
363
- ```
364
-
365
- ### `Dispatcher.pipeline(options, handler)`
366
-
367
- For easy use with [stream.pipeline](https://nodejs.org/api/stream.html#stream_stream_pipeline_source_transforms_destination_callback). The `handler` argument should return a `Readable` from which the result will be read. Usually it should just return the `body` argument unless some kind of transformation needs to be performed based on e.g. `headers` or `statusCode`. The `handler` should validate the response and save any required state. If there is an error, it should be thrown. The function returns a `Duplex` which writes to the request and reads from the response.
368
-
369
- Arguments:
370
-
371
- * **options** `PipelineOptions`
372
- * **handler** `(data: PipelineHandlerData) => stream.Readable`
373
-
374
- Returns: `stream.Duplex`
375
-
376
- #### Parameter: PipelineOptions
377
-
378
- Extends: [`RequestOptions`](/docs/docs/api/Dispatcher.md#parameter-requestoptions)
379
-
380
- * **objectMode** `boolean` (optional) - Default: `false` - Set to `true` if the `handler` will return an object stream.
381
-
382
- #### Parameter: PipelineHandlerData
383
-
384
- * **statusCode** `number`
385
- * **headers** `Record<string, string | string[] | undefined>`
386
- * **opaque** `unknown`
387
- * **body** `stream.Readable`
388
- * **context** `object`
389
- * **onInfo** `({statusCode: number, headers: Record<string, string | string[]>}) => void | null` (optional) - Default: `null` - Callback collecting all the info headers (HTTP 100-199) received.
390
-
391
- #### Example 1 - Pipeline Echo
392
-
393
- ```js
394
- import { Readable, Writable, PassThrough, pipeline } from 'stream'
395
- import { createServer } from 'http'
396
- import { Client } from 'undici'
397
- import { once } from 'events'
398
-
399
- const server = createServer((request, response) => {
400
- request.pipe(response)
401
- }).listen()
402
-
403
- await once(server, 'listening')
404
-
405
- const client = new Client(`http://localhost:${server.address().port}`)
406
-
407
- let res = ''
408
-
409
- pipeline(
410
- new Readable({
411
- read () {
412
- this.push(Buffer.from('undici'))
413
- this.push(null)
414
- }
415
- }),
416
- client.pipeline({
417
- path: '/',
418
- method: 'GET'
419
- }, ({ statusCode, headers, body }) => {
420
- console.log(`response received ${statusCode}`)
421
- console.log('headers', headers)
422
- return pipeline(body, new PassThrough(), () => {})
423
- }),
424
- new Writable({
425
- write (chunk, _, callback) {
426
- res += chunk.toString()
427
- callback()
428
- },
429
- final (callback) {
430
- console.log(`Response pipelined to writable: ${res}`)
431
- callback()
432
- }
433
- }),
434
- error => {
435
- if (error) {
436
- console.error(error)
437
- }
438
-
439
- client.close()
440
- server.close()
441
- }
442
- )
443
- ```
444
-
445
- ### `Dispatcher.request(options[, callback])`
446
-
447
- Performs a HTTP request.
448
-
449
- Non-idempotent requests will not be pipelined in order
450
- to avoid indirect failures.
451
-
452
- Idempotent requests will be automatically retried if
453
- they fail due to indirect failure from the request
454
- at the head of the pipeline. This does not apply to
455
- idempotent requests with a stream request body.
456
-
457
- All response bodies must always be fully consumed or destroyed.
458
-
459
- Arguments:
460
-
461
- * **options** `RequestOptions`
462
- * **callback** `(error: Error | null, data: ResponseData) => void` (optional)
463
-
464
- Returns: `void | Promise<ResponseData>` - Only returns a `Promise` if no `callback` argument was passed.
465
-
466
- #### Parameter: `RequestOptions`
467
-
468
- Extends: [`DispatchOptions`](/docs/docs/api/Dispatcher.md#parameter-dispatchoptions)
469
-
470
- * **opaque** `unknown` (optional) - Default: `null` - Used for passing through context to `ResponseData`.
471
- * **signal** `AbortSignal | events.EventEmitter | null` (optional) - Default: `null`.
472
- * **onInfo** `({statusCode: number, headers: Record<string, string | string[]>}) => void | null` (optional) - Default: `null` - Callback collecting all the info headers (HTTP 100-199) received.
473
-
474
- The `RequestOptions.method` property should not be value `'CONNECT'`.
475
-
476
- #### Parameter: `ResponseData`
477
-
478
- * **statusCode** `number`
479
- * **headers** `Record<string, string | string[]>` - Note that all header keys are lower-cased, e.g. `content-type`.
480
- * **body** `stream.Readable` which also implements [the body mixin from the Fetch Standard](https://fetch.spec.whatwg.org/#body-mixin).
481
- * **trailers** `Record<string, string>` - This object starts out
482
- as empty and will be mutated to contain trailers after `body` has emitted `'end'`.
483
- * **opaque** `unknown`
484
- * **context** `object`
485
-
486
- `body` contains the following additional [body mixin](https://fetch.spec.whatwg.org/#body-mixin) methods and properties:
487
-
488
- * [`.arrayBuffer()`](https://fetch.spec.whatwg.org/#dom-body-arraybuffer)
489
- * [`.blob()`](https://fetch.spec.whatwg.org/#dom-body-blob)
490
- * [`.bytes()`](https://fetch.spec.whatwg.org/#dom-body-bytes)
491
- * [`.json()`](https://fetch.spec.whatwg.org/#dom-body-json)
492
- * [`.text()`](https://fetch.spec.whatwg.org/#dom-body-text)
493
- * `body`
494
- * `bodyUsed`
495
-
496
- `body` can not be consumed twice. For example, calling `text()` after `json()` throws `TypeError`.
497
-
498
- `body` contains the following additional extensions:
499
-
500
- - `dump({ limit: Integer })`, dump the response by reading up to `limit` bytes without killing the socket (optional) - Default: 262144.
501
-
502
- Note that body will still be a `Readable` even if it is empty, but attempting to deserialize it with `json()` will result in an exception. Recommended way to ensure there is a body to deserialize is to check if status code is not 204, and `content-type` header starts with `application/json`.
503
-
504
- #### Example 1 - Basic GET Request
505
-
506
- ```js
507
- import { createServer } from 'http'
508
- import { Client } from 'undici'
509
- import { once } from 'events'
510
-
511
- const server = createServer((request, response) => {
512
- response.end('Hello, World!')
513
- }).listen()
514
-
515
- await once(server, 'listening')
516
-
517
- const client = new Client(`http://localhost:${server.address().port}`)
518
-
519
- try {
520
- const { body, headers, statusCode, trailers } = await client.request({
521
- path: '/',
522
- method: 'GET'
523
- })
524
- console.log(`response received ${statusCode}`)
525
- console.log('headers', headers)
526
- body.setEncoding('utf8')
527
- body.on('data', console.log)
528
- body.on('error', console.error)
529
- body.on('end', () => {
530
- console.log('trailers', trailers)
531
- })
532
-
533
- client.close()
534
- server.close()
535
- } catch (error) {
536
- console.error(error)
537
- }
538
- ```
539
-
540
- #### Example 2 - Aborting a request
541
-
542
- > Node.js v15+ is required to run this example
543
-
544
- ```js
545
- import { createServer } from 'http'
546
- import { Client } from 'undici'
547
- import { once } from 'events'
548
-
549
- const server = createServer((request, response) => {
550
- response.end('Hello, World!')
551
- }).listen()
552
-
553
- await once(server, 'listening')
554
-
555
- const client = new Client(`http://localhost:${server.address().port}`)
556
- const abortController = new AbortController()
557
-
558
- try {
559
- client.request({
560
- path: '/',
561
- method: 'GET',
562
- signal: abortController.signal
563
- })
564
- } catch (error) {
565
- console.error(error) // should print an RequestAbortedError
566
- client.close()
567
- server.close()
568
- }
569
-
570
- abortController.abort()
571
- ```
572
-
573
- Alternatively, any `EventEmitter` that emits an `'abort'` event may be used as an abort controller:
574
-
575
- ```js
576
- import { createServer } from 'http'
577
- import { Client } from 'undici'
578
- import EventEmitter, { once } from 'events'
579
-
580
- const server = createServer((request, response) => {
581
- response.end('Hello, World!')
582
- }).listen()
583
-
584
- await once(server, 'listening')
585
-
586
- const client = new Client(`http://localhost:${server.address().port}`)
587
- const ee = new EventEmitter()
588
-
589
- try {
590
- client.request({
591
- path: '/',
592
- method: 'GET',
593
- signal: ee
594
- })
595
- } catch (error) {
596
- console.error(error) // should print an RequestAbortedError
597
- client.close()
598
- server.close()
599
- }
600
-
601
- ee.emit('abort')
602
- ```
603
-
604
- Destroying the request or response body will have the same effect.
605
-
606
- ```js
607
- import { createServer } from 'http'
608
- import { Client } from 'undici'
609
- import { once } from 'events'
610
-
611
- const server = createServer((request, response) => {
612
- response.end('Hello, World!')
613
- }).listen()
614
-
615
- await once(server, 'listening')
616
-
617
- const client = new Client(`http://localhost:${server.address().port}`)
618
-
619
- try {
620
- const { body } = await client.request({
621
- path: '/',
622
- method: 'GET'
623
- })
624
- body.destroy()
625
- } catch (error) {
626
- console.error(error) // should print an RequestAbortedError
627
- client.close()
628
- server.close()
629
- }
630
- ```
631
-
632
- #### Example 3 - Conditionally reading the body
633
-
634
- Remember to fully consume the body even in the case when it is not read.
635
-
636
- ```js
637
- const { body, statusCode } = await client.request({
638
- path: '/',
639
- method: 'GET'
640
- })
641
-
642
- if (statusCode === 200) {
643
- return await body.arrayBuffer()
644
- }
645
-
646
- await body.dump()
647
-
648
- return null
649
- ```
650
-
651
- ### `Dispatcher.stream(options, factory[, callback])`
652
-
653
- A faster version of `Dispatcher.request`. This method expects the second argument `factory` to return a [`stream.Writable`](https://nodejs.org/api/stream.html#stream_class_stream_writable) stream which the response will be written to. This improves performance by avoiding creating an intermediate [`stream.Readable`](https://nodejs.org/api/stream.html#stream_readable_streams) stream when the user expects to directly pipe the response body to a [`stream.Writable`](https://nodejs.org/api/stream.html#stream_class_stream_writable) stream.
654
-
655
- As demonstrated in [Example 1 - Basic GET stream request](/docs/docs/api/Dispatcher.md#example-1-basic-get-stream-request), it is recommended to use the `option.opaque` property to avoid creating a closure for the `factory` method. This pattern works well with Node.js Web Frameworks such as [Fastify](https://fastify.io). See [Example 2 - Stream to Fastify Response](/docs/docs/api/Dispatch.md#example-2-stream-to-fastify-response) for more details.
656
-
657
- Arguments:
658
-
659
- * **options** `RequestOptions`
660
- * **factory** `(data: StreamFactoryData) => stream.Writable`
661
- * **callback** `(error: Error | null, data: StreamData) => void` (optional)
662
-
663
- Returns: `void | Promise<StreamData>` - Only returns a `Promise` if no `callback` argument was passed
664
-
665
- #### Parameter: `StreamFactoryData`
666
-
667
- * **statusCode** `number`
668
- * **headers** `Record<string, string | string[] | undefined>`
669
- * **opaque** `unknown`
670
- * **onInfo** `({statusCode: number, headers: Record<string, string | string[]>}) => void | null` (optional) - Default: `null` - Callback collecting all the info headers (HTTP 100-199) received.
671
-
672
- #### Parameter: `StreamData`
673
-
674
- * **opaque** `unknown`
675
- * **trailers** `Record<string, string>`
676
- * **context** `object`
677
-
678
- #### Example 1 - Basic GET stream request
679
-
680
- ```js
681
- import { createServer } from 'http'
682
- import { Client } from 'undici'
683
- import { once } from 'events'
684
- import { Writable } from 'stream'
685
-
686
- const server = createServer((request, response) => {
687
- response.end('Hello, World!')
688
- }).listen()
689
-
690
- await once(server, 'listening')
691
-
692
- const client = new Client(`http://localhost:${server.address().port}`)
693
-
694
- const bufs = []
695
-
696
- try {
697
- await client.stream({
698
- path: '/',
699
- method: 'GET',
700
- opaque: { bufs }
701
- }, ({ statusCode, headers, opaque: { bufs } }) => {
702
- console.log(`response received ${statusCode}`)
703
- console.log('headers', headers)
704
- return new Writable({
705
- write (chunk, encoding, callback) {
706
- bufs.push(chunk)
707
- callback()
708
- }
709
- })
710
- })
711
-
712
- console.log(Buffer.concat(bufs).toString('utf-8'))
713
-
714
- client.close()
715
- server.close()
716
- } catch (error) {
717
- console.error(error)
718
- }
719
- ```
720
-
721
- #### Example 2 - Stream to Fastify Response
722
-
723
- In this example, a (fake) request is made to the fastify server using `fastify.inject()`. This request then executes the fastify route handler which makes a subsequent request to the raw Node.js http server using `undici.dispatcher.stream()`. The fastify response is passed to the `opaque` option so that undici can tap into the underlying writable stream using `response.raw`. This methodology demonstrates how one could use undici and fastify together to create fast-as-possible requests from one backend server to another.
724
-
725
- ```js
726
- import { createServer } from 'http'
727
- import { Client } from 'undici'
728
- import { once } from 'events'
729
- import fastify from 'fastify'
730
-
731
- const nodeServer = createServer((request, response) => {
732
- response.end('Hello, World! From Node.js HTTP Server')
733
- }).listen()
734
-
735
- await once(nodeServer, 'listening')
736
-
737
- console.log('Node Server listening')
738
-
739
- const nodeServerUndiciClient = new Client(`http://localhost:${nodeServer.address().port}`)
740
-
741
- const fastifyServer = fastify()
742
-
743
- fastifyServer.route({
744
- url: '/',
745
- method: 'GET',
746
- handler: (request, response) => {
747
- nodeServerUndiciClient.stream({
748
- path: '/',
749
- method: 'GET',
750
- opaque: response
751
- }, ({ opaque }) => opaque.raw)
752
- }
753
- })
754
-
755
- await fastifyServer.listen()
756
-
757
- console.log('Fastify Server listening')
758
-
759
- const fastifyServerUndiciClient = new Client(`http://localhost:${fastifyServer.server.address().port}`)
760
-
761
- try {
762
- const { statusCode, body } = await fastifyServerUndiciClient.request({
763
- path: '/',
764
- method: 'GET'
765
- })
766
-
767
- console.log(`response received ${statusCode}`)
768
- body.setEncoding('utf8')
769
- body.on('data', console.log)
770
-
771
- nodeServerUndiciClient.close()
772
- fastifyServerUndiciClient.close()
773
- fastifyServer.close()
774
- nodeServer.close()
775
- } catch (error) { }
776
- ```
777
-
778
- ### `Dispatcher.upgrade(options[, callback])`
779
-
780
- Upgrade to a different protocol. Visit [MDN - HTTP - Protocol upgrade mechanism](https://developer.mozilla.org/en-US/docs/Web/HTTP/Protocol_upgrade_mechanism) for more details.
781
-
782
- Arguments:
783
-
784
- * **options** `UpgradeOptions`
785
-
786
- * **callback** `(error: Error | null, data: UpgradeData) => void` (optional)
787
-
788
- Returns: `void | Promise<UpgradeData>` - Only returns a `Promise` if no `callback` argument was passed
789
-
790
- #### Parameter: `UpgradeOptions`
791
-
792
- * **path** `string`
793
- * **method** `string` (optional) - Default: `'GET'`
794
- * **headers** `UndiciHeaders` (optional) - Default: `null`
795
- * **protocol** `string` (optional) - Default: `'Websocket'` - A string of comma separated protocols, in descending preference order.
796
- * **signal** `AbortSignal | EventEmitter | null` (optional) - Default: `null`
797
-
798
- #### Parameter: `UpgradeData`
799
-
800
- * **headers** `http.IncomingHeaders`
801
- * **socket** `stream.Duplex`
802
- * **opaque** `unknown`
803
-
804
- #### Example 1 - Basic Upgrade Request
805
-
806
- ```js
807
- import { createServer } from 'http'
808
- import { Client } from 'undici'
809
- import { once } from 'events'
810
-
811
- const server = createServer((request, response) => {
812
- response.statusCode = 101
813
- response.setHeader('connection', 'upgrade')
814
- response.setHeader('upgrade', request.headers.upgrade)
815
- response.end()
816
- }).listen()
817
-
818
- await once(server, 'listening')
819
-
820
- const client = new Client(`http://localhost:${server.address().port}`)
821
-
822
- try {
823
- const { headers, socket } = await client.upgrade({
824
- path: '/',
825
- })
826
- socket.on('end', () => {
827
- console.log(`upgrade: ${headers.upgrade}`) // upgrade: Websocket
828
- client.close()
829
- server.close()
830
- })
831
- socket.end()
832
- } catch (error) {
833
- console.error(error)
834
- client.close()
835
- server.close()
836
- }
837
- ```
838
-
839
- ### `Dispatcher.compose(interceptors[, interceptor])`
840
-
841
- Compose a new dispatcher from the current dispatcher and the given interceptors.
842
-
843
- > _Notes_:
844
- > - The order of the interceptors matters. The first interceptor will be the first to be called.
845
- > - It is important to note that the `interceptor` function should return a function that follows the `Dispatcher.dispatch` signature.
846
- > - Any fork of the chain of `interceptors` can lead to unexpected results.
847
-
848
- Arguments:
849
-
850
- * **interceptors** `Interceptor[interceptor[]]`: It is an array of `Interceptor` functions passed as only argument, or several interceptors passed as separate arguments.
851
-
852
- Returns: `Dispatcher`.
853
-
854
- #### Parameter: `Interceptor`
855
-
856
- A function that takes a `dispatch` method and returns a `dispatch`-like function.
857
-
858
- #### Example 1 - Basic Compose
859
-
860
- ```js
861
- const { Client, RedirectHandler } = require('undici')
862
-
863
- const redirectInterceptor = dispatch => {
864
- return (opts, handler) => {
865
- const { maxRedirections } = opts
866
-
867
- if (!maxRedirections) {
868
- return dispatch(opts, handler)
869
- }
870
-
871
- const redirectHandler = new RedirectHandler(
872
- dispatch,
873
- maxRedirections,
874
- opts,
875
- handler
876
- )
877
- opts = { ...opts, maxRedirections: 0 } // Stop sub dispatcher from also redirecting.
878
- return dispatch(opts, redirectHandler)
879
- }
880
- }
881
-
882
- const client = new Client('http://localhost:3000')
883
- .compose(redirectInterceptor)
884
-
885
- await client.request({ path: '/', method: 'GET' })
886
- ```
887
-
888
- #### Example 2 - Chained Compose
889
-
890
- ```js
891
- const { Client, RedirectHandler, RetryHandler } = require('undici')
892
-
893
- const redirectInterceptor = dispatch => {
894
- return (opts, handler) => {
895
- const { maxRedirections } = opts
896
-
897
- if (!maxRedirections) {
898
- return dispatch(opts, handler)
899
- }
900
-
901
- const redirectHandler = new RedirectHandler(
902
- dispatch,
903
- maxRedirections,
904
- opts,
905
- handler
906
- )
907
- opts = { ...opts, maxRedirections: 0 }
908
- return dispatch(opts, redirectHandler)
909
- }
910
- }
911
-
912
- const retryInterceptor = dispatch => {
913
- return function retryInterceptor (opts, handler) {
914
- return dispatch(
915
- opts,
916
- new RetryHandler(opts, {
917
- handler,
918
- dispatch
919
- })
920
- )
921
- }
922
- }
923
-
924
- const client = new Client('http://localhost:3000')
925
- .compose(redirectInterceptor)
926
- .compose(retryInterceptor)
927
-
928
- await client.request({ path: '/', method: 'GET' })
929
- ```
930
-
931
- #### Pre-built interceptors
932
-
933
- ##### `redirect`
934
-
935
- The `redirect` interceptor allows you to customize the way your dispatcher handles redirects.
936
-
937
- It accepts the same arguments as the [`RedirectHandler` constructor](/docs/docs/api/RedirectHandler.md).
938
-
939
- **Example - Basic Redirect Interceptor**
940
-
941
- ```js
942
- const { Client, interceptors } = require("undici");
943
- const { redirect } = interceptors;
944
-
945
- const client = new Client("http://example.com").compose(
946
- redirect({ maxRedirections: 3, throwOnMaxRedirects: true })
947
- );
948
- client.request({ path: "/" })
949
- ```
950
-
951
- ##### `retry`
952
-
953
- The `retry` interceptor allows you to customize the way your dispatcher handles retries.
954
-
955
- It accepts the same arguments as the [`RetryHandler` constructor](/docs/docs/api/RetryHandler.md).
956
-
957
- **Example - Basic Redirect Interceptor**
958
-
959
- ```js
960
- const { Client, interceptors } = require("undici");
961
- const { retry } = interceptors;
962
-
963
- const client = new Client("http://example.com").compose(
964
- retry({
965
- maxRetries: 3,
966
- minTimeout: 1000,
967
- maxTimeout: 10000,
968
- timeoutFactor: 2,
969
- retryAfter: true,
970
- })
971
- );
972
- ```
973
-
974
- ##### `dump`
975
-
976
- The `dump` interceptor enables you to dump the response body from a request upon a given limit.
977
-
978
- **Options**
979
- - `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`.
980
-
981
- > 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.
982
-
983
- **Example - Basic Dump Interceptor**
984
-
985
- ```js
986
- const { Client, interceptors } = require("undici");
987
- const { dump } = interceptors;
988
-
989
- const client = new Client("http://example.com").compose(
990
- dump({
991
- maxSize: 1024,
992
- })
993
- );
994
-
995
- // or
996
- client.dispatch(
997
- {
998
- path: "/",
999
- method: "GET",
1000
- dumpMaxSize: 1024,
1001
- },
1002
- handler
1003
- );
1004
- ```
1005
-
1006
- ##### `dns`
1007
-
1008
- The `dns` interceptor enables you to cache DNS lookups for a given duration, per origin.
1009
-
1010
- >It is well suited for scenarios where you want to cache DNS lookups to avoid the overhead of resolving the same domain multiple times
1011
-
1012
- **Options**
1013
- - `maxTTL` - The maximum time-to-live (in milliseconds) of the DNS cache. It should be a positive integer. Default: `10000`.
1014
- - Set `0` to disable TTL.
1015
- - `maxItems` - The maximum number of items to cache. It should be a positive integer. Default: `Infinity`.
1016
- - `dualStack` - Whether to resolve both IPv4 and IPv6 addresses. Default: `true`.
1017
- - It will also attempt a happy-eyeballs-like approach to connect to the available addresses in case of a connection failure.
1018
- - `affinity` - Whether to use IPv4 or IPv6 addresses. Default: `4`.
1019
- - It can be either `'4` or `6`.
1020
- - It will only take effect if `dualStack` is `false`.
1021
- - `lookup: (hostname: string, options: LookupOptions, callback: (err: NodeJS.ErrnoException | null, addresses: DNSInterceptorRecord[]) => void) => void` - Custom lookup function. Default: `dns.lookup`.
1022
- - For more info see [dns.lookup](https://nodejs.org/api/dns.html#dns_dns_lookup_hostname_options_callback).
1023
- - `pick: (origin: URL, records: DNSInterceptorRecords, affinity: 4 | 6) => DNSInterceptorRecord` - Custom pick function. Default: `RoundRobin`.
1024
- - The function should return a single record from the records array.
1025
- - By default a simplified version of Round Robin is used.
1026
- - The `records` property can be mutated to store the state of the balancing algorithm.
1027
-
1028
- > 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.
1029
-
1030
-
1031
- **DNSInterceptorRecord**
1032
- It represents a DNS record.
1033
- - `family` - (`number`) The IP family of the address. It can be either `4` or `6`.
1034
- - `address` - (`string`) The IP address.
1035
-
1036
- **DNSInterceptorOriginRecords**
1037
- It represents a map of DNS IP addresses records for a single origin.
1038
- - `4.ips` - (`DNSInterceptorRecord[] | null`) The IPv4 addresses.
1039
- - `6.ips` - (`DNSInterceptorRecord[] | null`) The IPv6 addresses.
1040
-
1041
- **Example - Basic DNS Interceptor**
1042
-
1043
- ```js
1044
- const { Client, interceptors } = require("undici");
1045
- const { dns } = interceptors;
1046
-
1047
- const client = new Agent().compose([
1048
- dns({ ...opts })
1049
- ])
1050
-
1051
- const response = await client.request({
1052
- origin: `http://localhost:3030`,
1053
- ...requestOpts
1054
- })
1055
- ```
1056
-
1057
- ##### `responseError`
1058
-
1059
- The `responseError` interceptor throws an error for responses with status code errors (>= 400).
1060
-
1061
- **Example**
1062
-
1063
- ```js
1064
- const { Client, interceptors } = require("undici");
1065
- const { responseError } = interceptors;
1066
-
1067
- const client = new Client("http://example.com").compose(
1068
- responseError()
1069
- );
1070
-
1071
- // Will throw a ResponseError for status codes >= 400
1072
- await client.request({
1073
- method: "GET",
1074
- path: "/"
1075
- });
1076
- ```
1077
-
1078
- ##### `Cache Interceptor`
1079
-
1080
- The `cache` interceptor implements client-side response caching as described in
1081
- [RFC9111](https://www.rfc-editor.org/rfc/rfc9111.html).
1082
-
1083
- **Options**
1084
-
1085
- - `store` - The [`CacheStore`](/docs/docs/api/CacheStore.md) to store and retrieve responses from. Default is [`MemoryCacheStore`](/docs/docs/api/CacheStore.md#memorycachestore).
1086
- - `methods` - The [**safe** HTTP methods](https://www.rfc-editor.org/rfc/rfc9110#section-9.2.1) to cache the response of.
1087
- - `cacheByDefault` - The default expiration time to cache responses by if they don't have an explicit expiration. If this isn't present, responses without explicit expiration will not be cached. Default `undefined`.
1088
- - `type` - The type of cache for Undici to act as. Can be `shared` or `private`. Default `shared`.
1089
-
1090
- ## Instance Events
1091
-
1092
- ### Event: `'connect'`
1093
-
1094
- Parameters:
1095
-
1096
- * **origin** `URL`
1097
- * **targets** `Array<Dispatcher>`
1098
-
1099
- ### Event: `'disconnect'`
1100
-
1101
- Parameters:
1102
-
1103
- * **origin** `URL`
1104
- * **targets** `Array<Dispatcher>`
1105
- * **error** `Error`
1106
-
1107
- Emitted when the dispatcher has been disconnected from the origin.
1108
-
1109
- > **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`.
1110
- > 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.
1111
- > It is recommended to handle this event and close the dispatcher to create a new HTTP/2 session.
1112
-
1113
- ### Event: `'connectionError'`
1114
-
1115
- Parameters:
1116
-
1117
- * **origin** `URL`
1118
- * **targets** `Array<Dispatcher>`
1119
- * **error** `Error`
1120
-
1121
- Emitted when dispatcher fails to connect to
1122
- origin.
1123
-
1124
- ### Event: `'drain'`
1125
-
1126
- Parameters:
1127
-
1128
- * **origin** `URL`
1129
-
1130
- Emitted when dispatcher is no longer busy.
1131
-
1132
- ## Parameter: `UndiciHeaders`
1133
-
1134
- * `Record<string, string | string[] | undefined> | string[] | Iterable<[string, string | string[] | undefined]> | null`
1135
-
1136
- Header arguments such as `options.headers` in [`Client.dispatch`](/docs/docs/api/Client.md#clientdispatchoptions-handlers) can be specified in three forms:
1137
- * As an object specified by the `Record<string, string | string[] | undefined>` (`IncomingHttpHeaders`) type.
1138
- * As an array of strings. An array representation of a header list must have an even length, or an `InvalidArgumentError` will be thrown.
1139
- * As an iterable that can encompass `Headers`, `Map`, or a custom iterator returning key-value pairs.
1140
- Keys are lowercase and values are not modified.
1141
-
1142
- Response headers will derive a `host` from the `url` of the [Client](/docs/docs/api/Client.md#class-client) instance if no `host` header was previously specified.
1143
-
1144
- ### Example 1 - Object
1145
-
1146
- ```js
1147
- {
1148
- 'content-length': '123',
1149
- 'content-type': 'text/plain',
1150
- connection: 'keep-alive',
1151
- host: 'mysite.com',
1152
- accept: '*/*'
1153
- }
1154
- ```
1155
-
1156
- ### Example 2 - Array
1157
-
1158
- ```js
1159
- [
1160
- 'content-length', '123',
1161
- 'content-type', 'text/plain',
1162
- 'connection', 'keep-alive',
1163
- 'host', 'mysite.com',
1164
- 'accept', '*/*'
1165
- ]
1166
- ```
1167
-
1168
- ### Example 3 - Iterable
1169
-
1170
- ```js
1171
- new Headers({
1172
- 'content-length': '123',
1173
- 'content-type': 'text/plain',
1174
- connection: 'keep-alive',
1175
- host: 'mysite.com',
1176
- accept: '*/*'
1177
- })
1178
- ```
1179
- or
1180
- ```js
1181
- new Map([
1182
- ['content-length', '123'],
1183
- ['content-type', 'text/plain'],
1184
- ['connection', 'keep-alive'],
1185
- ['host', 'mysite.com'],
1186
- ['accept', '*/*']
1187
- ])
1188
- ```
1189
- or
1190
- ```js
1191
- {
1192
- *[Symbol.iterator] () {
1193
- yield ['content-length', '123']
1194
- yield ['content-type', 'text/plain']
1195
- yield ['connection', 'keep-alive']
1196
- yield ['host', 'mysite.com']
1197
- yield ['accept', '*/*']
1198
- }
1199
- }
1200
- ```