@entelligentsia/forgecli 0.7.10 → 0.8.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +74 -0
- package/dist/CHANGELOG-forge-plugin.md +70 -0
- package/dist/CHANGELOG-pi.md +63 -0
- package/dist/bin/argv.d.ts +2 -2
- package/dist/bin/argv.js +10 -0
- package/dist/bin/argv.js.map +1 -1
- package/dist/bin/env-defaults.d.ts +1 -0
- package/dist/bin/env-defaults.js +13 -0
- package/dist/bin/env-defaults.js.map +1 -0
- package/dist/bin/forge.js +9 -0
- package/dist/bin/forge.js.map +1 -1
- package/dist/bin/update-cli.d.ts +9 -0
- package/dist/bin/update-cli.js +120 -0
- package/dist/bin/update-cli.js.map +1 -0
- package/dist/extensions/forgecli/index.js +3 -3
- package/dist/extensions/forgecli/index.js.map +1 -1
- package/dist/extensions/forgecli/update-check.js +1 -1
- package/dist/extensions/forgecli/update-check.js.map +1 -1
- package/dist/extensions/forgecli/whats-new-widget.d.ts +5 -5
- package/dist/extensions/forgecli/whats-new-widget.js +11 -11
- package/dist/extensions/forgecli/whats-new-widget.js.map +1 -1
- package/dist/extensions/forgecli/whats-new.js +6 -5
- package/dist/extensions/forgecli/whats-new.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
- package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts +27 -98
- package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/models.generated.js +62 -132
- package/node_modules/@earendil-works/pi-ai/dist/models.generated.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.js +25 -15
- package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.js +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.js +17 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-completions.js +8 -2
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-completions.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses.js +17 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/simple-options.js +8 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/simple-options.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/package.json +2 -2
- package/node_modules/@earendil-works/pi-coding-agent/CHANGELOG.md +63 -0
- package/node_modules/@earendil-works/pi-coding-agent/README.md +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/cli/config-selector.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/cli/config-selector.js +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/cli/config-selector.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/cli.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/cli.js +6 -10
- package/node_modules/@earendil-works/pi-coding-agent/dist/cli.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/config.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/config.js +12 -3
- package/node_modules/@earendil-works/pi-coding-agent/dist/config.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session.d.ts +1 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session.js +30 -15
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/compaction/compaction.d.ts +3 -3
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/compaction/compaction.js +23 -13
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/package-manager.d.ts +4 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/package-manager.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/package-manager.js +58 -38
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/package-manager.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/slash-commands.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/slash-commands.js +0 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/slash-commands.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/system-prompt.js +3 -2
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/config-selector.d.ts +2 -2
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/config-selector.js +7 -4
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/config-selector.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/interactive-mode.js +6 -2
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/package-manager-cli.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/package-manager-cli.js +3 -4
- package/node_modules/@earendil-works/pi-coding-agent/dist/package-manager-cli.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/utils/changelog.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/utils/changelog.js +2 -2
- package/node_modules/@earendil-works/pi-coding-agent/dist/utils/changelog.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/utils/child-process.d.ts +7 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/utils/child-process.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/utils/child-process.js +60 -7
- package/node_modules/@earendil-works/pi-coding-agent/dist/utils/child-process.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/docs/packages.md +2 -2
- package/node_modules/@earendil-works/pi-coding-agent/docs/settings.md +1 -3
- package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/sandbox/package.json +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/with-deps/package.json +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/package.json +6 -6
- package/node_modules/@earendil-works/pi-tui/package.json +2 -2
- package/node_modules/@protobufjs/fetch/CHANGELOG.md +8 -0
- package/node_modules/@protobufjs/fetch/index.d.ts +7 -7
- package/node_modules/@protobufjs/fetch/index.js +4 -7
- package/node_modules/@protobufjs/fetch/package.json +7 -5
- package/node_modules/@protobufjs/fetch/tests/data/file.txt +1 -0
- package/node_modules/@protobufjs/fetch/tests/index.js +150 -8
- package/node_modules/@protobufjs/fetch/util/fs.js +11 -0
- package/node_modules/@protobufjs/inquire/CHANGELOG.md +8 -0
- package/node_modules/@protobufjs/inquire/index.d.ts +1 -0
- package/node_modules/@protobufjs/inquire/index.js +1 -0
- package/node_modules/@protobufjs/inquire/package.json +1 -1
- package/node_modules/protobufjs/dist/light/protobuf.js +187 -153
- package/node_modules/protobufjs/dist/light/protobuf.js.map +1 -1
- package/node_modules/protobufjs/dist/light/protobuf.min.js +3 -3
- package/node_modules/protobufjs/dist/light/protobuf.min.js.map +1 -1
- package/node_modules/protobufjs/dist/minimal/protobuf.js +14 -5
- package/node_modules/protobufjs/dist/minimal/protobuf.js.map +1 -1
- package/node_modules/protobufjs/dist/minimal/protobuf.min.js +3 -3
- package/node_modules/protobufjs/dist/minimal/protobuf.min.js.map +1 -1
- package/node_modules/protobufjs/dist/protobuf.js +207 -173
- package/node_modules/protobufjs/dist/protobuf.js.map +1 -1
- package/node_modules/protobufjs/dist/protobuf.min.js +3 -3
- package/node_modules/protobufjs/dist/protobuf.min.js.map +1 -1
- package/node_modules/protobufjs/package.json +6 -3
- package/node_modules/protobufjs/src/util/fs.js +11 -0
- package/node_modules/protobufjs/src/util/minimal.js +10 -2
- package/node_modules/protobufjs/src/util.js +1 -1
- package/node_modules/undici/README.md +14 -5
- package/node_modules/undici/docs/docs/api/Client.md +4 -2
- package/node_modules/undici/docs/docs/api/Dispatcher.md +62 -27
- package/node_modules/undici/docs/docs/api/GlobalInstallation.md +7 -5
- package/node_modules/undici/docs/docs/api/H2CClient.md +1 -1
- package/node_modules/undici/docs/docs/api/RedirectHandler.md +14 -9
- package/node_modules/undici/docs/docs/api/RetryAgent.md +0 -1
- package/node_modules/undici/docs/docs/api/RetryHandler.md +12 -14
- package/node_modules/undici/docs/docs/api/SnapshotAgent.md +23 -0
- package/node_modules/undici/docs/docs/best-practices/migrating-from-v7-to-v8.md +231 -0
- package/node_modules/undici/index.js +4 -2
- package/node_modules/undici/lib/api/api-connect.js +13 -11
- package/node_modules/undici/lib/api/api-pipeline.js +26 -13
- package/node_modules/undici/lib/api/api-request.js +45 -21
- package/node_modules/undici/lib/api/api-stream.js +81 -20
- package/node_modules/undici/lib/api/api-upgrade.js +21 -11
- package/node_modules/undici/lib/api/readable.js +3 -2
- package/node_modules/undici/lib/cache/memory-cache-store.js +1 -1
- package/node_modules/undici/lib/cache/sqlite-cache-store.js +6 -4
- package/node_modules/undici/lib/core/connect.js +17 -1
- package/node_modules/undici/lib/core/constants.js +1 -24
- package/node_modules/undici/lib/core/errors.js +2 -2
- package/node_modules/undici/lib/core/request.js +115 -18
- package/node_modules/undici/lib/core/socks5-client.js +24 -9
- package/node_modules/undici/lib/core/socks5-utils.js +32 -23
- package/node_modules/undici/lib/core/symbols.js +1 -0
- package/node_modules/undici/lib/core/util.js +70 -43
- package/node_modules/undici/lib/dispatcher/agent.js +47 -33
- package/node_modules/undici/lib/dispatcher/balanced-pool.js +21 -26
- package/node_modules/undici/lib/dispatcher/client-h1.js +98 -39
- package/node_modules/undici/lib/dispatcher/client-h2.js +603 -272
- package/node_modules/undici/lib/dispatcher/client.js +12 -5
- package/node_modules/undici/lib/dispatcher/dispatcher-base.js +24 -5
- package/node_modules/undici/lib/dispatcher/dispatcher.js +0 -4
- package/node_modules/undici/lib/dispatcher/dispatcher1-wrapper.js +107 -0
- package/node_modules/undici/lib/dispatcher/h2c-client.js +5 -5
- package/node_modules/undici/lib/dispatcher/pool-base.js +28 -10
- package/node_modules/undici/lib/dispatcher/pool.js +31 -6
- package/node_modules/undici/lib/dispatcher/proxy-agent.js +38 -13
- package/node_modules/undici/lib/dispatcher/round-robin-pool.js +31 -9
- package/node_modules/undici/lib/dispatcher/socks5-proxy-agent.js +95 -80
- package/node_modules/undici/lib/global.js +13 -1
- package/node_modules/undici/lib/handler/cache-handler.js +16 -8
- package/node_modules/undici/lib/handler/decorator-handler.js +1 -2
- package/node_modules/undici/lib/handler/redirect-handler.js +5 -51
- package/node_modules/undici/lib/handler/retry-handler.js +15 -2
- package/node_modules/undici/lib/interceptor/cache.js +30 -17
- package/node_modules/undici/lib/interceptor/decompress.js +28 -2
- package/node_modules/undici/lib/interceptor/dns.js +1 -1
- package/node_modules/undici/lib/interceptor/redirect.js +3 -3
- package/node_modules/undici/lib/llhttp/llhttp-wasm.js +1 -1
- package/node_modules/undici/lib/llhttp/llhttp_simd-wasm.js +1 -1
- package/node_modules/undici/lib/mock/mock-agent.js +8 -8
- package/node_modules/undici/lib/mock/mock-call-history.js +15 -15
- package/node_modules/undici/lib/mock/mock-utils.js +37 -22
- package/node_modules/undici/lib/mock/snapshot-agent.js +16 -6
- package/node_modules/undici/lib/mock/snapshot-recorder.js +38 -3
- package/node_modules/undici/lib/util/cache.js +8 -7
- package/node_modules/undici/lib/util/runtime-features.js +3 -34
- package/node_modules/undici/lib/web/cache/cache.js +6 -8
- package/node_modules/undici/lib/web/eventsource/eventsource-stream.js +245 -150
- package/node_modules/undici/lib/web/fetch/body.js +3 -9
- package/node_modules/undici/lib/web/fetch/formdata-parser.js +17 -6
- package/node_modules/undici/lib/web/fetch/formdata.js +21 -2
- package/node_modules/undici/lib/web/fetch/index.js +214 -221
- package/node_modules/undici/lib/web/webidl/index.js +7 -9
- package/node_modules/undici/lib/web/websocket/frame.js +1 -7
- package/node_modules/undici/lib/web/websocket/permessage-deflate.js +13 -31
- package/node_modules/undici/lib/web/websocket/receiver.js +62 -22
- package/node_modules/undici/lib/web/websocket/stream/websocketstream.js +11 -17
- package/node_modules/undici/lib/web/websocket/websocket.js +6 -1
- package/node_modules/undici/package.json +9 -9
- package/node_modules/undici/types/agent.d.ts +0 -2
- package/node_modules/undici/types/client.d.ts +25 -19
- package/node_modules/undici/types/dispatcher.d.ts +7 -27
- package/node_modules/undici/types/dispatcher1-wrapper.d.ts +7 -0
- package/node_modules/undici/types/formdata.d.ts +0 -6
- package/node_modules/undici/types/h2c-client.d.ts +6 -6
- package/node_modules/undici/types/header.d.ts +5 -0
- package/node_modules/undici/types/index.d.ts +3 -1
- package/node_modules/undici/types/interceptors.d.ts +1 -1
- package/node_modules/undici/types/pool.d.ts +0 -2
- package/node_modules/undici/types/proxy-agent.d.ts +2 -2
- package/node_modules/undici/types/round-robin-pool.d.ts +0 -2
- package/node_modules/undici/types/snapshot-agent.d.ts +4 -0
- package/node_modules/undici/types/socks5-proxy-agent.d.ts +2 -2
- package/node_modules/undici/types/webidl.d.ts +0 -1
- package/package.json +7 -8
- package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/custom-provider-anthropic/package-lock.json +0 -24
- package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/sandbox/package-lock.json +0 -92
- package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/with-deps/package-lock.json +0 -31
- package/node_modules/undici/lib/handler/unwrap-handler.js +0 -100
- package/node_modules/undici/lib/handler/wrap-handler.js +0 -105
- package/node_modules/undici/lib/llhttp/.gitkeep +0 -0
- package/node_modules/undici/lib/util/promise.js +0 -28
- package/skills/refresh-kb-links/SKILL.md +0 -217
- package/skills/store-custodian/SKILL.md +0 -163
- package/skills/store-query-grammar/SKILL.md +0 -145
- package/skills/store-query-nlp/SKILL.md +0 -110
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
const Agent = require('../dispatcher/agent')
|
|
4
4
|
const MockAgent = require('./mock-agent')
|
|
5
5
|
const { SnapshotRecorder } = require('./snapshot-recorder')
|
|
6
|
-
const WrapHandler = require('../handler/wrap-handler')
|
|
7
6
|
const { InvalidArgumentError, UndiciError } = require('../core/errors')
|
|
7
|
+
const util = require('../core/util')
|
|
8
8
|
const { validateSnapshotMode } = require('./snapshot-utils')
|
|
9
9
|
|
|
10
10
|
const kSnapshotRecorder = Symbol('kSnapshotRecorder')
|
|
@@ -55,7 +55,9 @@ class SnapshotAgent extends MockAgent {
|
|
|
55
55
|
ignoreHeaders: opts.ignoreHeaders,
|
|
56
56
|
excludeHeaders: opts.excludeHeaders,
|
|
57
57
|
matchBody: opts.matchBody,
|
|
58
|
+
normalizeBody: opts.normalizeBody,
|
|
58
59
|
matchQuery: opts.matchQuery,
|
|
60
|
+
normalizeQuery: opts.normalizeQuery,
|
|
59
61
|
caseSensitive: opts.caseSensitive,
|
|
60
62
|
shouldRecord: opts.shouldRecord,
|
|
61
63
|
shouldPlayback: opts.shouldPlayback,
|
|
@@ -79,7 +81,6 @@ class SnapshotAgent extends MockAgent {
|
|
|
79
81
|
}
|
|
80
82
|
|
|
81
83
|
dispatch (opts, handler) {
|
|
82
|
-
handler = WrapHandler.wrap(handler)
|
|
83
84
|
const mode = this[kSnapshotMode]
|
|
84
85
|
|
|
85
86
|
// Check if URL should be excluded (pass through without mocking/recording)
|
|
@@ -107,8 +108,8 @@ class SnapshotAgent extends MockAgent {
|
|
|
107
108
|
} else {
|
|
108
109
|
// Playback mode but no snapshot found
|
|
109
110
|
const error = new UndiciError(`No snapshot found for ${opts.method || 'GET'} ${opts.path}`)
|
|
110
|
-
if (handler.
|
|
111
|
-
handler.
|
|
111
|
+
if (handler.onResponseError) {
|
|
112
|
+
handler.onResponseError(null, error)
|
|
112
113
|
return
|
|
113
114
|
}
|
|
114
115
|
throw error
|
|
@@ -173,6 +174,10 @@ class SnapshotAgent extends MockAgent {
|
|
|
173
174
|
})
|
|
174
175
|
.then(() => handler.onResponseEnd(controller, trailers))
|
|
175
176
|
.catch((error) => handler.onResponseError(controller, error))
|
|
177
|
+
},
|
|
178
|
+
|
|
179
|
+
onResponseError (controller, error) {
|
|
180
|
+
return handler.onResponseError(controller, error)
|
|
176
181
|
}
|
|
177
182
|
}
|
|
178
183
|
|
|
@@ -192,7 +197,12 @@ class SnapshotAgent extends MockAgent {
|
|
|
192
197
|
try {
|
|
193
198
|
const { response } = snapshot
|
|
194
199
|
|
|
200
|
+
const rawHeaders = response.headers ? util.toRawHeaders(response.headers) : []
|
|
201
|
+
const rawTrailers = response.trailers ? util.toRawHeaders(response.trailers) : []
|
|
202
|
+
|
|
195
203
|
const controller = {
|
|
204
|
+
rawHeaders,
|
|
205
|
+
rawTrailers,
|
|
196
206
|
pause () { },
|
|
197
207
|
resume () { },
|
|
198
208
|
abort (reason) {
|
|
@@ -206,7 +216,7 @@ class SnapshotAgent extends MockAgent {
|
|
|
206
216
|
|
|
207
217
|
handler.onRequestStart(controller)
|
|
208
218
|
|
|
209
|
-
handler.onResponseStart(controller, response.statusCode, response.headers)
|
|
219
|
+
handler.onResponseStart(controller, response.statusCode, response.headers, response.statusMessage)
|
|
210
220
|
|
|
211
221
|
// Body is always stored as base64 string
|
|
212
222
|
const body = Buffer.from(response.body, 'base64')
|
|
@@ -214,7 +224,7 @@ class SnapshotAgent extends MockAgent {
|
|
|
214
224
|
|
|
215
225
|
handler.onResponseEnd(controller, response.trailers)
|
|
216
226
|
} catch (error) {
|
|
217
|
-
handler.
|
|
227
|
+
handler.onResponseError?.(null, error)
|
|
218
228
|
}
|
|
219
229
|
}
|
|
220
230
|
|
|
@@ -46,7 +46,9 @@ const { hashId, isUrlExcludedFactory, normalizeHeaders, createHeaderFilters } =
|
|
|
46
46
|
* @property {Array<string>} [ignoreHeaders=[]] - Headers to ignore for matching
|
|
47
47
|
* @property {Array<string>} [excludeHeaders=[]] - Headers to exclude from matching
|
|
48
48
|
* @property {boolean} [matchBody=true] - Whether to match request body
|
|
49
|
-
* @property {
|
|
49
|
+
* @property {(body: string|Buffer|null|undefined) => string} [normalizeBody] - Function to normalize the body before matching (e.g. strip timestamps)
|
|
50
|
+
* @property {boolean} [matchQuery=true] - Whether to match query parameters
|
|
51
|
+
* @property {(query: URLSearchParams) => string} [normalizeQuery] - Function to normalize query parameters before matching (e.g. strip volatile params)
|
|
50
52
|
* @property {boolean} [caseSensitive=false] - Whether header matching is case-sensitive
|
|
51
53
|
*/
|
|
52
54
|
|
|
@@ -79,6 +81,37 @@ const { hashId, isUrlExcludedFactory, normalizeHeaders, createHeaderFilters } =
|
|
|
79
81
|
* @property {string} timestamp - ISO timestamp of when the snapshot was created
|
|
80
82
|
*/
|
|
81
83
|
|
|
84
|
+
/**
|
|
85
|
+
* Normalizes the URL string used for request matching.
|
|
86
|
+
*
|
|
87
|
+
* @param {URL} url - Parsed request URL
|
|
88
|
+
* @param {boolean} matchQuery - Whether to include query parameters in matching
|
|
89
|
+
* @param {((query: URLSearchParams) => string)|undefined} normalizeQuery - Optional normalization function
|
|
90
|
+
* @returns {string} - URL string for hashing
|
|
91
|
+
*/
|
|
92
|
+
function normalizeUrlForMatching (url, matchQuery, normalizeQuery) {
|
|
93
|
+
if (matchQuery === false) return `${url.origin}${url.pathname}`
|
|
94
|
+
if (normalizeQuery) {
|
|
95
|
+
const normalized = String(normalizeQuery(url.searchParams) ?? '')
|
|
96
|
+
return normalized ? `${url.origin}${url.pathname}?${normalized}` : `${url.origin}${url.pathname}`
|
|
97
|
+
}
|
|
98
|
+
return url.toString()
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Normalizes the body value used for request matching.
|
|
103
|
+
*
|
|
104
|
+
* @param {string|Buffer|null|undefined} body - Raw request body
|
|
105
|
+
* @param {boolean} matchBody - Whether to include the body in matching
|
|
106
|
+
* @param {((body: string|Buffer|null|undefined) => string)|undefined} normalizeBody - Optional normalization function
|
|
107
|
+
* @returns {string} - Body string for hashing
|
|
108
|
+
*/
|
|
109
|
+
function normalizeBodyForMatching (body, matchBody, normalizeBody) {
|
|
110
|
+
if (matchBody === false) return ''
|
|
111
|
+
if (normalizeBody) return String(normalizeBody(body) ?? '')
|
|
112
|
+
return body ? String(body) : ''
|
|
113
|
+
}
|
|
114
|
+
|
|
82
115
|
/**
|
|
83
116
|
* Formats a request for consistent snapshot storage
|
|
84
117
|
* Caches normalized headers to avoid repeated processing
|
|
@@ -99,9 +132,9 @@ function formatRequestKey (opts, headerFilters, matchOptions = {}) {
|
|
|
99
132
|
|
|
100
133
|
return {
|
|
101
134
|
method: opts.method || 'GET',
|
|
102
|
-
url: matchOptions.matchQuery
|
|
135
|
+
url: normalizeUrlForMatching(url, matchOptions.matchQuery, matchOptions.normalizeQuery),
|
|
103
136
|
headers: filterHeadersForMatching(normalized, headerFilters, matchOptions),
|
|
104
|
-
body:
|
|
137
|
+
body: normalizeBodyForMatching(opts.body, matchOptions.matchBody, matchOptions.normalizeBody)
|
|
105
138
|
}
|
|
106
139
|
}
|
|
107
140
|
|
|
@@ -250,7 +283,9 @@ class SnapshotRecorder {
|
|
|
250
283
|
ignoreHeaders: options.ignoreHeaders || [],
|
|
251
284
|
excludeHeaders: options.excludeHeaders || [],
|
|
252
285
|
matchBody: options.matchBody !== false, // default: true
|
|
286
|
+
normalizeBody: options.normalizeBody || undefined,
|
|
253
287
|
matchQuery: options.matchQuery !== false, // default: true
|
|
288
|
+
normalizeQuery: options.normalizeQuery || undefined,
|
|
254
289
|
caseSensitive: options.caseSensitive || false
|
|
255
290
|
}
|
|
256
291
|
|
|
@@ -18,7 +18,7 @@ function makeCacheKey (opts) {
|
|
|
18
18
|
|
|
19
19
|
let fullPath = opts.path || '/'
|
|
20
20
|
|
|
21
|
-
if (opts.query && !pathHasQueryOrFragment(
|
|
21
|
+
if (opts.query && !pathHasQueryOrFragment(fullPath)) {
|
|
22
22
|
fullPath = serializePathWithQuery(fullPath, opts.query)
|
|
23
23
|
}
|
|
24
24
|
|
|
@@ -374,9 +374,11 @@ function assertCacheMethods (methods, name = 'CacheMethods') {
|
|
|
374
374
|
* @returns {string}
|
|
375
375
|
*/
|
|
376
376
|
function makeDeduplicationKey (cacheKey, excludeHeaders) {
|
|
377
|
-
//
|
|
378
|
-
//
|
|
379
|
-
|
|
377
|
+
// Use JSON.stringify to produce a collision-resistant key.
|
|
378
|
+
// Previous format used `:` and `=` delimiters without escaping, which
|
|
379
|
+
// allowed different header sets to produce identical keys (e.g.
|
|
380
|
+
// {a:"x:b=y"} vs {a:"x", b:"y"}). See: https://github.com/nodejs/undici/issues/5012
|
|
381
|
+
const headers = {}
|
|
380
382
|
|
|
381
383
|
if (cacheKey.headers) {
|
|
382
384
|
const sortedHeaders = Object.keys(cacheKey.headers).sort()
|
|
@@ -385,12 +387,11 @@ function makeDeduplicationKey (cacheKey, excludeHeaders) {
|
|
|
385
387
|
if (excludeHeaders?.has(header.toLowerCase())) {
|
|
386
388
|
continue
|
|
387
389
|
}
|
|
388
|
-
|
|
389
|
-
key += `:${header}=${Array.isArray(value) ? value.join(',') : value}`
|
|
390
|
+
headers[header] = cacheKey.headers[header]
|
|
390
391
|
}
|
|
391
392
|
}
|
|
392
393
|
|
|
393
|
-
return
|
|
394
|
+
return JSON.stringify([cacheKey.origin, cacheKey.method, cacheKey.path, headers])
|
|
394
395
|
}
|
|
395
396
|
|
|
396
397
|
module.exports = {
|
|
@@ -6,9 +6,7 @@
|
|
|
6
6
|
const lazyLoaders = {
|
|
7
7
|
__proto__: null,
|
|
8
8
|
'node:crypto': () => require('node:crypto'),
|
|
9
|
-
'node:sqlite': () => require('node:sqlite')
|
|
10
|
-
'node:worker_threads': () => require('node:worker_threads'),
|
|
11
|
-
'node:zlib': () => require('node:zlib')
|
|
9
|
+
'node:sqlite': () => require('node:sqlite')
|
|
12
10
|
}
|
|
13
11
|
|
|
14
12
|
/**
|
|
@@ -27,35 +25,9 @@ function detectRuntimeFeatureByNodeModule (moduleName) {
|
|
|
27
25
|
}
|
|
28
26
|
}
|
|
29
27
|
|
|
30
|
-
/**
|
|
31
|
-
* @param {NodeModuleName} moduleName
|
|
32
|
-
* @param {string} property
|
|
33
|
-
* @returns {boolean}
|
|
34
|
-
*/
|
|
35
|
-
function detectRuntimeFeatureByExportedProperty (moduleName, property) {
|
|
36
|
-
const module = lazyLoaders[moduleName]()
|
|
37
|
-
return typeof module[property] !== 'undefined'
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const runtimeFeaturesByExportedProperty = /** @type {const} */ (['markAsUncloneable', 'zstd'])
|
|
41
|
-
|
|
42
|
-
/** @type {Record<RuntimeFeatureByExportedProperty, [NodeModuleName, string]>} */
|
|
43
|
-
const exportedPropertyLookup = {
|
|
44
|
-
markAsUncloneable: ['node:worker_threads', 'markAsUncloneable'],
|
|
45
|
-
zstd: ['node:zlib', 'createZstdDecompress']
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/** @typedef {typeof runtimeFeaturesByExportedProperty[number]} RuntimeFeatureByExportedProperty */
|
|
49
|
-
|
|
50
28
|
const runtimeFeaturesAsNodeModule = /** @type {const} */ (['crypto', 'sqlite'])
|
|
51
29
|
/** @typedef {typeof runtimeFeaturesAsNodeModule[number]} RuntimeFeatureByNodeModule */
|
|
52
|
-
|
|
53
|
-
const features = /** @type {const} */ ([
|
|
54
|
-
...runtimeFeaturesAsNodeModule,
|
|
55
|
-
...runtimeFeaturesByExportedProperty
|
|
56
|
-
])
|
|
57
|
-
|
|
58
|
-
/** @typedef {typeof features[number]} Feature */
|
|
30
|
+
/** @typedef {RuntimeFeatureByNodeModule} Feature */
|
|
59
31
|
|
|
60
32
|
/**
|
|
61
33
|
* @param {Feature} feature
|
|
@@ -64,9 +36,6 @@ const features = /** @type {const} */ ([
|
|
|
64
36
|
function detectRuntimeFeature (feature) {
|
|
65
37
|
if (runtimeFeaturesAsNodeModule.includes(/** @type {RuntimeFeatureByNodeModule} */ (feature))) {
|
|
66
38
|
return detectRuntimeFeatureByNodeModule(`node:${feature}`)
|
|
67
|
-
} else if (runtimeFeaturesByExportedProperty.includes(/** @type {RuntimeFeatureByExportedProperty} */ (feature))) {
|
|
68
|
-
const [moduleName, property] = exportedPropertyLookup[feature]
|
|
69
|
-
return detectRuntimeFeatureByExportedProperty(moduleName, property)
|
|
70
39
|
}
|
|
71
40
|
throw new TypeError(`unknown feature: ${feature}`)
|
|
72
41
|
}
|
|
@@ -101,7 +70,7 @@ class RuntimeFeatures {
|
|
|
101
70
|
* @param {boolean} value
|
|
102
71
|
*/
|
|
103
72
|
set (feature, value) {
|
|
104
|
-
if (
|
|
73
|
+
if (runtimeFeaturesAsNodeModule.includes(feature) === false) {
|
|
105
74
|
throw new TypeError(`unknown feature: ${feature}`)
|
|
106
75
|
}
|
|
107
76
|
this.#map.set(feature, value)
|
|
@@ -10,8 +10,6 @@ const { cloneResponse, fromInnerResponse, getResponseState } = require('../fetch
|
|
|
10
10
|
const { Request, fromInnerRequest, getRequestState } = require('../fetch/request')
|
|
11
11
|
const { fetching } = require('../fetch/index')
|
|
12
12
|
const { urlIsHttpHttpsScheme, readAllBytes } = require('../fetch/util')
|
|
13
|
-
const { createDeferredPromise } = require('../../util/promise')
|
|
14
|
-
|
|
15
13
|
/**
|
|
16
14
|
* @see https://w3c.github.io/ServiceWorker/#dfn-cache-batch-operation
|
|
17
15
|
* @typedef {Object} CacheBatchOperation
|
|
@@ -153,7 +151,7 @@ class Cache {
|
|
|
153
151
|
requestList.push(r)
|
|
154
152
|
|
|
155
153
|
// 5.6
|
|
156
|
-
const responsePromise =
|
|
154
|
+
const responsePromise = Promise.withResolvers()
|
|
157
155
|
|
|
158
156
|
// 5.7
|
|
159
157
|
fetchControllers.push(fetching({
|
|
@@ -231,7 +229,7 @@ class Cache {
|
|
|
231
229
|
}
|
|
232
230
|
|
|
233
231
|
// 7.5
|
|
234
|
-
const cacheJobPromise =
|
|
232
|
+
const cacheJobPromise = Promise.withResolvers()
|
|
235
233
|
|
|
236
234
|
// 7.6.1
|
|
237
235
|
let errorData = null
|
|
@@ -325,7 +323,7 @@ class Cache {
|
|
|
325
323
|
const clonedResponse = cloneResponse(innerResponse)
|
|
326
324
|
|
|
327
325
|
// 10.
|
|
328
|
-
const bodyReadPromise =
|
|
326
|
+
const bodyReadPromise = Promise.withResolvers()
|
|
329
327
|
|
|
330
328
|
// 11.
|
|
331
329
|
if (innerResponse.body != null) {
|
|
@@ -364,7 +362,7 @@ class Cache {
|
|
|
364
362
|
}
|
|
365
363
|
|
|
366
364
|
// 19.1
|
|
367
|
-
const cacheJobPromise =
|
|
365
|
+
const cacheJobPromise = Promise.withResolvers()
|
|
368
366
|
|
|
369
367
|
// 19.2.1
|
|
370
368
|
let errorData = null
|
|
@@ -427,7 +425,7 @@ class Cache {
|
|
|
427
425
|
|
|
428
426
|
operations.push(operation)
|
|
429
427
|
|
|
430
|
-
const cacheJobPromise =
|
|
428
|
+
const cacheJobPromise = Promise.withResolvers()
|
|
431
429
|
|
|
432
430
|
let errorData = null
|
|
433
431
|
let requestResponses
|
|
@@ -483,7 +481,7 @@ class Cache {
|
|
|
483
481
|
}
|
|
484
482
|
|
|
485
483
|
// 4.
|
|
486
|
-
const promise =
|
|
484
|
+
const promise = Promise.withResolvers()
|
|
487
485
|
|
|
488
486
|
// 5.
|
|
489
487
|
// 5.1
|