deepv-code 1.0.182

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 (223) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +3 -0
  3. package/bundle/assets/help/README.md +113 -0
  4. package/bundle/assets/help/cli-help-knowledge.md +1382 -0
  5. package/bundle/assets/sounds/README.md +74 -0
  6. package/bundle/assets/sounds/confirmation-required.wav +0 -0
  7. package/bundle/assets/sounds/response-complete.wav +0 -0
  8. package/bundle/assets/sounds/selection-made.wav +0 -0
  9. package/bundle/dvcode.js +4442 -0
  10. package/bundle/fix-binary-permissions.js +215 -0
  11. package/bundle/login/templates/authSelectPage.html +870 -0
  12. package/bundle/login/templates/deepv.ico +0 -0
  13. package/bundle/login/templates/feishu.ico +0 -0
  14. package/bundle/node_modules/@vscode/ripgrep/bin/darwin-arm64-rg +0 -0
  15. package/bundle/node_modules/@vscode/ripgrep/bin/darwin-x64-rg +0 -0
  16. package/bundle/node_modules/@vscode/ripgrep/bin/linux-arm-rg +0 -0
  17. package/bundle/node_modules/@vscode/ripgrep/bin/linux-arm64-rg +0 -0
  18. package/bundle/node_modules/@vscode/ripgrep/bin/linux-x64-rg +0 -0
  19. package/bundle/node_modules/@vscode/ripgrep/bin/rg.exe +0 -0
  20. package/bundle/node_modules/@vscode/ripgrep/bin/win32-arm64-rg.exe +0 -0
  21. package/bundle/node_modules/@vscode/ripgrep/bin/win32-ia32-rg.exe +0 -0
  22. package/bundle/node_modules/@vscode/ripgrep/bin/win32-x64-rg.exe +0 -0
  23. package/bundle/node_modules/@vscode/ripgrep/lib/download.js +357 -0
  24. package/bundle/node_modules/@vscode/ripgrep/lib/index.d.ts +1 -0
  25. package/bundle/node_modules/@vscode/ripgrep/lib/index.js +42 -0
  26. package/bundle/node_modules/@vscode/ripgrep/lib/postinstall.js +121 -0
  27. package/bundle/node_modules/@vscode/ripgrep/package.json +24 -0
  28. package/bundle/node_modules/undici/LICENSE +21 -0
  29. package/bundle/node_modules/undici/README.md +472 -0
  30. package/bundle/node_modules/undici/docs/docs/api/Agent.md +83 -0
  31. package/bundle/node_modules/undici/docs/docs/api/BalancedPool.md +99 -0
  32. package/bundle/node_modules/undici/docs/docs/api/CacheStorage.md +30 -0
  33. package/bundle/node_modules/undici/docs/docs/api/CacheStore.md +151 -0
  34. package/bundle/node_modules/undici/docs/docs/api/Client.md +281 -0
  35. package/bundle/node_modules/undici/docs/docs/api/ClientStats.md +27 -0
  36. package/bundle/node_modules/undici/docs/docs/api/Connector.md +115 -0
  37. package/bundle/node_modules/undici/docs/docs/api/ContentType.md +57 -0
  38. package/bundle/node_modules/undici/docs/docs/api/Cookies.md +101 -0
  39. package/bundle/node_modules/undici/docs/docs/api/Debug.md +62 -0
  40. package/bundle/node_modules/undici/docs/docs/api/DiagnosticsChannel.md +204 -0
  41. package/bundle/node_modules/undici/docs/docs/api/Dispatcher.md +1200 -0
  42. package/bundle/node_modules/undici/docs/docs/api/EnvHttpProxyAgent.md +159 -0
  43. package/bundle/node_modules/undici/docs/docs/api/Errors.md +49 -0
  44. package/bundle/node_modules/undici/docs/docs/api/EventSource.md +45 -0
  45. package/bundle/node_modules/undici/docs/docs/api/Fetch.md +52 -0
  46. package/bundle/node_modules/undici/docs/docs/api/H2CClient.md +262 -0
  47. package/bundle/node_modules/undici/docs/docs/api/MockAgent.md +603 -0
  48. package/bundle/node_modules/undici/docs/docs/api/MockCallHistory.md +197 -0
  49. package/bundle/node_modules/undici/docs/docs/api/MockCallHistoryLog.md +43 -0
  50. package/bundle/node_modules/undici/docs/docs/api/MockClient.md +77 -0
  51. package/bundle/node_modules/undici/docs/docs/api/MockErrors.md +12 -0
  52. package/bundle/node_modules/undici/docs/docs/api/MockPool.md +548 -0
  53. package/bundle/node_modules/undici/docs/docs/api/Pool.md +84 -0
  54. package/bundle/node_modules/undici/docs/docs/api/PoolStats.md +35 -0
  55. package/bundle/node_modules/undici/docs/docs/api/ProxyAgent.md +227 -0
  56. package/bundle/node_modules/undici/docs/docs/api/RedirectHandler.md +96 -0
  57. package/bundle/node_modules/undici/docs/docs/api/RetryAgent.md +45 -0
  58. package/bundle/node_modules/undici/docs/docs/api/RetryHandler.md +117 -0
  59. package/bundle/node_modules/undici/docs/docs/api/Util.md +25 -0
  60. package/bundle/node_modules/undici/docs/docs/api/WebSocket.md +85 -0
  61. package/bundle/node_modules/undici/docs/docs/api/api-lifecycle.md +91 -0
  62. package/bundle/node_modules/undici/docs/docs/best-practices/client-certificate.md +64 -0
  63. package/bundle/node_modules/undici/docs/docs/best-practices/mocking-request.md +190 -0
  64. package/bundle/node_modules/undici/docs/docs/best-practices/proxy.md +127 -0
  65. package/bundle/node_modules/undici/docs/docs/best-practices/writing-tests.md +20 -0
  66. package/bundle/node_modules/undici/index-fetch.js +35 -0
  67. package/bundle/node_modules/undici/index.d.ts +3 -0
  68. package/bundle/node_modules/undici/index.js +183 -0
  69. package/bundle/node_modules/undici/lib/api/abort-signal.js +59 -0
  70. package/bundle/node_modules/undici/lib/api/api-connect.js +110 -0
  71. package/bundle/node_modules/undici/lib/api/api-pipeline.js +252 -0
  72. package/bundle/node_modules/undici/lib/api/api-request.js +199 -0
  73. package/bundle/node_modules/undici/lib/api/api-stream.js +209 -0
  74. package/bundle/node_modules/undici/lib/api/api-upgrade.js +110 -0
  75. package/bundle/node_modules/undici/lib/api/index.js +7 -0
  76. package/bundle/node_modules/undici/lib/api/readable.js +558 -0
  77. package/bundle/node_modules/undici/lib/api/util.js +95 -0
  78. package/bundle/node_modules/undici/lib/cache/memory-cache-store.js +234 -0
  79. package/bundle/node_modules/undici/lib/cache/sqlite-cache-store.js +461 -0
  80. package/bundle/node_modules/undici/lib/core/connect.js +164 -0
  81. package/bundle/node_modules/undici/lib/core/constants.js +143 -0
  82. package/bundle/node_modules/undici/lib/core/diagnostics.js +196 -0
  83. package/bundle/node_modules/undici/lib/core/errors.js +244 -0
  84. package/bundle/node_modules/undici/lib/core/request.js +397 -0
  85. package/bundle/node_modules/undici/lib/core/symbols.js +68 -0
  86. package/bundle/node_modules/undici/lib/core/tree.js +160 -0
  87. package/bundle/node_modules/undici/lib/core/util.js +988 -0
  88. package/bundle/node_modules/undici/lib/dispatcher/agent.js +135 -0
  89. package/bundle/node_modules/undici/lib/dispatcher/balanced-pool.js +206 -0
  90. package/bundle/node_modules/undici/lib/dispatcher/client-h1.js +1615 -0
  91. package/bundle/node_modules/undici/lib/dispatcher/client-h2.js +798 -0
  92. package/bundle/node_modules/undici/lib/dispatcher/client.js +614 -0
  93. package/bundle/node_modules/undici/lib/dispatcher/dispatcher-base.js +161 -0
  94. package/bundle/node_modules/undici/lib/dispatcher/dispatcher.js +48 -0
  95. package/bundle/node_modules/undici/lib/dispatcher/env-http-proxy-agent.js +151 -0
  96. package/bundle/node_modules/undici/lib/dispatcher/fixed-queue.js +159 -0
  97. package/bundle/node_modules/undici/lib/dispatcher/h2c-client.js +122 -0
  98. package/bundle/node_modules/undici/lib/dispatcher/pool-base.js +191 -0
  99. package/bundle/node_modules/undici/lib/dispatcher/pool.js +118 -0
  100. package/bundle/node_modules/undici/lib/dispatcher/proxy-agent.js +275 -0
  101. package/bundle/node_modules/undici/lib/dispatcher/retry-agent.js +35 -0
  102. package/bundle/node_modules/undici/lib/global.js +32 -0
  103. package/bundle/node_modules/undici/lib/handler/cache-handler.js +448 -0
  104. package/bundle/node_modules/undici/lib/handler/cache-revalidation-handler.js +124 -0
  105. package/bundle/node_modules/undici/lib/handler/decorator-handler.js +67 -0
  106. package/bundle/node_modules/undici/lib/handler/redirect-handler.js +227 -0
  107. package/bundle/node_modules/undici/lib/handler/retry-handler.js +342 -0
  108. package/bundle/node_modules/undici/lib/handler/unwrap-handler.js +96 -0
  109. package/bundle/node_modules/undici/lib/handler/wrap-handler.js +95 -0
  110. package/bundle/node_modules/undici/lib/interceptor/cache.js +372 -0
  111. package/bundle/node_modules/undici/lib/interceptor/dns.js +432 -0
  112. package/bundle/node_modules/undici/lib/interceptor/dump.js +111 -0
  113. package/bundle/node_modules/undici/lib/interceptor/redirect.js +21 -0
  114. package/bundle/node_modules/undici/lib/interceptor/response-error.js +95 -0
  115. package/bundle/node_modules/undici/lib/interceptor/retry.js +19 -0
  116. package/bundle/node_modules/undici/lib/llhttp/.gitkeep +0 -0
  117. package/bundle/node_modules/undici/lib/llhttp/constants.d.ts +97 -0
  118. package/bundle/node_modules/undici/lib/llhttp/constants.js +498 -0
  119. package/bundle/node_modules/undici/lib/llhttp/constants.js.map +1 -0
  120. package/bundle/node_modules/undici/lib/llhttp/llhttp-wasm.js +15 -0
  121. package/bundle/node_modules/undici/lib/llhttp/llhttp_simd-wasm.js +15 -0
  122. package/bundle/node_modules/undici/lib/llhttp/utils.d.ts +2 -0
  123. package/bundle/node_modules/undici/lib/llhttp/utils.js +15 -0
  124. package/bundle/node_modules/undici/lib/llhttp/utils.js.map +1 -0
  125. package/bundle/node_modules/undici/lib/mock/mock-agent.js +224 -0
  126. package/bundle/node_modules/undici/lib/mock/mock-call-history.js +248 -0
  127. package/bundle/node_modules/undici/lib/mock/mock-client.js +64 -0
  128. package/bundle/node_modules/undici/lib/mock/mock-errors.js +19 -0
  129. package/bundle/node_modules/undici/lib/mock/mock-interceptor.js +209 -0
  130. package/bundle/node_modules/undici/lib/mock/mock-pool.js +64 -0
  131. package/bundle/node_modules/undici/lib/mock/mock-symbols.js +31 -0
  132. package/bundle/node_modules/undici/lib/mock/mock-utils.js +433 -0
  133. package/bundle/node_modules/undici/lib/mock/pending-interceptors-formatter.js +43 -0
  134. package/bundle/node_modules/undici/lib/util/cache.js +368 -0
  135. package/bundle/node_modules/undici/lib/util/date.js +259 -0
  136. package/bundle/node_modules/undici/lib/util/stats.js +32 -0
  137. package/bundle/node_modules/undici/lib/util/timers.js +423 -0
  138. package/bundle/node_modules/undici/lib/web/cache/cache.js +862 -0
  139. package/bundle/node_modules/undici/lib/web/cache/cachestorage.js +152 -0
  140. package/bundle/node_modules/undici/lib/web/cache/util.js +45 -0
  141. package/bundle/node_modules/undici/lib/web/cookies/constants.js +12 -0
  142. package/bundle/node_modules/undici/lib/web/cookies/index.js +199 -0
  143. package/bundle/node_modules/undici/lib/web/cookies/parse.js +322 -0
  144. package/bundle/node_modules/undici/lib/web/cookies/util.js +282 -0
  145. package/bundle/node_modules/undici/lib/web/eventsource/eventsource-stream.js +399 -0
  146. package/bundle/node_modules/undici/lib/web/eventsource/eventsource.js +484 -0
  147. package/bundle/node_modules/undici/lib/web/eventsource/util.js +37 -0
  148. package/bundle/node_modules/undici/lib/web/fetch/LICENSE +21 -0
  149. package/bundle/node_modules/undici/lib/web/fetch/body.js +532 -0
  150. package/bundle/node_modules/undici/lib/web/fetch/constants.js +131 -0
  151. package/bundle/node_modules/undici/lib/web/fetch/data-url.js +744 -0
  152. package/bundle/node_modules/undici/lib/web/fetch/dispatcher-weakref.js +46 -0
  153. package/bundle/node_modules/undici/lib/web/fetch/formdata-parser.js +501 -0
  154. package/bundle/node_modules/undici/lib/web/fetch/formdata.js +263 -0
  155. package/bundle/node_modules/undici/lib/web/fetch/global.js +40 -0
  156. package/bundle/node_modules/undici/lib/web/fetch/headers.js +719 -0
  157. package/bundle/node_modules/undici/lib/web/fetch/index.js +2258 -0
  158. package/bundle/node_modules/undici/lib/web/fetch/request.js +1099 -0
  159. package/bundle/node_modules/undici/lib/web/fetch/response.js +636 -0
  160. package/bundle/node_modules/undici/lib/web/fetch/util.js +1782 -0
  161. package/bundle/node_modules/undici/lib/web/fetch/webidl.js +740 -0
  162. package/bundle/node_modules/undici/lib/web/websocket/connection.js +325 -0
  163. package/bundle/node_modules/undici/lib/web/websocket/constants.js +126 -0
  164. package/bundle/node_modules/undici/lib/web/websocket/events.js +331 -0
  165. package/bundle/node_modules/undici/lib/web/websocket/frame.js +138 -0
  166. package/bundle/node_modules/undici/lib/web/websocket/permessage-deflate.js +70 -0
  167. package/bundle/node_modules/undici/lib/web/websocket/receiver.js +454 -0
  168. package/bundle/node_modules/undici/lib/web/websocket/sender.js +109 -0
  169. package/bundle/node_modules/undici/lib/web/websocket/stream/websocketerror.js +83 -0
  170. package/bundle/node_modules/undici/lib/web/websocket/stream/websocketstream.js +485 -0
  171. package/bundle/node_modules/undici/lib/web/websocket/util.js +338 -0
  172. package/bundle/node_modules/undici/lib/web/websocket/websocket.js +686 -0
  173. package/bundle/node_modules/undici/package.json +149 -0
  174. package/bundle/node_modules/undici/scripts/strip-comments.js +10 -0
  175. package/bundle/node_modules/undici/types/README.md +6 -0
  176. package/bundle/node_modules/undici/types/agent.d.ts +35 -0
  177. package/bundle/node_modules/undici/types/api.d.ts +43 -0
  178. package/bundle/node_modules/undici/types/balanced-pool.d.ts +29 -0
  179. package/bundle/node_modules/undici/types/cache-interceptor.d.ts +172 -0
  180. package/bundle/node_modules/undici/types/cache.d.ts +36 -0
  181. package/bundle/node_modules/undici/types/client-stats.d.ts +15 -0
  182. package/bundle/node_modules/undici/types/client.d.ts +110 -0
  183. package/bundle/node_modules/undici/types/connector.d.ts +34 -0
  184. package/bundle/node_modules/undici/types/content-type.d.ts +21 -0
  185. package/bundle/node_modules/undici/types/cookies.d.ts +30 -0
  186. package/bundle/node_modules/undici/types/diagnostics-channel.d.ts +66 -0
  187. package/bundle/node_modules/undici/types/dispatcher.d.ts +281 -0
  188. package/bundle/node_modules/undici/types/env-http-proxy-agent.d.ts +21 -0
  189. package/bundle/node_modules/undici/types/errors.d.ts +171 -0
  190. package/bundle/node_modules/undici/types/eventsource.d.ts +61 -0
  191. package/bundle/node_modules/undici/types/fetch.d.ts +210 -0
  192. package/bundle/node_modules/undici/types/formdata.d.ts +108 -0
  193. package/bundle/node_modules/undici/types/global-dispatcher.d.ts +9 -0
  194. package/bundle/node_modules/undici/types/global-origin.d.ts +7 -0
  195. package/bundle/node_modules/undici/types/h2c-client.d.ts +75 -0
  196. package/bundle/node_modules/undici/types/handlers.d.ts +15 -0
  197. package/bundle/node_modules/undici/types/header.d.ts +160 -0
  198. package/bundle/node_modules/undici/types/index.d.ts +75 -0
  199. package/bundle/node_modules/undici/types/interceptors.d.ts +34 -0
  200. package/bundle/node_modules/undici/types/mock-agent.d.ts +68 -0
  201. package/bundle/node_modules/undici/types/mock-call-history.d.ts +111 -0
  202. package/bundle/node_modules/undici/types/mock-client.d.ts +25 -0
  203. package/bundle/node_modules/undici/types/mock-errors.d.ts +12 -0
  204. package/bundle/node_modules/undici/types/mock-interceptor.d.ts +93 -0
  205. package/bundle/node_modules/undici/types/mock-pool.d.ts +25 -0
  206. package/bundle/node_modules/undici/types/patch.d.ts +29 -0
  207. package/bundle/node_modules/undici/types/pool-stats.d.ts +19 -0
  208. package/bundle/node_modules/undici/types/pool.d.ts +41 -0
  209. package/bundle/node_modules/undici/types/proxy-agent.d.ts +29 -0
  210. package/bundle/node_modules/undici/types/readable.d.ts +68 -0
  211. package/bundle/node_modules/undici/types/retry-agent.d.ts +8 -0
  212. package/bundle/node_modules/undici/types/retry-handler.d.ts +116 -0
  213. package/bundle/node_modules/undici/types/util.d.ts +18 -0
  214. package/bundle/node_modules/undici/types/utility.d.ts +7 -0
  215. package/bundle/node_modules/undici/types/webidl.d.ts +266 -0
  216. package/bundle/node_modules/undici/types/websocket.d.ts +184 -0
  217. package/bundle/sandbox-macos-permissive-closed.sb +26 -0
  218. package/bundle/sandbox-macos-permissive-open.sb +19 -0
  219. package/bundle/sandbox-macos-permissive-proxied.sb +31 -0
  220. package/bundle/sandbox-macos-restrictive-closed.sb +87 -0
  221. package/bundle/sandbox-macos-restrictive-open.sb +90 -0
  222. package/bundle/sandbox-macos-restrictive-proxied.sb +92 -0
  223. package/package.json +137 -0
