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,95 @@
1
+ 'use strict'
2
+
3
+ const { InvalidArgumentError } = require('../core/errors')
4
+
5
+ module.exports = class WrapHandler {
6
+ #handler
7
+
8
+ constructor (handler) {
9
+ this.#handler = handler
10
+ }
11
+
12
+ static wrap (handler) {
13
+ // TODO (fix): More checks...
14
+ return handler.onRequestStart ? handler : new WrapHandler(handler)
15
+ }
16
+
17
+ // Unwrap Interface
18
+
19
+ onConnect (abort, context) {
20
+ return this.#handler.onConnect?.(abort, context)
21
+ }
22
+
23
+ onHeaders (statusCode, rawHeaders, resume, statusMessage) {
24
+ return this.#handler.onHeaders?.(statusCode, rawHeaders, resume, statusMessage)
25
+ }
26
+
27
+ onUpgrade (statusCode, rawHeaders, socket) {
28
+ return this.#handler.onUpgrade?.(statusCode, rawHeaders, socket)
29
+ }
30
+
31
+ onData (data) {
32
+ return this.#handler.onData?.(data)
33
+ }
34
+
35
+ onComplete (trailers) {
36
+ return this.#handler.onComplete?.(trailers)
37
+ }
38
+
39
+ onError (err) {
40
+ if (!this.#handler.onError) {
41
+ throw err
42
+ }
43
+
44
+ return this.#handler.onError?.(err)
45
+ }
46
+
47
+ // Wrap Interface
48
+
49
+ onRequestStart (controller, context) {
50
+ this.#handler.onConnect?.((reason) => controller.abort(reason), context)
51
+ }
52
+
53
+ onRequestUpgrade (controller, statusCode, headers, socket) {
54
+ const rawHeaders = []
55
+ for (const [key, val] of Object.entries(headers)) {
56
+ rawHeaders.push(Buffer.from(key), Array.isArray(val) ? val.map(v => Buffer.from(v)) : Buffer.from(val))
57
+ }
58
+
59
+ this.#handler.onUpgrade?.(statusCode, rawHeaders, socket)
60
+ }
61
+
62
+ onResponseStart (controller, statusCode, headers, statusMessage) {
63
+ const rawHeaders = []
64
+ for (const [key, val] of Object.entries(headers)) {
65
+ rawHeaders.push(Buffer.from(key), Array.isArray(val) ? val.map(v => Buffer.from(v)) : Buffer.from(val))
66
+ }
67
+
68
+ if (this.#handler.onHeaders?.(statusCode, rawHeaders, () => controller.resume(), statusMessage) === false) {
69
+ controller.pause()
70
+ }
71
+ }
72
+
73
+ onResponseData (controller, data) {
74
+ if (this.#handler.onData?.(data) === false) {
75
+ controller.pause()
76
+ }
77
+ }
78
+
79
+ onResponseEnd (controller, trailers) {
80
+ const rawTrailers = []
81
+ for (const [key, val] of Object.entries(trailers)) {
82
+ rawTrailers.push(Buffer.from(key), Array.isArray(val) ? val.map(v => Buffer.from(v)) : Buffer.from(val))
83
+ }
84
+
85
+ this.#handler.onComplete?.(rawTrailers)
86
+ }
87
+
88
+ onResponseError (controller, err) {
89
+ if (!this.#handler.onError) {
90
+ throw new InvalidArgumentError('invalid onError method')
91
+ }
92
+
93
+ this.#handler.onError?.(err)
94
+ }
95
+ }
@@ -0,0 +1,372 @@
1
+ 'use strict'
2
+
3
+ const assert = require('node:assert')
4
+ const { Readable } = require('node:stream')
5
+ const util = require('../core/util')
6
+ const CacheHandler = require('../handler/cache-handler')
7
+ const MemoryCacheStore = require('../cache/memory-cache-store')
8
+ const CacheRevalidationHandler = require('../handler/cache-revalidation-handler')
9
+ const { assertCacheStore, assertCacheMethods, makeCacheKey, normaliseHeaders, parseCacheControlHeader } = require('../util/cache.js')
10
+ const { AbortError } = require('../core/errors.js')
11
+
12
+ /**
13
+ * @typedef {(options: import('../../types/dispatcher.d.ts').default.DispatchOptions, handler: import('../../types/dispatcher.d.ts').default.DispatchHandler) => void} DispatchFn
14
+ */
15
+
16
+ /**
17
+ * @param {import('../../types/cache-interceptor.d.ts').default.GetResult} result
18
+ * @param {import('../../types/cache-interceptor.d.ts').default.CacheControlDirectives | undefined} cacheControlDirectives
19
+ * @returns {boolean}
20
+ */
21
+ function needsRevalidation (result, cacheControlDirectives) {
22
+ if (cacheControlDirectives?.['no-cache']) {
23
+ // Always revalidate requests with the no-cache request directive
24
+ return true
25
+ }
26
+
27
+ if (result.cacheControlDirectives?.['no-cache'] && !Array.isArray(result.cacheControlDirectives['no-cache'])) {
28
+ // Always revalidate requests with unqualified no-cache response directive
29
+ return true
30
+ }
31
+
32
+ const now = Date.now()
33
+ if (now > result.staleAt) {
34
+ // Response is stale
35
+ if (cacheControlDirectives?.['max-stale']) {
36
+ // There's a threshold where we can serve stale responses, let's see if
37
+ // we're in it
38
+ // https://www.rfc-editor.org/rfc/rfc9111.html#name-max-stale
39
+ const gracePeriod = result.staleAt + (cacheControlDirectives['max-stale'] * 1000)
40
+ return now > gracePeriod
41
+ }
42
+
43
+ return true
44
+ }
45
+
46
+ if (cacheControlDirectives?.['min-fresh']) {
47
+ // https://www.rfc-editor.org/rfc/rfc9111.html#section-5.2.1.3
48
+
49
+ // At this point, staleAt is always > now
50
+ const timeLeftTillStale = result.staleAt - now
51
+ const threshold = cacheControlDirectives['min-fresh'] * 1000
52
+
53
+ return timeLeftTillStale <= threshold
54
+ }
55
+
56
+ return false
57
+ }
58
+
59
+ /**
60
+ * @param {DispatchFn} dispatch
61
+ * @param {import('../../types/cache-interceptor.d.ts').default.CacheHandlerOptions} globalOpts
62
+ * @param {import('../../types/cache-interceptor.d.ts').default.CacheKey} cacheKey
63
+ * @param {import('../../types/dispatcher.d.ts').default.DispatchHandler} handler
64
+ * @param {import('../../types/dispatcher.d.ts').default.RequestOptions} opts
65
+ * @param {import('../../types/cache-interceptor.d.ts').default.CacheControlDirectives | undefined} reqCacheControl
66
+ */
67
+ function handleUncachedResponse (
68
+ dispatch,
69
+ globalOpts,
70
+ cacheKey,
71
+ handler,
72
+ opts,
73
+ reqCacheControl
74
+ ) {
75
+ if (reqCacheControl?.['only-if-cached']) {
76
+ let aborted = false
77
+ try {
78
+ if (typeof handler.onConnect === 'function') {
79
+ handler.onConnect(() => {
80
+ aborted = true
81
+ })
82
+
83
+ if (aborted) {
84
+ return
85
+ }
86
+ }
87
+
88
+ if (typeof handler.onHeaders === 'function') {
89
+ handler.onHeaders(504, [], () => {}, 'Gateway Timeout')
90
+ if (aborted) {
91
+ return
92
+ }
93
+ }
94
+
95
+ if (typeof handler.onComplete === 'function') {
96
+ handler.onComplete([])
97
+ }
98
+ } catch (err) {
99
+ if (typeof handler.onError === 'function') {
100
+ handler.onError(err)
101
+ }
102
+ }
103
+
104
+ return true
105
+ }
106
+
107
+ return dispatch(opts, new CacheHandler(globalOpts, cacheKey, handler))
108
+ }
109
+
110
+ /**
111
+ * @param {import('../../types/dispatcher.d.ts').default.DispatchHandler} handler
112
+ * @param {import('../../types/dispatcher.d.ts').default.RequestOptions} opts
113
+ * @param {import('../../types/cache-interceptor.d.ts').default.GetResult} result
114
+ * @param {number} age
115
+ * @param {any} context
116
+ * @param {boolean} isStale
117
+ */
118
+ function sendCachedValue (handler, opts, result, age, context, isStale) {
119
+ // TODO (perf): Readable.from path can be optimized...
120
+ const stream = util.isStream(result.body)
121
+ ? result.body
122
+ : Readable.from(result.body ?? [])
123
+
124
+ assert(!stream.destroyed, 'stream should not be destroyed')
125
+ assert(!stream.readableDidRead, 'stream should not be readableDidRead')
126
+
127
+ const controller = {
128
+ resume () {
129
+ stream.resume()
130
+ },
131
+ pause () {
132
+ stream.pause()
133
+ },
134
+ get paused () {
135
+ return stream.isPaused()
136
+ },
137
+ get aborted () {
138
+ return stream.destroyed
139
+ },
140
+ get reason () {
141
+ return stream.errored
142
+ },
143
+ abort (reason) {
144
+ stream.destroy(reason ?? new AbortError())
145
+ }
146
+ }
147
+
148
+ stream
149
+ .on('error', function (err) {
150
+ if (!this.readableEnded) {
151
+ if (typeof handler.onResponseError === 'function') {
152
+ handler.onResponseError(controller, err)
153
+ } else {
154
+ throw err
155
+ }
156
+ }
157
+ })
158
+ .on('close', function () {
159
+ if (!this.errored) {
160
+ handler.onResponseEnd?.(controller, {})
161
+ }
162
+ })
163
+
164
+ handler.onRequestStart?.(controller, context)
165
+
166
+ if (stream.destroyed) {
167
+ return
168
+ }
169
+
170
+ // Add the age header
171
+ // https://www.rfc-editor.org/rfc/rfc9111.html#name-age
172
+ const headers = { ...result.headers, age: String(age) }
173
+
174
+ if (isStale) {
175
+ // Add warning header
176
+ // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Warning
177
+ headers.warning = '110 - "response is stale"'
178
+ }
179
+
180
+ handler.onResponseStart?.(controller, result.statusCode, headers, result.statusMessage)
181
+
182
+ if (opts.method === 'HEAD') {
183
+ stream.destroy()
184
+ } else {
185
+ stream.on('data', function (chunk) {
186
+ handler.onResponseData?.(controller, chunk)
187
+ })
188
+ }
189
+ }
190
+
191
+ /**
192
+ * @param {DispatchFn} dispatch
193
+ * @param {import('../../types/cache-interceptor.d.ts').default.CacheHandlerOptions} globalOpts
194
+ * @param {import('../../types/cache-interceptor.d.ts').default.CacheKey} cacheKey
195
+ * @param {import('../../types/dispatcher.d.ts').default.DispatchHandler} handler
196
+ * @param {import('../../types/dispatcher.d.ts').default.RequestOptions} opts
197
+ * @param {import('../../types/cache-interceptor.d.ts').default.CacheControlDirectives | undefined} reqCacheControl
198
+ * @param {import('../../types/cache-interceptor.d.ts').default.GetResult | undefined} result
199
+ */
200
+ function handleResult (
201
+ dispatch,
202
+ globalOpts,
203
+ cacheKey,
204
+ handler,
205
+ opts,
206
+ reqCacheControl,
207
+ result
208
+ ) {
209
+ if (!result) {
210
+ return handleUncachedResponse(dispatch, globalOpts, cacheKey, handler, opts, reqCacheControl)
211
+ }
212
+
213
+ const now = Date.now()
214
+ if (now > result.deleteAt) {
215
+ // Response is expired, cache store shouldn't have given this to us
216
+ return dispatch(opts, new CacheHandler(globalOpts, cacheKey, handler))
217
+ }
218
+
219
+ const age = Math.round((now - result.cachedAt) / 1000)
220
+ if (reqCacheControl?.['max-age'] && age >= reqCacheControl['max-age']) {
221
+ // Response is considered expired for this specific request
222
+ // https://www.rfc-editor.org/rfc/rfc9111.html#section-5.2.1.1
223
+ return dispatch(opts, handler)
224
+ }
225
+
226
+ // Check if the response is stale
227
+ if (needsRevalidation(result, reqCacheControl)) {
228
+ if (util.isStream(opts.body) && util.bodyLength(opts.body) !== 0) {
229
+ // If body is a stream we can't revalidate...
230
+ // TODO (fix): This could be less strict...
231
+ return dispatch(opts, new CacheHandler(globalOpts, cacheKey, handler))
232
+ }
233
+
234
+ let withinStaleIfErrorThreshold = false
235
+ const staleIfErrorExpiry = result.cacheControlDirectives['stale-if-error'] ?? reqCacheControl?.['stale-if-error']
236
+ if (staleIfErrorExpiry) {
237
+ withinStaleIfErrorThreshold = now < (result.staleAt + (staleIfErrorExpiry * 1000))
238
+ }
239
+
240
+ let headers = {
241
+ ...opts.headers,
242
+ 'if-modified-since': new Date(result.cachedAt).toUTCString()
243
+ }
244
+
245
+ if (result.etag) {
246
+ headers['if-none-match'] = result.etag
247
+ }
248
+
249
+ if (result.vary) {
250
+ headers = {
251
+ ...headers,
252
+ ...result.vary
253
+ }
254
+ }
255
+
256
+ // We need to revalidate the response
257
+ return dispatch(
258
+ {
259
+ ...opts,
260
+ headers
261
+ },
262
+ new CacheRevalidationHandler(
263
+ (success, context) => {
264
+ if (success) {
265
+ sendCachedValue(handler, opts, result, age, context, true)
266
+ } else if (util.isStream(result.body)) {
267
+ result.body.on('error', () => {}).destroy()
268
+ }
269
+ },
270
+ new CacheHandler(globalOpts, cacheKey, handler),
271
+ withinStaleIfErrorThreshold
272
+ )
273
+ )
274
+ }
275
+
276
+ // Dump request body.
277
+ if (util.isStream(opts.body)) {
278
+ opts.body.on('error', () => {}).destroy()
279
+ }
280
+
281
+ sendCachedValue(handler, opts, result, age, null, false)
282
+ }
283
+
284
+ /**
285
+ * @param {import('../../types/cache-interceptor.d.ts').default.CacheOptions} [opts]
286
+ * @returns {import('../../types/dispatcher.d.ts').default.DispatcherComposeInterceptor}
287
+ */
288
+ module.exports = (opts = {}) => {
289
+ const {
290
+ store = new MemoryCacheStore(),
291
+ methods = ['GET'],
292
+ cacheByDefault = undefined,
293
+ type = 'shared'
294
+ } = opts
295
+
296
+ if (typeof opts !== 'object' || opts === null) {
297
+ throw new TypeError(`expected type of opts to be an Object, got ${opts === null ? 'null' : typeof opts}`)
298
+ }
299
+
300
+ assertCacheStore(store, 'opts.store')
301
+ assertCacheMethods(methods, 'opts.methods')
302
+
303
+ if (typeof cacheByDefault !== 'undefined' && typeof cacheByDefault !== 'number') {
304
+ throw new TypeError(`exepcted opts.cacheByDefault to be number or undefined, got ${typeof cacheByDefault}`)
305
+ }
306
+
307
+ if (typeof type !== 'undefined' && type !== 'shared' && type !== 'private') {
308
+ throw new TypeError(`exepcted opts.type to be shared, private, or undefined, got ${typeof type}`)
309
+ }
310
+
311
+ const globalOpts = {
312
+ store,
313
+ methods,
314
+ cacheByDefault,
315
+ type
316
+ }
317
+
318
+ const safeMethodsToNotCache = util.safeHTTPMethods.filter(method => methods.includes(method) === false)
319
+
320
+ return dispatch => {
321
+ return (opts, handler) => {
322
+ if (!opts.origin || safeMethodsToNotCache.includes(opts.method)) {
323
+ // Not a method we want to cache or we don't have the origin, skip
324
+ return dispatch(opts, handler)
325
+ }
326
+
327
+ opts = {
328
+ ...opts,
329
+ headers: normaliseHeaders(opts)
330
+ }
331
+
332
+ const reqCacheControl = opts.headers?.['cache-control']
333
+ ? parseCacheControlHeader(opts.headers['cache-control'])
334
+ : undefined
335
+
336
+ if (reqCacheControl?.['no-store']) {
337
+ return dispatch(opts, handler)
338
+ }
339
+
340
+ /**
341
+ * @type {import('../../types/cache-interceptor.d.ts').default.CacheKey}
342
+ */
343
+ const cacheKey = makeCacheKey(opts)
344
+ const result = store.get(cacheKey)
345
+
346
+ if (result && typeof result.then === 'function') {
347
+ result.then(result => {
348
+ handleResult(dispatch,
349
+ globalOpts,
350
+ cacheKey,
351
+ handler,
352
+ opts,
353
+ reqCacheControl,
354
+ result
355
+ )
356
+ })
357
+ } else {
358
+ handleResult(
359
+ dispatch,
360
+ globalOpts,
361
+ cacheKey,
362
+ handler,
363
+ opts,
364
+ reqCacheControl,
365
+ result
366
+ )
367
+ }
368
+
369
+ return true
370
+ }
371
+ }
372
+ }