@openclaw/discord 2026.6.33 → 2026.6.35
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/dist/action-runtime-api.js +1 -1
- package/dist/{api-CjnGBhM3.js → api-1GXlSrYP.js} +42 -21
- package/dist/api.js +14 -14
- package/dist/{approval-handler.runtime-BWPQrzpP.js → approval-handler.runtime-Dv4p7REU.js} +3 -3
- package/dist/{audit-BwJ_2OjL.js → audit-DEVi9nIs.js} +3 -3
- package/dist/{channel-Ddnonoy4.js → channel-CQIRiosn.js} +15 -15
- package/dist/{channel-actions-CwmIqnYN.js → channel-actions-JziPEcBU.js} +2 -2
- package/dist/{channel-actions.runtime-DvpTfaJ4.js → channel-actions.runtime-D7L47LY3.js} +5 -5
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel.setup-glZ5Y98a.js → channel.setup-oMeR19Cc.js} +2 -2
- package/dist/{components-j6lTZBsT.js → components-_s5UPJqU.js} +1 -1
- package/dist/{conversation-identity-36FFBwm5.js → conversation-identity-B0k94-bz.js} +2 -2
- package/dist/{directory-config-BYMFzL29.js → directory-config-CD1svkyN.js} +1 -1
- package/dist/directory-contract-api.js +1 -1
- package/dist/{directory-live-9JtJCiu8.js → directory-live-DBTsSRxl.js} +5 -5
- package/dist/{handle-action.guild-admin-xxGYrp-I.js → handle-action.guild-admin-CYIFMxh-.js} +2 -2
- package/dist/index.js +1 -1
- package/dist/{manager.runtime-BK6cf2Zu.js → manager.runtime-BZVdGX2d.js} +17 -9
- package/dist/{message-handler-BqpJIavO.js → message-handler-DZd9Bpq8.js} +7 -6
- package/dist/{message-handler.preflight-C90MxCcv.js → message-handler.preflight-Axv9J9EO.js} +12 -11
- package/dist/{message-handler.process-CeQ7Bd_3.js → message-handler.process-CG0zFS-Z.js} +10 -10
- package/dist/{message-utils-CJeAoISH.js → message-utils-Dbuw27gd.js} +1 -1
- package/dist/{outbound-adapter-Dxs6iKEq.js → outbound-adapter-CKC_kmUN.js} +6 -6
- package/dist/pluralkit-CfTReLl3.js +40 -0
- package/dist/{probe-esE_Oqdm.js → probe-DcgZIpyF.js} +3 -2
- package/dist/{probe.runtime-C3Atgpvr.js → probe.runtime-CVwM9L5E.js} +1 -1
- package/dist/{provider-C7376XFH.js → provider-CwwSXIIj.js} +102 -37
- package/dist/{provider-session.runtime-CCdqogGf.js → provider-session.runtime-reBWkqHZ.js} +3 -3
- package/dist/provider.runtime-BsmTLYS_.js +2 -0
- package/dist/{resolve-allowlist-common-3gB2Gpmm.js → resolve-allowlist-common-D7bZqAw3.js} +3 -3
- package/dist/{resolve-channels-B3gQf8QL.js → resolve-channels--oE-RnO6.js} +6 -6
- package/dist/{resolve-users-BO10y5fJ.js → resolve-users-QXo8CXBU.js} +5 -5
- package/dist/{runtime-CFlR3L9X.js → runtime-CF7ramAs.js} +7 -7
- package/dist/runtime-api.actions.js +2 -2
- package/dist/runtime-api.js +19 -19
- package/dist/runtime-api.lookup.js +5 -5
- package/dist/runtime-api.monitor-CzF8MUl_.js +6 -0
- package/dist/runtime-api.monitor.js +5 -5
- package/dist/runtime-api.send.js +5 -5
- package/dist/runtime-api.threads.js +3 -3
- package/dist/{send-JHxfT4Pk.js → send-Bb295iHT.js} +5 -5
- package/dist/{send.components-CN35E2Ck.js → send.components-COkDUO3B.js} +4 -4
- package/dist/{send.outbound-B-cA1Esv.js → send.outbound-B_sk0hNe.js} +3 -3
- package/dist/{send.receipt-CGecJDin.js → send.receipt-Cli6_9Sn.js} +19 -7
- package/dist/{send.shared-vcbfThdy.js → send.shared-BCG7MWnP.js} +2 -2
- package/dist/session-binding-contract-api.js +1 -1
- package/dist/setup-plugin-api.js +1 -1
- package/dist/{subagent-hooks-20wXhVzZ.js → subagent-hooks-CtqoWK4x.js} +2 -2
- package/dist/subagent-hooks-api.js +1 -1
- package/dist/{system-events-DR27TE7p.js → system-events-BxGNk_wE.js} +1 -1
- package/dist/{target-resolver-CDi1gI90.js → target-resolver-BcoK6b0g.js} +2 -2
- package/dist/targets-Q-ZoP7K4.js +3 -0
- package/dist/{thread-bindings-DU4T6nDo.js → thread-bindings-DJ_HT6GJ.js} +4 -4
- package/dist/{thread-bindings.discord-api-CYkr-3Gj.js → thread-bindings.discord-api-OPyjvgyz.js} +4 -4
- package/dist/{thread-bindings.manager-BqWs1UE2.js → thread-bindings.manager-Cd2HAVw_.js} +3 -3
- package/dist/{transcripts-source-D-lBI5ZD.js → transcripts-source-CPf5gURy.js} +1 -1
- package/dist/transcripts-source-api.js +1 -1
- package/dist/{typing-xr05bL-r.js → typing-DY0cwLdg.js} +1 -1
- package/node_modules/undici/README.md +8 -2
- package/node_modules/undici/docs/docs/api/Agent.md +248 -44
- package/node_modules/undici/docs/docs/api/BalancedPool.md +246 -48
- package/node_modules/undici/docs/docs/api/CacheStorage.md +171 -13
- package/node_modules/undici/docs/docs/api/CacheStore.md +294 -98
- package/node_modules/undici/docs/docs/api/Client.md +386 -179
- package/node_modules/undici/docs/docs/api/ClientStats.md +80 -14
- package/node_modules/undici/docs/docs/api/Connector.md +118 -36
- package/node_modules/undici/docs/docs/api/ContentType.md +65 -25
- package/node_modules/undici/docs/docs/api/Cookies.md +122 -71
- package/node_modules/undici/docs/docs/api/Debug.md +34 -18
- package/node_modules/undici/docs/docs/api/DiagnosticsChannel.md +364 -164
- package/node_modules/undici/docs/docs/api/Dispatcher.md +485 -1102
- package/node_modules/undici/docs/docs/api/EnvHttpProxyAgent.md +102 -87
- package/node_modules/undici/docs/docs/api/Errors.md +503 -40
- package/node_modules/undici/docs/docs/api/EventSource.md +298 -32
- package/node_modules/undici/docs/docs/api/Fetch.md +680 -31
- package/node_modules/undici/docs/docs/api/GlobalInstallation.md +78 -98
- package/node_modules/undici/docs/docs/api/H2CClient.md +298 -176
- package/node_modules/undici/docs/docs/api/Interceptors.md +418 -0
- package/node_modules/undici/docs/docs/api/MockAgent.md +333 -314
- package/node_modules/undici/docs/docs/api/MockCallHistory.md +272 -98
- package/node_modules/undici/docs/docs/api/MockCallHistoryLog.md +189 -26
- package/node_modules/undici/docs/docs/api/MockClient.md +151 -33
- package/node_modules/undici/docs/docs/api/MockErrors.md +56 -5
- package/node_modules/undici/docs/docs/api/MockPool.md +321 -258
- package/node_modules/undici/docs/docs/api/Pool.md +235 -43
- package/node_modules/undici/docs/docs/api/PoolStats.md +119 -13
- package/node_modules/undici/docs/docs/api/ProxyAgent.md +179 -160
- package/node_modules/undici/docs/docs/api/RedirectHandler.md +238 -63
- package/node_modules/undici/docs/docs/api/RetryAgent.md +113 -26
- package/node_modules/undici/docs/docs/api/RetryHandler.md +161 -77
- package/node_modules/undici/docs/docs/api/RoundRobinPool.md +166 -72
- package/node_modules/undici/docs/docs/api/SnapshotAgent.md +264 -542
- package/node_modules/undici/docs/docs/api/Socks5ProxyAgent.md +177 -196
- package/node_modules/undici/docs/docs/api/Util.md +68 -11
- package/node_modules/undici/docs/docs/api/WebSocket.md +475 -80
- package/node_modules/undici/docs/docs/api/api-lifecycle.md +100 -32
- package/node_modules/undici/docs/docs/best-practices/client-certificate.md +2 -0
- package/node_modules/undici/docs/docs/best-practices/crawling.md +3 -1
- package/node_modules/undici/docs/docs/best-practices/migrating-from-v7-to-v8.md +6 -4
- package/node_modules/undici/docs/docs/best-practices/mocking-request.md +9 -7
- package/node_modules/undici/docs/docs/best-practices/proxy.md +3 -1
- package/node_modules/undici/docs/docs/best-practices/undici-vs-builtin-fetch.md +10 -8
- package/node_modules/undici/docs/docs/best-practices/writing-tests.md +2 -0
- package/node_modules/undici/docs/docs/{GettingStarted.md → getting-started.md} +22 -19
- package/node_modules/undici/docs/docs/index.md +784 -0
- package/node_modules/undici/docs/docs/site.json +125 -0
- package/node_modules/undici/docs/docs/type-map.json +79 -0
- package/node_modules/undici/lib/api/api-request.js +7 -1
- package/node_modules/undici/lib/api/readable.js +42 -7
- package/node_modules/undici/lib/cache/memory-cache-store.js +56 -11
- package/node_modules/undici/lib/cache/sqlite-cache-store.js +7 -1
- package/node_modules/undici/lib/core/connect.js +16 -2
- package/node_modules/undici/lib/core/errors.js +20 -0
- package/node_modules/undici/lib/core/request.js +14 -3
- package/node_modules/undici/lib/core/symbols.js +3 -0
- package/node_modules/undici/lib/core/util.js +30 -2
- package/node_modules/undici/lib/dispatcher/agent.js +10 -5
- package/node_modules/undici/lib/dispatcher/balanced-pool.js +7 -4
- package/node_modules/undici/lib/dispatcher/client-h1.js +74 -9
- package/node_modules/undici/lib/dispatcher/client-h2.js +483 -151
- package/node_modules/undici/lib/dispatcher/client.js +76 -30
- package/node_modules/undici/lib/dispatcher/dispatcher-base.js +13 -1
- package/node_modules/undici/lib/dispatcher/dispatcher.js +15 -1
- package/node_modules/undici/lib/dispatcher/dispatcher1-wrapper.js +3 -0
- package/node_modules/undici/lib/dispatcher/env-http-proxy-agent.js +37 -8
- package/node_modules/undici/lib/dispatcher/proxy-agent.js +58 -7
- package/node_modules/undici/lib/dispatcher/retry-agent.js +3 -0
- package/node_modules/undici/lib/dispatcher/round-robin-pool.js +1 -1
- package/node_modules/undici/lib/dispatcher/socks5-proxy-agent.js +106 -22
- package/node_modules/undici/lib/global.js +36 -16
- package/node_modules/undici/lib/handler/cache-handler.js +297 -65
- package/node_modules/undici/lib/handler/cache-revalidation-handler.js +13 -3
- package/node_modules/undici/lib/handler/decorator-handler.js +7 -1
- package/node_modules/undici/lib/handler/deduplication-handler.js +12 -6
- package/node_modules/undici/lib/handler/redirect-handler.js +26 -5
- package/node_modules/undici/lib/handler/retry-handler.js +238 -51
- package/node_modules/undici/lib/interceptor/cache.js +221 -58
- package/node_modules/undici/lib/interceptor/decompress.js +124 -15
- package/node_modules/undici/lib/interceptor/deduplicate.js +5 -4
- package/node_modules/undici/lib/interceptor/dns.js +7 -0
- package/node_modules/undici/lib/interceptor/dump.js +10 -23
- package/node_modules/undici/lib/mock/mock-agent.js +13 -1
- package/node_modules/undici/lib/mock/mock-interceptor.js +25 -7
- package/node_modules/undici/lib/mock/mock-utils.js +246 -27
- package/node_modules/undici/lib/util/cache.js +415 -71
- package/node_modules/undici/lib/util/date.js +23 -6
- package/node_modules/undici/lib/web/cookies/parse.js +150 -146
- package/node_modules/undici/lib/web/cookies/util.js +79 -9
- package/node_modules/undici/lib/web/eventsource/eventsource-stream.js +28 -1
- package/node_modules/undici/lib/web/eventsource/eventsource.js +13 -3
- package/node_modules/undici/lib/web/eventsource/util.js +1 -1
- package/node_modules/undici/lib/web/fetch/body.js +2 -1
- package/node_modules/undici/lib/web/fetch/constants.js +1 -1
- package/node_modules/undici/lib/web/fetch/index.js +17 -2
- package/node_modules/undici/lib/web/fetch/request.js +2 -3
- package/node_modules/undici/lib/web/fetch/response.js +1 -3
- package/node_modules/undici/lib/web/fetch/util.js +10 -2
- package/node_modules/undici/lib/web/webidl/index.js +3 -3
- package/node_modules/undici/lib/web/websocket/connection.js +1 -1
- package/node_modules/undici/lib/web/websocket/permessage-deflate.js +5 -0
- package/node_modules/undici/lib/web/websocket/stream/websocketstream.js +8 -10
- package/node_modules/undici/lib/web/websocket/websocket.js +22 -0
- package/node_modules/undici/package.json +4 -4
- package/node_modules/undici/types/client.d.ts +53 -3
- package/node_modules/undici/types/cookies.d.ts +1 -1
- package/node_modules/undici/types/dispatcher.d.ts +3 -3
- package/node_modules/undici/types/errors.d.ts +10 -0
- package/node_modules/undici/types/handlers.d.ts +2 -0
- package/node_modules/undici/types/interceptors.d.ts +2 -0
- package/node_modules/undici/types/mock-agent.d.ts +11 -10
- package/node_modules/undici/types/mock-interceptor.d.ts +5 -1
- package/node_modules/undici/types/proxy-agent.d.ts +7 -0
- package/node_modules/undici/types/socks5-proxy-agent.d.ts +2 -0
- package/npm-shrinkwrap.json +7 -7
- package/package.json +6 -5
- package/dist/pluralkit-DI6RYaVj.js +0 -24
- package/dist/provider.runtime-D1m66kDS.js +0 -2
- package/dist/runtime-api.monitor-4oc58TSk.js +0 -6
- package/dist/targets-C6yd3y8R.js +0 -3
|
@@ -3,16 +3,190 @@
|
|
|
3
3
|
const {
|
|
4
4
|
safeHTTPMethods,
|
|
5
5
|
pathHasQueryOrFragment,
|
|
6
|
-
hasSafeIterator
|
|
6
|
+
hasSafeIterator,
|
|
7
|
+
isValidHTTPToken
|
|
7
8
|
} = require('../core/util')
|
|
8
9
|
|
|
9
10
|
const { serializePathWithQuery } = require('../core/util')
|
|
11
|
+
const { kRequestOrigin } = require('../core/symbols')
|
|
12
|
+
|
|
13
|
+
const MAX_DELTA_SECONDS = 2147483647
|
|
14
|
+
const RESTRICTIVE_DIRECTIVE_NAMES = ['no-store', 'private', 'no-cache']
|
|
15
|
+
const kInvalidCacheControlDirectives = Symbol('invalid cache-control directives')
|
|
16
|
+
|
|
17
|
+
function trimOWS (value) {
|
|
18
|
+
return value.replace(/^[\t ]+|[\t ]+$/g, '')
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function arrayIncludes (array, value) {
|
|
22
|
+
for (let i = 0; i < array.length; i++) {
|
|
23
|
+
if (array[i] === value) {
|
|
24
|
+
return true
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return false
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function trimOWSStart (value) {
|
|
32
|
+
return value.replace(/^[\t ]+/, '')
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function trimOWSEnd (value) {
|
|
36
|
+
return value.replace(/[\t ]+$/, '')
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function findUnescapedQuote (value, start) {
|
|
40
|
+
let escaped = false
|
|
41
|
+
for (let i = start; i < value.length; i++) {
|
|
42
|
+
if (escaped) {
|
|
43
|
+
escaped = false
|
|
44
|
+
} else if (value[i] === '\\') {
|
|
45
|
+
escaped = true
|
|
46
|
+
} else if (value[i] === '"') {
|
|
47
|
+
return i
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return -1
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function splitCacheControlHeaderValue (value) {
|
|
55
|
+
const directives = []
|
|
56
|
+
let start = 0
|
|
57
|
+
let quoteStart = -1
|
|
58
|
+
let inQuote = false
|
|
59
|
+
let escaped = false
|
|
60
|
+
|
|
61
|
+
for (let i = 0; i < value.length; i++) {
|
|
62
|
+
if (inQuote) {
|
|
63
|
+
if (escaped) {
|
|
64
|
+
escaped = false
|
|
65
|
+
} else if (value[i] === '\\') {
|
|
66
|
+
escaped = true
|
|
67
|
+
} else if (value[i] === '"') {
|
|
68
|
+
inQuote = false
|
|
69
|
+
quoteStart = -1
|
|
70
|
+
}
|
|
71
|
+
} else if (value[i] === '"') {
|
|
72
|
+
inQuote = true
|
|
73
|
+
quoteStart = i
|
|
74
|
+
} else if (value[i] === ',') {
|
|
75
|
+
directives.push({ value: value.substring(start, i), fromMalformedQuote: false })
|
|
76
|
+
start = i + 1
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (!inQuote) {
|
|
81
|
+
directives.push({ value: value.substring(start), fromMalformedQuote: false })
|
|
82
|
+
return directives
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const tail = value.substring(start)
|
|
86
|
+
const quoteOffset = quoteStart - start
|
|
87
|
+
let tailStart = 0
|
|
88
|
+
for (let i = 0; i < tail.length; i++) {
|
|
89
|
+
if (tail[i] === ',') {
|
|
90
|
+
directives.push({
|
|
91
|
+
value: tail.substring(tailStart, i),
|
|
92
|
+
fromMalformedQuote: tailStart > quoteOffset
|
|
93
|
+
})
|
|
94
|
+
tailStart = i + 1
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
directives.push({
|
|
99
|
+
value: tail.substring(tailStart),
|
|
100
|
+
fromMalformedQuote: tailStart > quoteOffset
|
|
101
|
+
})
|
|
102
|
+
return directives
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function markInvalidCacheControlDirective (directives, key) {
|
|
106
|
+
let invalidDirectives = directives[kInvalidCacheControlDirectives]
|
|
107
|
+
|
|
108
|
+
if (invalidDirectives === undefined) {
|
|
109
|
+
invalidDirectives = new Set()
|
|
110
|
+
Object.defineProperty(directives, kInvalidCacheControlDirectives, {
|
|
111
|
+
value: invalidDirectives
|
|
112
|
+
})
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
invalidDirectives.add(key)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function hasInvalidCacheControlDirective (directives, key) {
|
|
119
|
+
return directives[kInvalidCacheControlDirectives]?.has(key) === true
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function getMalformedRestrictiveDirectiveName (key) {
|
|
123
|
+
for (const directiveName of RESTRICTIVE_DIRECTIVE_NAMES) {
|
|
124
|
+
if (
|
|
125
|
+
key.startsWith(directiveName) &&
|
|
126
|
+
key.length > directiveName.length &&
|
|
127
|
+
!isValidHTTPToken(key[directiveName.length])
|
|
128
|
+
) {
|
|
129
|
+
return directiveName
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
let tokenOnlyKey = ''
|
|
134
|
+
let hasInvalidTokenChar = false
|
|
135
|
+
for (let i = 0; i < key.length; i++) {
|
|
136
|
+
if (isValidHTTPToken(key[i])) {
|
|
137
|
+
tokenOnlyKey += key[i]
|
|
138
|
+
} else {
|
|
139
|
+
hasInvalidTokenChar = true
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (hasInvalidTokenChar && arrayIncludes(RESTRICTIVE_DIRECTIVE_NAMES, tokenOnlyKey)) {
|
|
144
|
+
return tokenOnlyKey
|
|
145
|
+
}
|
|
146
|
+
}
|
|
10
147
|
|
|
11
148
|
/**
|
|
12
149
|
* @param {import('../../types/dispatcher.d.ts').default.DispatchOptions} opts
|
|
13
150
|
*/
|
|
14
|
-
function
|
|
15
|
-
|
|
151
|
+
function getRequestOrigin (opts) {
|
|
152
|
+
const origin = opts[kRequestOrigin] === undefined
|
|
153
|
+
? opts.origin
|
|
154
|
+
: opts[kRequestOrigin]
|
|
155
|
+
return typeof origin === 'string' || origin instanceof URL
|
|
156
|
+
? origin
|
|
157
|
+
: null
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* @param {import('../../types/dispatcher.d.ts').default.DispatchOptions} opts
|
|
162
|
+
* @param {string|null|undefined} interceptorOrigin
|
|
163
|
+
*/
|
|
164
|
+
function getInterceptorOrigin (opts, interceptorOrigin) {
|
|
165
|
+
const requestOrigin = getRequestOrigin(opts)
|
|
166
|
+
if (interceptorOrigin === undefined) {
|
|
167
|
+
return requestOrigin
|
|
168
|
+
}
|
|
169
|
+
if (interceptorOrigin === null) {
|
|
170
|
+
return null
|
|
171
|
+
}
|
|
172
|
+
if (requestOrigin) {
|
|
173
|
+
try {
|
|
174
|
+
if (new URL(requestOrigin).origin !== interceptorOrigin) {
|
|
175
|
+
return null
|
|
176
|
+
}
|
|
177
|
+
} catch {
|
|
178
|
+
return interceptorOrigin
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return interceptorOrigin
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* @param {import('../../types/dispatcher.d.ts').default.DispatchOptions} opts
|
|
186
|
+
* @param {string|URL|null} [origin]
|
|
187
|
+
*/
|
|
188
|
+
function makeCacheKey (opts, origin = getRequestOrigin(opts)) {
|
|
189
|
+
if (!origin) {
|
|
16
190
|
throw new Error('opts.origin is undefined')
|
|
17
191
|
}
|
|
18
192
|
|
|
@@ -23,13 +197,27 @@ function makeCacheKey (opts) {
|
|
|
23
197
|
}
|
|
24
198
|
|
|
25
199
|
return {
|
|
26
|
-
origin:
|
|
200
|
+
origin: origin.toString(),
|
|
27
201
|
method: opts.method,
|
|
28
202
|
path: fullPath,
|
|
29
203
|
headers: opts.headers
|
|
30
204
|
}
|
|
31
205
|
}
|
|
32
206
|
|
|
207
|
+
function appendHeader (headers, key, val) {
|
|
208
|
+
const headerName = key.toLowerCase()
|
|
209
|
+
const current = headers[headerName]
|
|
210
|
+
const values = Array.isArray(val) ? val : [val]
|
|
211
|
+
|
|
212
|
+
if (current === undefined) {
|
|
213
|
+
headers[headerName] = Array.isArray(val) ? val.slice() : val
|
|
214
|
+
} else if (Array.isArray(current)) {
|
|
215
|
+
current.push(...values)
|
|
216
|
+
} else {
|
|
217
|
+
headers[headerName] = [current, ...values]
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
33
221
|
/**
|
|
34
222
|
* @param {Record<string, string[] | string>}
|
|
35
223
|
* @returns {Record<string, string[] | string>}
|
|
@@ -42,19 +230,61 @@ function normalizeHeaders (opts) {
|
|
|
42
230
|
headers = {}
|
|
43
231
|
|
|
44
232
|
if (hasSafeIterator(opts.headers)) {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
233
|
+
if (Array.isArray(opts.headers)) {
|
|
234
|
+
// Array format: could be flat alternating [k, v, k, v, ...]
|
|
235
|
+
// or array-of-pairs [[k, v], ...]
|
|
236
|
+
const first = opts.headers[0]
|
|
237
|
+
if (Array.isArray(first)) {
|
|
238
|
+
for (const x of opts.headers) {
|
|
239
|
+
if (!Array.isArray(x)) {
|
|
240
|
+
throw new Error('opts.headers is not a valid header map')
|
|
241
|
+
}
|
|
242
|
+
const [key, val] = x
|
|
243
|
+
if (typeof key !== 'string' || typeof val !== 'string') {
|
|
244
|
+
throw new Error('opts.headers is not a valid header map')
|
|
245
|
+
}
|
|
246
|
+
appendHeader(headers, key, val)
|
|
247
|
+
}
|
|
248
|
+
} else {
|
|
249
|
+
// Flat alternating array [k, v, k, v, ...]
|
|
250
|
+
const len = opts.headers.length
|
|
251
|
+
if (len % 2 !== 0) {
|
|
252
|
+
throw new Error('opts.headers is not a valid header map')
|
|
253
|
+
}
|
|
254
|
+
for (let i = 0; i < len; i += 2) {
|
|
255
|
+
const key = opts.headers[i]
|
|
256
|
+
const val = opts.headers[i + 1]
|
|
257
|
+
if (typeof key !== 'string' || (typeof val !== 'string' && !Array.isArray(val))) {
|
|
258
|
+
throw new Error('opts.headers is not a valid header map')
|
|
259
|
+
}
|
|
260
|
+
if (typeof val === 'string') {
|
|
261
|
+
appendHeader(headers, key, val)
|
|
262
|
+
} else {
|
|
263
|
+
const mapped = []
|
|
264
|
+
for (let j = 0; j < val.length; j++) {
|
|
265
|
+
const v = val[j]
|
|
266
|
+
mapped.push(typeof v === 'string' ? v : v.toString('latin1'))
|
|
267
|
+
}
|
|
268
|
+
appendHeader(headers, key, mapped)
|
|
269
|
+
}
|
|
270
|
+
}
|
|
48
271
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
272
|
+
} else {
|
|
273
|
+
// Non-array iterable (e.g. Map) — use original iteration logic
|
|
274
|
+
for (const x of opts.headers) {
|
|
275
|
+
if (!Array.isArray(x)) {
|
|
276
|
+
throw new Error('opts.headers is not a valid header map')
|
|
277
|
+
}
|
|
278
|
+
const [key, val] = x
|
|
279
|
+
if (typeof key !== 'string' || typeof val !== 'string') {
|
|
280
|
+
throw new Error('opts.headers is not a valid header map')
|
|
281
|
+
}
|
|
282
|
+
appendHeader(headers, key, val)
|
|
52
283
|
}
|
|
53
|
-
headers[key.toLowerCase()] = val
|
|
54
284
|
}
|
|
55
285
|
} else {
|
|
56
286
|
for (const key of Object.keys(opts.headers)) {
|
|
57
|
-
headers
|
|
287
|
+
appendHeader(headers, key, opts.headers[key])
|
|
58
288
|
}
|
|
59
289
|
}
|
|
60
290
|
} else {
|
|
@@ -126,29 +356,37 @@ function parseCacheControlHeader (header) {
|
|
|
126
356
|
* @type {import('../../types/cache-interceptor.d.ts').default.CacheControlDirectives}
|
|
127
357
|
*/
|
|
128
358
|
const output = {}
|
|
359
|
+
const invalidNumericDirectives = new Set()
|
|
360
|
+
const invalidNoArgumentDirectives = new Set()
|
|
129
361
|
|
|
130
|
-
|
|
131
|
-
if (Array.isArray(header)) {
|
|
132
|
-
directives = []
|
|
133
|
-
|
|
134
|
-
for (const directive of header) {
|
|
135
|
-
directives.push(...directive.split(','))
|
|
136
|
-
}
|
|
137
|
-
} else {
|
|
138
|
-
directives = header.split(',')
|
|
139
|
-
}
|
|
362
|
+
const directives = splitCacheControlHeaderValue(Array.isArray(header) ? header.join(',') : header)
|
|
140
363
|
|
|
141
364
|
for (let i = 0; i < directives.length; i++) {
|
|
142
|
-
const
|
|
365
|
+
const directiveRecord = directives[i]
|
|
366
|
+
const directive = directiveRecord.value.toLowerCase()
|
|
367
|
+
const fromMalformedQuote = directiveRecord.fromMalformedQuote
|
|
143
368
|
const keyValueDelimiter = directive.indexOf('=')
|
|
144
369
|
|
|
145
370
|
let key
|
|
146
371
|
let value
|
|
372
|
+
let keyHasTrailingWhitespace = false
|
|
373
|
+
let valueHasLeadingWhitespace = false
|
|
147
374
|
if (keyValueDelimiter !== -1) {
|
|
148
|
-
|
|
149
|
-
|
|
375
|
+
const rawKey = directive.substring(0, keyValueDelimiter)
|
|
376
|
+
const rawValue = directive.substring(keyValueDelimiter + 1)
|
|
377
|
+
|
|
378
|
+
keyHasTrailingWhitespace = trimOWSEnd(rawKey) !== rawKey
|
|
379
|
+
valueHasLeadingWhitespace = trimOWSStart(rawValue) !== rawValue
|
|
380
|
+
key = trimOWS(rawKey)
|
|
381
|
+
value = trimOWSStart(rawValue)
|
|
150
382
|
} else {
|
|
151
|
-
key = directive
|
|
383
|
+
key = trimOWS(directive)
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
const malformedRestrictiveDirectiveName = getMalformedRestrictiveDirectiveName(key)
|
|
387
|
+
if (malformedRestrictiveDirectiveName !== undefined) {
|
|
388
|
+
output[malformedRestrictiveDirectiveName] = true
|
|
389
|
+
continue
|
|
152
390
|
}
|
|
153
391
|
|
|
154
392
|
switch (key) {
|
|
@@ -158,7 +396,14 @@ function parseCacheControlHeader (header) {
|
|
|
158
396
|
case 's-maxage':
|
|
159
397
|
case 'stale-while-revalidate':
|
|
160
398
|
case 'stale-if-error': {
|
|
161
|
-
if (
|
|
399
|
+
if (fromMalformedQuote || invalidNumericDirectives.has(key)) {
|
|
400
|
+
continue
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
if (value === undefined || keyHasTrailingWhitespace || valueHasLeadingWhitespace) {
|
|
404
|
+
delete output[key]
|
|
405
|
+
invalidNumericDirectives.add(key)
|
|
406
|
+
markInvalidCacheControlDirective(output, key)
|
|
162
407
|
continue
|
|
163
408
|
}
|
|
164
409
|
|
|
@@ -170,22 +415,37 @@ function parseCacheControlHeader (header) {
|
|
|
170
415
|
value = value.substring(1, value.length - 1)
|
|
171
416
|
}
|
|
172
417
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
418
|
+
if (!/^[0-9]+$/.test(value)) {
|
|
419
|
+
delete output[key]
|
|
420
|
+
invalidNumericDirectives.add(key)
|
|
421
|
+
markInvalidCacheControlDirective(output, key)
|
|
176
422
|
continue
|
|
177
423
|
}
|
|
178
424
|
|
|
179
|
-
|
|
180
|
-
continue
|
|
181
|
-
}
|
|
425
|
+
const parsedValue = Math.min(parseInt(value, 10), MAX_DELTA_SECONDS)
|
|
182
426
|
|
|
183
|
-
|
|
427
|
+
if (key === 'min-fresh') {
|
|
428
|
+
if (!(key in output) || output[key] < parsedValue) {
|
|
429
|
+
output[key] = parsedValue
|
|
430
|
+
}
|
|
431
|
+
} else if (!(key in output) || output[key] > parsedValue) {
|
|
432
|
+
output[key] = parsedValue
|
|
433
|
+
}
|
|
184
434
|
|
|
185
435
|
break
|
|
186
436
|
}
|
|
187
437
|
case 'private':
|
|
188
438
|
case 'no-cache': {
|
|
439
|
+
if (fromMalformedQuote) {
|
|
440
|
+
output[key] = true
|
|
441
|
+
break
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
if (value !== undefined && value.length === 0) {
|
|
445
|
+
output[key] = true
|
|
446
|
+
break
|
|
447
|
+
}
|
|
448
|
+
|
|
189
449
|
if (value) {
|
|
190
450
|
// The private and no-cache directives can be unqualified (aka just
|
|
191
451
|
// `private` or `no-cache`) or qualified (w/ a value). When they're
|
|
@@ -193,45 +453,64 @@ function parseCacheControlHeader (header) {
|
|
|
193
453
|
// `no-cache="header1"`, or `no-cache="header1, header2"`
|
|
194
454
|
// If we're given multiple headers, the comma messes us up since
|
|
195
455
|
// we split the full header by commas. So, let's loop through the
|
|
196
|
-
// remaining parts in front of us until we find one that
|
|
197
|
-
// quote. We can then
|
|
198
|
-
//
|
|
199
|
-
// and continue parsing like normal.
|
|
456
|
+
// remaining parts in front of us until we find one that contains a
|
|
457
|
+
// closing quote. We can then skip the consumed quoted-list fragments and
|
|
458
|
+
// continue parsing like normal.
|
|
200
459
|
// https://www.rfc-editor.org/rfc/rfc9111.html#name-no-cache-2
|
|
201
460
|
if (value[0] === '"') {
|
|
202
461
|
// Something like `no-cache="some-header"` OR `no-cache="some-header, another-header"`.
|
|
462
|
+
value = trimOWSEnd(value)
|
|
203
463
|
|
|
204
|
-
|
|
205
|
-
|
|
464
|
+
let fieldList = ''
|
|
465
|
+
let lastQuotedPart = i
|
|
466
|
+
let foundEndingQuote = false
|
|
467
|
+
const closingQuote = findUnescapedQuote(value, 1)
|
|
206
468
|
|
|
207
|
-
|
|
208
|
-
|
|
469
|
+
if (closingQuote !== -1) {
|
|
470
|
+
fieldList = value.substring(1, closingQuote)
|
|
471
|
+
foundEndingQuote = true
|
|
472
|
+
} else {
|
|
209
473
|
// Something like `no-cache="some-header, another-header"`
|
|
210
474
|
// This can still be something invalid, e.g. `no-cache="some-header, ...`
|
|
475
|
+
const fieldListParts = [value.substring(1)]
|
|
476
|
+
|
|
211
477
|
for (let j = i + 1; j < directives.length; j++) {
|
|
212
|
-
const nextPart = directives[j]
|
|
213
|
-
const
|
|
478
|
+
const nextPart = trimOWS(directives[j].value)
|
|
479
|
+
const closingQuote = findUnescapedQuote(nextPart, 0)
|
|
214
480
|
|
|
215
|
-
|
|
481
|
+
lastQuotedPart = j
|
|
216
482
|
|
|
217
|
-
if (
|
|
483
|
+
if (closingQuote !== -1) {
|
|
484
|
+
fieldListParts.push(nextPart.substring(0, closingQuote))
|
|
218
485
|
foundEndingQuote = true
|
|
219
486
|
break
|
|
220
487
|
}
|
|
488
|
+
|
|
489
|
+
fieldListParts.push(nextPart)
|
|
221
490
|
}
|
|
491
|
+
|
|
492
|
+
fieldList = fieldListParts.join(',')
|
|
222
493
|
}
|
|
223
494
|
|
|
224
|
-
if (foundEndingQuote) {
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
headers[headers.length - 1] = lastHeader
|
|
229
|
-
}
|
|
495
|
+
if (!foundEndingQuote) {
|
|
496
|
+
output[key] = true
|
|
497
|
+
break
|
|
498
|
+
}
|
|
230
499
|
|
|
231
|
-
|
|
232
|
-
|
|
500
|
+
i = lastQuotedPart
|
|
501
|
+
|
|
502
|
+
const headers = fieldList.split(',')
|
|
503
|
+
let validFieldNames = true
|
|
504
|
+
for (let j = 0; j < headers.length; j++) {
|
|
505
|
+
headers[j] = trimOWS(headers[j])
|
|
506
|
+
if (!isValidHTTPToken(headers[j])) {
|
|
507
|
+
validFieldNames = false
|
|
233
508
|
}
|
|
509
|
+
}
|
|
234
510
|
|
|
511
|
+
if (!validFieldNames) {
|
|
512
|
+
output[key] = true
|
|
513
|
+
} else if (output[key] !== true) {
|
|
235
514
|
if (key in output) {
|
|
236
515
|
output[key] = output[key].concat(headers)
|
|
237
516
|
} else {
|
|
@@ -239,13 +518,17 @@ function parseCacheControlHeader (header) {
|
|
|
239
518
|
}
|
|
240
519
|
}
|
|
241
520
|
} else {
|
|
242
|
-
// Something like `no-cache=
|
|
243
|
-
const fieldName = value
|
|
521
|
+
// Something like `no-cache=some-header`
|
|
522
|
+
const fieldName = trimOWS(value)
|
|
244
523
|
|
|
245
|
-
if (
|
|
246
|
-
output[key] =
|
|
247
|
-
} else {
|
|
248
|
-
|
|
524
|
+
if (!isValidHTTPToken(fieldName)) {
|
|
525
|
+
output[key] = true
|
|
526
|
+
} else if (output[key] !== true) {
|
|
527
|
+
if (key in output) {
|
|
528
|
+
output[key] = output[key].concat(fieldName)
|
|
529
|
+
} else {
|
|
530
|
+
output[key] = [fieldName]
|
|
531
|
+
}
|
|
249
532
|
}
|
|
250
533
|
}
|
|
251
534
|
|
|
@@ -254,19 +537,27 @@ function parseCacheControlHeader (header) {
|
|
|
254
537
|
}
|
|
255
538
|
// eslint-disable-next-line no-fallthrough
|
|
256
539
|
case 'public':
|
|
257
|
-
case 'no-store':
|
|
258
540
|
case 'must-revalidate':
|
|
259
541
|
case 'proxy-revalidate':
|
|
260
542
|
case 'immutable':
|
|
261
543
|
case 'no-transform':
|
|
262
544
|
case 'must-understand':
|
|
263
545
|
case 'only-if-cached':
|
|
264
|
-
if (
|
|
546
|
+
if (fromMalformedQuote || invalidNoArgumentDirectives.has(key)) {
|
|
547
|
+
continue
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
if (value !== undefined) {
|
|
265
551
|
// These are qualified (something like `public=...`) when they aren't
|
|
266
|
-
// allowed to be, skip
|
|
552
|
+
// allowed to be, skip all instances of the malformed directive.
|
|
553
|
+
delete output[key]
|
|
554
|
+
invalidNoArgumentDirectives.add(key)
|
|
267
555
|
continue
|
|
268
556
|
}
|
|
269
557
|
|
|
558
|
+
output[key] = true
|
|
559
|
+
break
|
|
560
|
+
case 'no-store':
|
|
270
561
|
output[key] = true
|
|
271
562
|
break
|
|
272
563
|
default:
|
|
@@ -278,31 +569,79 @@ function parseCacheControlHeader (header) {
|
|
|
278
569
|
return output
|
|
279
570
|
}
|
|
280
571
|
|
|
572
|
+
/**
|
|
573
|
+
* @param {string | string[]} varyHeader Vary header from the server
|
|
574
|
+
* @returns {string[]}
|
|
575
|
+
*/
|
|
576
|
+
function splitVaryHeader (varyHeader) {
|
|
577
|
+
const values = Array.isArray(varyHeader) ? varyHeader : [varyHeader]
|
|
578
|
+
const output = []
|
|
579
|
+
|
|
580
|
+
for (let i = 0; i < values.length; i++) {
|
|
581
|
+
const parts = values[i].split(',')
|
|
582
|
+
for (let j = 0; j < parts.length; j++) {
|
|
583
|
+
output.push(parts[j])
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
return output
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
/**
|
|
591
|
+
* @param {string | string[]} varyHeader Vary header from the server
|
|
592
|
+
* @returns {boolean}
|
|
593
|
+
*/
|
|
594
|
+
function hasVaryStar (varyHeader) {
|
|
595
|
+
const values = splitVaryHeader(varyHeader)
|
|
596
|
+
for (let i = 0; i < values.length; i++) {
|
|
597
|
+
if (trimOWS(values[i]).indexOf('*') !== -1) {
|
|
598
|
+
return true
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
return false
|
|
603
|
+
}
|
|
604
|
+
|
|
281
605
|
/**
|
|
282
606
|
* @param {string | string[]} varyHeader Vary header from the server
|
|
283
607
|
* @param {Record<string, string | string[]>} headers Request headers
|
|
284
|
-
* @returns {Record<string, string | string[]>}
|
|
608
|
+
* @returns {Record<string, string | string[] | null> | undefined}
|
|
285
609
|
*/
|
|
286
610
|
function parseVaryHeader (varyHeader, headers) {
|
|
287
|
-
if (
|
|
611
|
+
if (hasVaryStar(varyHeader)) {
|
|
288
612
|
return headers
|
|
289
613
|
}
|
|
290
614
|
|
|
291
615
|
const output = /** @type {Record<string, string | string[] | null>} */ ({})
|
|
292
616
|
|
|
293
|
-
const varyingHeaders =
|
|
294
|
-
? varyHeader.split(',')
|
|
295
|
-
: varyHeader
|
|
617
|
+
const varyingHeaders = splitVaryHeader(varyHeader)
|
|
296
618
|
|
|
297
619
|
for (const header of varyingHeaders) {
|
|
298
|
-
const trimmedHeader = header
|
|
620
|
+
const trimmedHeader = trimOWS(header).toLowerCase()
|
|
621
|
+
|
|
622
|
+
if (trimmedHeader.length === 0) {
|
|
623
|
+
continue
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
if (!isValidHTTPToken(trimmedHeader)) {
|
|
627
|
+
return undefined
|
|
628
|
+
}
|
|
299
629
|
|
|
300
|
-
|
|
630
|
+
const headerValue = headers[trimmedHeader]
|
|
631
|
+
output[trimmedHeader] = Array.isArray(headerValue) ? headerValue.slice() : headerValue ?? null
|
|
301
632
|
}
|
|
302
633
|
|
|
303
634
|
return output
|
|
304
635
|
}
|
|
305
636
|
|
|
637
|
+
/**
|
|
638
|
+
* @param {string | string[]} varyHeader Vary header from the server
|
|
639
|
+
* @returns {boolean}
|
|
640
|
+
*/
|
|
641
|
+
function isInvalidOrWildcardVaryHeader (varyHeader) {
|
|
642
|
+
return hasVaryStar(varyHeader) || parseVaryHeader(varyHeader, {}) === undefined
|
|
643
|
+
}
|
|
644
|
+
|
|
306
645
|
/**
|
|
307
646
|
* Note: this deviates from the spec a little. Empty etags ("", W/"") are valid,
|
|
308
647
|
* however, including them in cached resposnes serves little to no purpose.
|
|
@@ -366,7 +705,7 @@ function assertCacheMethods (methods, name = 'CacheMethods') {
|
|
|
366
705
|
}
|
|
367
706
|
|
|
368
707
|
for (const method of methods) {
|
|
369
|
-
if (!safeHTTPMethods
|
|
708
|
+
if (!arrayIncludes(safeHTTPMethods, method)) {
|
|
370
709
|
throw new TypeError(`element of ${name}-array needs to be one of following values: ${safeHTTPMethods.join(', ')}, got ${method}`)
|
|
371
710
|
}
|
|
372
711
|
}
|
|
@@ -401,12 +740,17 @@ function makeDeduplicationKey (cacheKey, excludeHeaders) {
|
|
|
401
740
|
}
|
|
402
741
|
|
|
403
742
|
module.exports = {
|
|
743
|
+
getInterceptorOrigin,
|
|
744
|
+
getRequestOrigin,
|
|
404
745
|
makeCacheKey,
|
|
405
746
|
normalizeHeaders,
|
|
406
747
|
assertCacheKey,
|
|
407
748
|
assertCacheValue,
|
|
408
749
|
parseCacheControlHeader,
|
|
750
|
+
hasInvalidCacheControlDirective,
|
|
409
751
|
parseVaryHeader,
|
|
752
|
+
hasVaryStar,
|
|
753
|
+
isInvalidOrWildcardVaryHeader,
|
|
410
754
|
isEtagUsable,
|
|
411
755
|
assertCacheMethods,
|
|
412
756
|
assertCacheStore,
|