@@ -0,0 +1,91 @@
1
+ # Client Lifecycle
2
+
3
+ An Undici [Client](/docs/docs/api/Client.md) can be best described as a state machine. The following list is a summary of the various state transitions the `Client` will go through in its lifecycle. This document also contains detailed breakdowns of each state.
4
+
5
+ > This diagram is not a perfect representation of the undici Client. Since the Client class is not actually implemented as a state-machine, actual execution may deviate slightly from what is described below. Consider this as a general resource for understanding the inner workings of the Undici client rather than some kind of formal specification.
6
+
7
+ ## State Transition Overview
8
+
9
+ * A `Client` begins in the **idle** state with no socket connection and no requests in queue.
10
+ * The *connect* event transitions the `Client` to the **pending** state where requests can be queued prior to processing.
11
+ * The *close* and *destroy* events transition the `Client` to the **destroyed** state. Since there are no requests in the queue, the *close* event immediately transitions to the **destroyed** state.
12
+ * The **pending** state indicates the underlying socket connection has been successfully established and requests are queueing.
13
+ * The *process* event transitions the `Client` to the **processing** state where requests are processed.
14
+ * If requests are queued, the *close* event transitions to the **processing** state; otherwise, it transitions to the **destroyed** state.
15
+ * The *destroy* event transitions to the **destroyed** state.
16
+ * The **processing** state initializes to the **processing.running** state.
17
+ * If the current request requires draining, the *needDrain* event transitions the `Client` into the **processing.busy** state which will return to the **processing.running** state with the *drainComplete* event.
18
+ * After all queued requests are completed, the *keepalive* event transitions the `Client` back to the **pending** state. If no requests are queued during the timeout, the **close** event transitions the `Client` to the **destroyed** state.
19
+ * If the *close* event is fired while the `Client` still has queued requests, the `Client` transitions to the **process.closing** state where it will complete all existing requests before firing the *done* event.
20
+ * The *done* event gracefully transitions the `Client` to the **destroyed** state.
21
+ * At any point in time, the *destroy* event will transition the `Client` from the **processing** state to the **destroyed** state, destroying any queued requests.
22
+ * The **destroyed** state is a final state and the `Client` is no longer functional.
23
+
24
+ A state diagram representing an Undici Client instance:
25
+
26
+ ```mermaid
27
+ stateDiagram-v2
28
+ [*] --> idle
29
+ idle --> pending : connect
30
+ idle --> destroyed : destroy/close
31
+
32
+ pending --> idle : timeout
33
+ pending --> destroyed : destroy
34
+
35
+ state close_fork <<fork>>
36
+ pending --> close_fork : close
37
+ close_fork --> processing
38
+ close_fork --> destroyed
39
+
40
+ pending --> processing : process
41
+
42
+ processing --> pending : keepalive
43
+ processing --> destroyed : done
44
+ processing --> destroyed : destroy
45
+
46
+ destroyed --> [*]
47
+
48
+ state processing {
49
+ [*] --> running
50
+ running --> closing : close
51
+ running --> busy : needDrain
52
+ busy --> running : drainComplete
53
+ running --> [*] : keepalive
54
+ closing --> [*] : done
55
+ }
56
+ ```
57
+ ## State details
58
+
59
+ ### idle
60
+
61
+ The **idle** state is the initial state of a `Client` instance. While an `origin` is required for instantiating a `Client` instance, the underlying socket connection will not be established until a request is queued using [`Client.dispatch()`](/docs/docs/api/Client.md#clientdispatchoptions-handlers). By calling `Client.dispatch()` directly or using one of the multiple implementations ([`Client.connect()`](Client.md#clientconnectoptions-callback), [`Client.pipeline()`](Client.md#clientpipelineoptions-handler), [`Client.request()`](Client.md#clientrequestoptions-callback), [`Client.stream()`](Client.md#clientstreamoptions-factory-callback), and [`Client.upgrade()`](/docs/docs/api/Client.md#clientupgradeoptions-callback)), the `Client` instance will transition from **idle** to [**pending**](/docs/docs/api/Client.md#pending) and then most likely directly to [**processing**](/docs/docs/api/Client.md#processing).
62
+
63
+ Calling [`Client.close()`](/docs/docs/api/Client.md#clientclosecallback) or [`Client.destroy()`](Client.md#clientdestroyerror-callback) transitions directly to the [**destroyed**](/docs/docs/api/Client.md#destroyed) state since the `Client` instance will have no queued requests in this state.
64
+
65
+ ### pending
66
+
67
+ The **pending** state signifies a non-processing `Client`. Upon entering this state, the `Client` establishes a socket connection and emits the [`'connect'`](/docs/docs/api/Client.md#event-connect) event signalling a connection was successfully established with the `origin` provided during `Client` instantiation. The internal queue is initially empty, and requests can start queueing.
68
+
69
+ Calling [`Client.close()`](/docs/docs/api/Client.md#clientclosecallback) with queued requests, transitions the `Client` to the [**processing**](/docs/docs/api/Client.md#processing) state. Without queued requests, it transitions to the [**destroyed**](/docs/docs/api/Client.md#destroyed) state.
70
+
71
+ Calling [`Client.destroy()`](/docs/docs/api/Client.md#clientdestroyerror-callback) transitions directly to the [**destroyed**](/docs/docs/api/Client.md#destroyed) state regardless of existing requests.
72
+
73
+ ### processing
74
+
75
+ The **processing** state is a state machine within itself. It initializes to the [**processing.running**](/docs/docs/api/Client.md#running) state. The [`Client.dispatch()`](/docs/docs/api/Client.md#clientdispatchoptions-handlers), [`Client.close()`](Client.md#clientclosecallback), and [`Client.destroy()`](Client.md#clientdestroyerror-callback) can be called at any time while the `Client` is in this state. `Client.dispatch()` will add more requests to the queue while existing requests continue to be processed. `Client.close()` will transition to the [**processing.closing**](/docs/docs/api/Client.md#closing) state. And `Client.destroy()` will transition to [**destroyed**](/docs/docs/api/Client.md#destroyed).
76
+
77
+ #### running
78
+
79
+ In the **processing.running** sub-state, queued requests are being processed in a FIFO order. If a request body requires draining, the *needDrain* event transitions to the [**processing.busy**](/docs/docs/api/Client.md#busy) sub-state. The *close* event transitions the Client to the [**process.closing**](/docs/docs/api/Client.md#closing) sub-state. If all queued requests are processed and neither [`Client.close()`](/docs/docs/api/Client.md#clientclosecallback) nor [`Client.destroy()`](Client.md#clientdestroyerror-callback) are called, then the [**processing**](/docs/docs/api/Client.md#processing) machine will trigger a *keepalive* event transitioning the `Client` back to the [**pending**](/docs/docs/api/Client.md#pending) state. During this time, the `Client` is waiting for the socket connection to timeout, and once it does, it triggers the *timeout* event and transitions to the [**idle**](/docs/docs/api/Client.md#idle) state.
80
+
81
+ #### busy
82
+
83
+ This sub-state is only entered when a request body is an instance of [Stream](https://nodejs.org/api/stream.html) and requires draining. The `Client` cannot process additional requests while in this state and must wait until the currently processing request body is completely drained before transitioning back to [**processing.running**](/docs/docs/api/Client.md#running).
84
+
85
+ #### closing
86
+
87
+ This sub-state is only entered when a `Client` instance has queued requests and the [`Client.close()`](/docs/docs/api/Client.md#clientclosecallback) method is called. In this state, the `Client` instance continues to process requests as usual, with the one exception that no additional requests can be queued. Once all of the queued requests are processed, the `Client` will trigger the *done* event gracefully entering the [**destroyed**](/docs/docs/api/Client.md#destroyed) state without an error.
88
+
89
+ ### destroyed
90
+
91
+ The **destroyed** state is a final state for the `Client` instance. Once in this state, a `Client` is nonfunctional. Calling any other `Client` methods will result in an `ClientDestroyedError`.
@@ -0,0 +1,64 @@
1
+ # Client certificate
2
+
3
+ Client certificate authentication can be configured with the `Client`, the required options are passed along through the `connect` option.
4
+
5
+ The client certificates must be signed by a trusted CA. The Node.js default is to trust the well-known CAs curated by Mozilla.
6
+
7
+ Setting the server option `requestCert: true` tells the server to request the client certificate.
8
+
9
+ The server option `rejectUnauthorized: false` allows us to handle any invalid certificate errors in client code. The `authorized` property on the socket of the incoming request will show if the client certificate was valid. The `authorizationError` property will give the reason if the certificate was not valid.
10
+
11
+ ### Client Certificate Authentication
12
+
13
+ ```js
14
+ const { readFileSync } = require('node:fs')
15
+ const { join } = require('node:path')
16
+ const { createServer } = require('node:https')
17
+ const { Client } = require('undici')
18
+
19
+ const serverOptions = {
20
+ ca: [
21
+ readFileSync(join(__dirname, 'client-ca-crt.pem'), 'utf8')
22
+ ],
23
+ key: readFileSync(join(__dirname, 'server-key.pem'), 'utf8'),
24
+ cert: readFileSync(join(__dirname, 'server-crt.pem'), 'utf8'),
25
+ requestCert: true,
26
+ rejectUnauthorized: false
27
+ }
28
+
29
+ const server = createServer(serverOptions, (req, res) => {
30
+ // true if client cert is valid
31
+ if(req.client.authorized === true) {
32
+ console.log('valid')
33
+ } else {
34
+ console.error(req.client.authorizationError)
35
+ }
36
+ res.end()
37
+ })
38
+
39
+ server.listen(0, function () {
40
+ const tls = {
41
+ ca: [
42
+ readFileSync(join(__dirname, 'server-ca-crt.pem'), 'utf8')
43
+ ],
44
+ key: readFileSync(join(__dirname, 'client-key.pem'), 'utf8'),
45
+ cert: readFileSync(join(__dirname, 'client-crt.pem'), 'utf8'),
46
+ rejectUnauthorized: false,
47
+ servername: 'agent1'
48
+ }
49
+ const client = new Client(`https://localhost:${server.address().port}`, {
50
+ connect: tls
51
+ })
52
+
53
+ client.request({
54
+ path: '/',
55
+ method: 'GET'
56
+ }, (err, { body }) => {
57
+ body.on('data', (buf) => {})
58
+ body.on('end', () => {
59
+ client.close()
60
+ server.close()
61
+ })
62
+ })
63
+ })
64
+ ```
@@ -0,0 +1,190 @@
1
+ # Mocking Request
2
+
3
+ Undici has its own mocking [utility](/docs/docs/api/MockAgent.md). It allow us to intercept undici HTTP requests and return mocked values instead. It can be useful for testing purposes.
4
+
5
+ Example:
6
+
7
+ ```js
8
+ // bank.mjs
9
+ import { request } from 'undici'
10
+
11
+ export async function bankTransfer(recipient, amount) {
12
+ const { body } = await request('http://localhost:3000/bank-transfer',
13
+ {
14
+ method: 'POST',
15
+ headers: {
16
+ 'X-TOKEN-SECRET': 'SuperSecretToken',
17
+ },
18
+ body: JSON.stringify({
19
+ recipient,
20
+ amount
21
+ })
22
+ }
23
+ )
24
+ return await body.json()
25
+ }
26
+ ```
27
+
28
+ And this is what the test file looks like:
29
+
30
+ ```js
31
+ // index.test.mjs
32
+ import { strict as assert } from 'node:assert'
33
+ import { MockAgent, setGlobalDispatcher, } from 'undici'
34
+ import { bankTransfer } from './bank.mjs'
35
+
36
+ const mockAgent = new MockAgent();
37
+
38
+ setGlobalDispatcher(mockAgent);
39
+
40
+ // Provide the base url to the request
41
+ const mockPool = mockAgent.get('http://localhost:3000');
42
+
43
+ // intercept the request
44
+ mockPool.intercept({
45
+ path: '/bank-transfer',
46
+ method: 'POST',
47
+ headers: {
48
+ 'X-TOKEN-SECRET': 'SuperSecretToken',
49
+ },
50
+ body: JSON.stringify({
51
+ recipient: '1234567890',
52
+ amount: '100'
53
+ })
54
+ }).reply(200, {
55
+ message: 'transaction processed'
56
+ })
57
+
58
+ const success = await bankTransfer('1234567890', '100')
59
+
60
+ assert.deepEqual(success, { message: 'transaction processed' })
61
+
62
+ // if you dont want to check whether the body or the headers contain the same value
63
+ // just remove it from interceptor
64
+ mockPool.intercept({
65
+ path: '/bank-transfer',
66
+ method: 'POST',
67
+ }).reply(400, {
68
+ message: 'bank account not found'
69
+ })
70
+
71
+ const badRequest = await bankTransfer('1234567890', '100')
72
+
73
+ assert.deepEqual(badRequest, { message: 'bank account not found' })
74
+ ```
75
+
76
+ Explore other MockAgent functionality [here](/docs/docs/api/MockAgent.md)
77
+
78
+ ## Access agent call history
79
+
80
+ Using a MockAgent also allows you to make assertions on the configuration used to make your request in your application.
81
+
82
+ Here is an example :
83
+
84
+ ```js
85
+ // index.test.mjs
86
+ import { strict as assert } from 'node:assert'
87
+ import { MockAgent, setGlobalDispatcher, fetch } from 'undici'
88
+ import { app } from './app.mjs'
89
+
90
+ // given an application server running on http://localhost:3000
91
+ await app.start()
92
+
93
+ // enable call history at instantiation
94
+ const mockAgent = new MockAgent({ enableCallHistory: true })
95
+ // or after instantiation
96
+ mockAgent.enableCallHistory()
97
+
98
+ setGlobalDispatcher(mockAgent)
99
+
100
+ // this call is made (not intercepted)
101
+ await fetch(`http://localhost:3000/endpoint?query='hello'`, {
102
+ method: 'POST',
103
+ headers: { 'content-type': 'application/json' }
104
+ body: JSON.stringify({ data: '' })
105
+ })
106
+
107
+ // access to the call history of the MockAgent (which register every call made intercepted or not)
108
+ assert.ok(mockAgent.getCallHistory()?.calls().length === 1)
109
+ assert.strictEqual(mockAgent.getCallHistory()?.firstCall()?.fullUrl, `http://localhost:3000/endpoint?query='hello'`)
110
+ assert.strictEqual(mockAgent.getCallHistory()?.firstCall()?.body, JSON.stringify({ data: '' }))
111
+ assert.deepStrictEqual(mockAgent.getCallHistory()?.firstCall()?.searchParams, { query: 'hello' })
112
+ assert.strictEqual(mockAgent.getCallHistory()?.firstCall()?.port, '3000')
113
+ assert.strictEqual(mockAgent.getCallHistory()?.firstCall()?.host, 'localhost:3000')
114
+ assert.strictEqual(mockAgent.getCallHistory()?.firstCall()?.method, 'POST')
115
+ assert.strictEqual(mockAgent.getCallHistory()?.firstCall()?.path, '/endpoint')
116
+ assert.deepStrictEqual(mockAgent.getCallHistory()?.firstCall()?.headers, { 'content-type': 'application/json' })
117
+
118
+ // clear all call history logs
119
+ mockAgent.clearCallHistory()
120
+
121
+ assert.ok(mockAgent.getCallHistory()?.calls().length === 0)
122
+ ```
123
+
124
+ Calling `mockAgent.close()` will automatically clear and delete every call history for you.
125
+
126
+ Explore other MockAgent functionality [here](/docs/docs/api/MockAgent.md)
127
+
128
+ Explore other MockCallHistory functionality [here](/docs/docs/api/MockCallHistory.md)
129
+
130
+ Explore other MockCallHistoryLog functionality [here](/docs/docs/api/MockCallHistoryLog.md)
131
+
132
+ ## Debug Mock Value
133
+
134
+ When the interceptor and the request options are not the same, undici will automatically make a real HTTP request. To prevent real requests from being made, use `mockAgent.disableNetConnect()`:
135
+
136
+ ```js
137
+ const mockAgent = new MockAgent();
138
+
139
+ setGlobalDispatcher(mockAgent);
140
+ mockAgent.disableNetConnect()
141
+
142
+ // Provide the base url to the request
143
+ const mockPool = mockAgent.get('http://localhost:3000');
144
+
145
+ mockPool.intercept({
146
+ path: '/bank-transfer',
147
+ method: 'POST',
148
+ }).reply(200, {
149
+ message: 'transaction processed'
150
+ })
151
+
152
+ const badRequest = await bankTransfer('1234567890', '100')
153
+ // Will throw an error
154
+ // MockNotMatchedError: Mock dispatch not matched for path '/bank-transfer':
155
+ // subsequent request to origin http://localhost:3000 was not allowed (net.connect disabled)
156
+ ```
157
+
158
+ ## Reply with data based on request
159
+
160
+ If the mocked response needs to be dynamically derived from the request parameters, you can provide a function instead of an object to `reply`:
161
+
162
+ ```js
163
+ mockPool.intercept({
164
+ path: '/bank-transfer',
165
+ method: 'POST',
166
+ headers: {
167
+ 'X-TOKEN-SECRET': 'SuperSecretToken',
168
+ },
169
+ body: JSON.stringify({
170
+ recipient: '1234567890',
171
+ amount: '100'
172
+ })
173
+ }).reply(200, (opts) => {
174
+ // do something with opts
175
+
176
+ return { message: 'transaction processed' }
177
+ })
178
+ ```
179
+
180
+ in this case opts will be
181
+
182
+ ```
183
+ {
184
+ method: 'POST',
185
+ headers: { 'X-TOKEN-SECRET': 'SuperSecretToken' },
186
+ body: '{"recipient":"1234567890","amount":"100"}',
187
+ origin: 'http://localhost:3000',
188
+ path: '/bank-transfer'
189
+ }
190
+ ```
@@ -0,0 +1,127 @@
1
+ # Connecting through a proxy
2
+
3
+ Connecting through a proxy is possible by:
4
+
5
+ - Using [ProxyAgent](/docs/docs/api/ProxyAgent.md).
6
+ - Configuring `Client` or `Pool` constructor.
7
+
8
+ The proxy url should be passed to the `Client` or `Pool` constructor, while the upstream server url
9
+ should be added to every request call in the `path`.
10
+ For instance, if you need to send a request to the `/hello` route of your upstream server,
11
+ the `path` should be `path: 'http://upstream.server:port/hello?foo=bar'`.
12
+
13
+ If you proxy requires basic authentication, you can send it via the `proxy-authorization` header.
14
+
15
+ ### Connect without authentication
16
+
17
+ ```js
18
+ import { Client } from 'undici'
19
+ import { createServer } from 'http'
20
+ import { createProxy } from 'proxy'
21
+
22
+ const server = await buildServer()
23
+ const proxyServer = await buildProxy()
24
+
25
+ const serverUrl = `http://localhost:${server.address().port}`
26
+ const proxyUrl = `http://localhost:${proxyServer.address().port}`
27
+
28
+ server.on('request', (req, res) => {
29
+ console.log(req.url) // '/hello?foo=bar'
30
+ res.setHeader('content-type', 'application/json')
31
+ res.end(JSON.stringify({ hello: 'world' }))
32
+ })
33
+
34
+ const client = new Client(proxyUrl)
35
+
36
+ const response = await client.request({
37
+ method: 'GET',
38
+ path: serverUrl + '/hello?foo=bar'
39
+ })
40
+
41
+ response.body.setEncoding('utf8')
42
+ let data = ''
43
+ for await (const chunk of response.body) {
44
+ data += chunk
45
+ }
46
+ console.log(response.statusCode) // 200
47
+ console.log(JSON.parse(data)) // { hello: 'world' }
48
+
49
+ server.close()
50
+ proxyServer.close()
51
+ client.close()
52
+
53
+ function buildServer () {
54
+ return new Promise((resolve, reject) => {
55
+ const server = createServer()
56
+ server.listen(0, () => resolve(server))
57
+ })
58
+ }
59
+
60
+ function buildProxy () {
61
+ return new Promise((resolve, reject) => {
62
+ const server = createProxy(createServer())
63
+ server.listen(0, () => resolve(server))
64
+ })
65
+ }
66
+ ```
67
+
68
+ ### Connect with authentication
69
+
70
+ ```js
71
+ import { Client } from 'undici'
72
+ import { createServer } from 'http'
73
+ import { createProxy } from 'proxy'
74
+
75
+ const server = await buildServer()
76
+ const proxyServer = await buildProxy()
77
+
78
+ const serverUrl = `http://localhost:${server.address().port}`
79
+ const proxyUrl = `http://localhost:${proxyServer.address().port}`
80
+
81
+ proxyServer.authenticate = function (req) {
82
+ return req.headers['proxy-authorization'] === `Basic ${Buffer.from('user:pass').toString('base64')}`
83
+ }
84
+
85
+ server.on('request', (req, res) => {
86
+ console.log(req.url) // '/hello?foo=bar'
87
+ res.setHeader('content-type', 'application/json')
88
+ res.end(JSON.stringify({ hello: 'world' }))
89
+ })
90
+
91
+ const client = new Client(proxyUrl)
92
+
93
+ const response = await client.request({
94
+ method: 'GET',
95
+ path: serverUrl + '/hello?foo=bar',
96
+ headers: {
97
+ 'proxy-authorization': `Basic ${Buffer.from('user:pass').toString('base64')}`
98
+ }
99
+ })
100
+
101
+ response.body.setEncoding('utf8')
102
+ let data = ''
103
+ for await (const chunk of response.body) {
104
+ data += chunk
105
+ }
106
+ console.log(response.statusCode) // 200
107
+ console.log(JSON.parse(data)) // { hello: 'world' }
108
+
109
+ server.close()
110
+ proxyServer.close()
111
+ client.close()
112
+
113
+ function buildServer () {
114
+ return new Promise((resolve, reject) => {
115
+ const server = createServer()
116
+ server.listen(0, () => resolve(server))
117
+ })
118
+ }
119
+
120
+ function buildProxy () {
121
+ return new Promise((resolve, reject) => {
122
+ const server = createProxy(createServer())
123
+ server.listen(0, () => resolve(server))
124
+ })
125
+ }
126
+ ```
127
+
@@ -0,0 +1,20 @@
1
+ # Writing tests
2
+
3
+ Undici is tuned for a production use case and its default will keep
4
+ a socket open for a few seconds after an HTTP request is completed to
5
+ remove the overhead of opening up a new socket. These settings that makes
6
+ Undici shine in production are not a good fit for using Undici in automated
7
+ tests, as it will result in longer execution times.
8
+
9
+ The following are good defaults that will keep the socket open for only 10ms:
10
+
11
+ ```js
12
+ import { request, setGlobalDispatcher, Agent } from 'undici'
13
+
14
+ const agent = new Agent({
15
+ keepAliveTimeout: 10, // milliseconds
16
+ keepAliveMaxTimeout: 10 // milliseconds
17
+ })
18
+
19
+ setGlobalDispatcher(agent)
20
+ ```
@@ -0,0 +1,35 @@
1
+ 'use strict'
2
+
3
+ const { getGlobalDispatcher, setGlobalDispatcher } = require('./lib/global')
4
+ const EnvHttpProxyAgent = require('./lib/dispatcher/env-http-proxy-agent')
5
+ const fetchImpl = require('./lib/web/fetch').fetch
6
+
7
+ module.exports.fetch = function fetch (resource, init = undefined) {
8
+ return fetchImpl(resource, init).catch((err) => {
9
+ if (err && typeof err === 'object') {
10
+ Error.captureStackTrace(err)
11
+ }
12
+ throw err
13
+ })
14
+ }
15
+ module.exports.FormData = require('./lib/web/fetch/formdata').FormData
16
+ module.exports.Headers = require('./lib/web/fetch/headers').Headers
17
+ module.exports.Response = require('./lib/web/fetch/response').Response
18
+ module.exports.Request = require('./lib/web/fetch/request').Request
19
+
20
+ const { CloseEvent, ErrorEvent, MessageEvent, createFastMessageEvent } = require('./lib/web/websocket/events')
21
+ module.exports.WebSocket = require('./lib/web/websocket/websocket').WebSocket
22
+ module.exports.CloseEvent = CloseEvent
23
+ module.exports.ErrorEvent = ErrorEvent
24
+ module.exports.MessageEvent = MessageEvent
25
+ module.exports.createFastMessageEvent = createFastMessageEvent
26
+
27
+ module.exports.EventSource = require('./lib/web/eventsource/eventsource').EventSource
28
+
29
+ const api = require('./lib/api')
30
+ const Dispatcher = require('./lib/dispatcher/dispatcher')
31
+ Object.assign(Dispatcher.prototype, api)
32
+ // Expose the fetch implementation to be enabled in Node.js core via a flag
33
+ module.exports.EnvHttpProxyAgent = EnvHttpProxyAgent
34
+ module.exports.getGlobalDispatcher = getGlobalDispatcher
35
+ module.exports.setGlobalDispatcher = setGlobalDispatcher
@@ -0,0 +1,3 @@
1
+ import Undici from './types/index'
2
+ export default Undici
3
+ export * from './types/index'