Repository navigation
Expand file tree
/
Copy pathquality-exceptions.json
More file actions
278 lines (278 loc) · 26.2 KB
/
Copy pathquality-exceptions.json
File metadata and controls
278 lines (278 loc) · 26.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
[
{
"rule": "eslint/no-redeclare",
"scope": "src/index.ts:QueryBuilder",
"rationale": "The published QueryBuilder is both the runtime class and the public generic type. TypeScript keeps values and types in separate declaration spaces, so the pair is one public name, not a redeclaration.",
"evidence": "https://www.typescriptlang.org/docs/handbook/declaration-merging.html describes separate value and type meanings for one name. oxlint's eslint/no-redeclare does not separate them and has no option to. Renaming either half breaks the published API that test/fixtures/public-api-compatibility.d.ts checks."
},
{
"rule": "eslint/no-redeclare",
"scope": "src/index.ts:StorageFileApi",
"rationale": "The published StorageFileApi is both the runtime class and the public type. TypeScript keeps values and types in separate declaration spaces, so the pair is one public name, not a redeclaration.",
"evidence": "https://www.typescriptlang.org/docs/handbook/declaration-merging.html describes separate value and type meanings for one name. oxlint's eslint/no-redeclare does not separate them and has no option to. Renaming either half breaks the published API that test/fixtures/public-api-compatibility.d.ts checks."
},
{
"rule": "unicorn/prefer-number-coercion",
"scope": "src/volcano-fetch.ts:retryAfterSeconds",
"rationale": "Retry-After parsing keeps parseInt's leading-integer semantics. The rule's replacement, Math.trunc(Number(header)), turns '' into 0 and reads '0x10' as 16 and '1e3' as 1000, which would change retryAfter on errors for malformed headers.",
"evidence": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number#number_coercion and https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt document the differing conversions. API errors and generated-client errors share this one parser."
},
{
"rule": "eslint/require-unicode-regexp",
"scope": "scripts/jest-completeness.cts:testNamePattern",
"rationale": "The completeness reporter must select the same tests as Jest's --testNamePattern, which Jest compiles with the i flag only. The u flag rejects patterns Jest accepts, such as a\\-b, and its case folding matches characters Jest's pattern does not.",
"evidence": "jest-circus 30.5.2 builds the filter with new RegExp(testNamePattern, 'i'). https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/unicode documents the stricter u-mode syntax. scripts/jest-completeness.test.mts checks the case-insensitive selection."
},
{
"rule": "unicorn/no-thenable",
"scope": "src/database-query.ts:QueryBuilder.then",
"rationale": "Awaiting a query builder runs the query. That is the published database API (`await volcano.from('posts').select('*')`), so the builder must stay thenable.",
"evidence": "https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-thenable.md targets accidental thenables. docs/database.md documents awaiting query builders, and removing `then` breaks every awaited query."
},
{
"rule": "unicorn/no-thenable",
"scope": "src/database-mutations.ts:MutationBuilder.then",
"rationale": "Awaiting a mutation builder runs the mutation. That is the published database API (`await volcano.insert('posts', row)`), so the builder must stay thenable.",
"evidence": "https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-thenable.md targets accidental thenables. docs/database.md documents awaiting mutation builders, and removing `then` breaks every awaited mutation."
},
{
"rule": "unicorn/no-thenable",
"scope": "__tests__/durable-messages-subscribe-handlers.test.ts:runsReturnedThenables",
"rationale": "Durable message delivery adopts whatever a handler returns through Promise.resolve, so a handler may return any thenable. The test needs a plain object with a then method, not a Promise, to prove a non-Promise thenable's rejection is reported.",
"evidence": "src/durable-message-stream.ts reports handler results with Promise.resolve(result).catch(...). https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise#thenables documents that Promise.resolve adopts thenables. A real Promise passes through Promise.resolve unchanged, so only a plain thenable exercises adoption."
},
{
"rule": "eslint/no-await-in-loop",
"scope": "src/durable-platform-request.ts:postToPlatform.retryTimeout",
"rationale": "postToPlatform retries one request. Each retry first waits out its backoff delay, which starts only after the previous attempt failed with a retryable answer, and stops at the 30-second deadline, so the waits cannot overlap.",
"evidence": "RETRY_DELAYS_MS backs off from 0.5 to 5 seconds and retryTimeout checks the deadline after each sleep. __tests__/durable-approval-deadline.test.ts expects eight attempts by 27.499 seconds and the ninth and last at 27.5."
},
{
"rule": "eslint/no-await-in-loop",
"scope": "src/durable-platform-request.ts:postToPlatform.send",
"rationale": "A retry is sent only once the previous attempt has failed and its backoff has passed; a success or a final refusal ends the loop. Sending attempts in parallel would repeat a request Volcano may already have accepted.",
"evidence": "postToPlatform returns the first successful body and throws a non-retryable failure at once. __tests__/durable-approval-deadline.test.ts counts each attempt against fake time and gives each one only the time left before the deadline."
},
{
"rule": "eslint/no-await-in-loop",
"scope": "src/durable-message-stream.ts:DurableMessageStream.readPages",
"rationale": "Catch-up reads one page at a time: each request asks for the messages after lastSeq, which delivering the previous page advances, so the next page's cursor is unknown until the previous page is delivered.",
"evidence": "readPages sets after = this.lastSeq before each listAfter call. __tests__/durable-messages-subscribe-gaps.test.ts expects the list calls to ask for after 0 and then after 1, and to stop once a page delivers nothing new."
},
{
"rule": "eslint/no-await-in-loop",
"scope": "src/storage-file-objects.ts:deletePaths",
"rationale": "remove() sends one DELETE per path from a caller-supplied list with no size limit. Deleting one path at a time keeps a long list from opening that many requests at once against a rate-limited API, and keeps requests in list order.",
"evidence": "__tests__/storage-mutations.test.ts answers the three deletes of one remove call with 404, 200, and 429 rate_limited from mocks consumed in request order, and expects each failure reported against its path in list order."
},
{
"rule": "eslint/no-await-in-loop",
"scope": "src/storage-resumable.ts:uploadParts",
"rationale": "A resumable upload sends its parts in order. The first failed part aborts the session before any later part is sent, and onProgress reports the uploaded byte count growing after each part; parallel parts would keep uploading into an aborted session.",
"evidence": "uploadParts returns abortFailedPart on the first part error and calls onProgress(end, size) after each part. __tests__/storage-resumable.test.ts checks the slices in order, progress [3/5, 5/5], and the abort without completion after a failed part."
},
{
"rule": "import/max-dependencies",
"scope": "src/volcano-auth.ts:imports",
"rationale": "VolcanoAuth is the SDK's composition root: it wires one module per public sub-API (accounts, database builders, storage, durable, locks, sandboxes) to the bootstrap, transport configuration, facades, and services base class, so its imports track the published client surface.",
"evidence": "test/fixtures/published-api/client.d.ts publishes auth, durable, storage, locks, sandboxes, from, and insert on one VolcanoAuth class. Moving their construction into a pass-through module would hide the same dependencies instead of removing them."
},
{
"rule": "import/max-dependencies",
"scope": "scripts/property-policy.test.mts:imports",
"rationale": "This end-to-end policy test compiles a fixture with Babel, runs Jest on it in a temporary directory, and reads the JSON report, so it needs Node's process, file, module, OS, path, test, and URL APIs as well as Babel and the shared report helpers.",
"evidence": "Eight of its eleven imports are node: built-ins, and the file holds one scenario (a failing property keeps its seed and counterexample); splitting it would separate that scenario's setup from its assertions."
},
{
"rule": "import/max-dependencies",
"scope": "scripts/typescript-policy.test.mts:imports",
"rationale": "This policy test checks every tracked file against the TypeScript projects, Jest discovery, oxlint, oxfmt, and the suppression policy, so it needs the compiler API, the shared lint and suppression checks, and Node's process, file, module, path, test, and URL APIs.",
"evidence": "Seven of its eleven imports are node: built-ins. typecheckedFiles, discoveredTests, requireRootFormatting, requireLinted, and requireUnsuppressed each wrap a different tool, and one test applies them all to the same git ls-files scan."
},
{
"rule": "eslint/no-await-in-loop",
"scope": "__tests__/durable-message-runtime.test.ts:keepsPublishOrder",
"rationale": "The test yields fifty microtask turns one after another so that, on replay, the already answered session resolves before step second starts. Awaiting them together would collapse them into one turn and change the interleaving the test checks.",
"evidence": "The comment above keepsPublishOrder describes the live and replayed orders, and the test expects { published: { id: 'msg-1', seq: 1 }, second: 2 } with exactly one publish request."
},
{
"rule": "eslint/no-await-in-loop",
"scope": "__tests__/durable-messages-subscribe-retries.test.ts:backsOffBetweenRetries",
"rationale": "Fake time has to advance in order, to a millisecond before each backoff delay and then onto it, so the test can check the list call count after each step. Each step depends on the timers the previous step left pending.",
"evidence": "The steps come from the delays [500, 1000, 2000, 4000, 8000, 16000, 30000, 30000]; each asserts toHaveBeenCalledTimes(calls + retries), and the total of ten calls is checked after disconnecting."
},
{
"rule": "eslint/no-await-in-loop",
"scope": "__tests__/support/durable-messages-realtime.ts:until",
"rationale": "until re-checks a condition once per event-loop turn, for at most twenty turns. Each check has to follow the previous turn, or it cannot see the asynchronous work that turn finished.",
"evidence": "Subscribe tests await until(() => reported.mock.calls.length > 0) for handler rejections logged on later turns; settled() resolves on setImmediate and until throws 'condition not reached' after twenty turns."
},
{
"rule": "eslint/no-await-in-loop",
"scope": "__tests__/functions-http.test.ts:reachesResolvedHost",
"rationale": "Invocations two and three must start after the first one has cached the resolved function. Run concurrently they would share one in-flight resolve, which the separate concurrent-invocation test already covers.",
"evidence": "After three sequential invokes the test expects api.targets() to equal ['/functions/resolve?name=my-function'] and functions.targets() to equal ['/', '/', '/']."
},
{
"rule": "eslint/no-await-in-loop",
"scope": "__tests__/functions-http.test.ts:sharesResolution",
"rationale": "Each retry must run after the earlier failed resolve is cached, so the test checks that a failed resolve is cached. Concurrent calls would only share the in-flight request.",
"evidence": "After three sequential invokes of missing-function the test expects api.targets() to equal ['/functions/resolve?name=missing-function']."
},
{
"rule": "eslint/no-await-in-loop",
"scope": "__tests__/realtime-channel-lifecycle-presence.test.ts:ignoresMalformedPresence",
"rationale": "Each malformed presence snapshot must be emitted and the fake clock advanced before the next, because the cases share one client, one channel state, and one fake timer.",
"evidence": "Each refreshPresence call sets client.presenceResult, emits subscribed, and advances fake time by 150 ms, and the test asserts state._presenceState before the next snapshot."
},
{
"rule": "eslint/no-extend-native",
"scope": "__tests__/errors.test.ts:preservesInheritedBrandReceiver",
"rationale": "hasValue boxes a primitive and reads the brand with the primitive as receiver. Only an inherited getter can observe the receiver, and a string's prototype chain holds only String.prototype and Object.prototype, so the test installs one there and removes it in finally.",
"evidence": "src/errors-brand.ts calls Reflect.get(new BoxValue(value), key, value). Without a getter on String.prototype no test fails when the third argument is dropped, and stryker.config.json breaks below a 100% mutation score."
},
{
"rule": "import/no-unassigned-import",
"scope": "examples/nextjs-notes-app/src/app/layout.tsx:RootLayout",
"rationale": "The Next.js App Router loads global CSS only through a side-effect import in a layout; the stylesheet exports nothing to assign, and the root layout is where the example applies its Tailwind styles.",
"evidence": "https://nextjs.org/docs/app/getting-started/css documents global styles as import './global.css' in app/layout. The rule's allow option for CSS would change the pinned .oxlintrc.json."
},
{
"rule": "jsx-a11y/no-autofocus",
"scope": "examples/nextjs-notes-app/src/components/NoteCardEditor.tsx:NoteCardEditor",
"rationale": "The editor replaces the note's view when the user clicks Edit. That Edit button had focus and unmounts, so without autoFocus keyboard focus falls back to the document body instead of moving into the editor the user opened.",
"evidence": "NoteCard renders NoteCardEditor in place of NoteCardView once editor.isEditing is set by the Edit button's handler; the editor never appears on page load."
},
{
"rule": "jsx-a11y/no-autofocus",
"scope": "examples/nextjs-notes-app/src/components/NoteEditorForm.tsx:NoteEditorForm",
"rationale": "The form replaces the collapsed Create a new note button when the user clicks it. That button had focus and unmounts, so without autoFocus keyboard focus falls back to the document body instead of moving into the form the user opened.",
"evidence": "NoteEditor renders NoteEditorForm in place of the collapsed button once its click handler sets isExpanded; the form never appears on page load."
},
{
"rule": "react/memo-dependencies",
"scope": "examples/nextjs-notes-app/src/components/useNoteEditor.ts:useNoteEditor.handleSubmit",
"rationale": "handleSubmit calls onCreate inside a try block whose finally clears isSubmitting, so onCreate is a real dependency. Dropping it would create notes through a stale onCreate after useNotes replaces it for a new user.",
"evidence": "oxlint 1.88.0 reports any identifier used only inside try { } finally { } as an extra dependency: useCallback(async () => { try { await save(); } finally { setBusy(false); } }, [save, setBusy]) is flagged for save."
},
{
"rule": "typescript/no-unsafe-type-assertion",
"scope": "src/volcano-fetch.ts:volcanoFetch",
"rationale": "Human-approved Orval boundary: generated callers supply the complete response type. Validating the unknown payload here would change existing runtime response behavior.",
"evidence": "https://orval.dev/docs/guides/custom-client/ requires a generic custom client. Existing JSON, text, binary, bodyless, and error response tests preserve the generated response contract. Approved by Sean Keever on 2026-09-24."
},
{
"rule": "typescript/no-unnecessary-type-parameters",
"scope": "src/sdk-public-types-functions.ts:Functions.invoke",
"rationale": "Preserves existing caller-specified payload and result type parameters for source-compatible SDK upgrades.",
"evidence": "https://typescript-eslint.io/rules/no-unnecessary-type-parameters/ documents that this rule has no configuration options. Sean Keever approved this declaration-scoped compatibility exception on 2026-09-24."
},
{
"rule": "typescript/no-unnecessary-type-parameters",
"scope": "src/sdk-public-types-durable.ts:Durable.start",
"rationale": "Preserves the published caller-specified durable input type parameter.",
"evidence": "https://typescript-eslint.io/rules/no-unnecessary-type-parameters/ documents that this rule has no configuration options. Sean Keever approved this declaration-scoped compatibility exception on 2026-09-24."
},
{
"rule": "typescript/no-deprecated",
"scope": "src/volcano-auth-facades.ts:authApi.signUpAnonymous",
"rationale": "Auth publishes the deprecated signUpAnonymous alias until the next major release, so the facade must bind the deprecated client method.",
"evidence": "test/fixtures/published-api/auth.d.ts publishes signUpAnonymous on Auth, and src/sdk-public-types-auth-methods.ts marks it @deprecated in favour of signInAnonymously. Removing it is a breaking change."
},
{
"rule": "typescript/no-deprecated",
"scope": "src/volcano-auth-facades.ts:authApi.forgotPassword",
"rationale": "Auth publishes the deprecated forgotPassword alias until the next major release, so the facade must bind the deprecated client method.",
"evidence": "test/fixtures/published-api/auth.d.ts publishes forgotPassword on Auth, and src/sdk-public-types-auth-methods.ts marks it @deprecated in favour of resetPasswordForEmail. Removing it is a breaking change."
},
{
"rule": "typescript/strict-void-return",
"scope": "src/volcano-auth-facades.ts:providerRedirect",
"rationale": "Auth declares signInWithGoogle, signInWithGitHub, signInWithMicrosoft, and signInWithApple as void, but the bound client methods return the redirect URL, which JavaScript callers have always received. Discarding it would change the runtime result.",
"evidence": "test/fixtures/published-api/auth.d.ts declares the four shortcuts as returning void, and signInWithProvider in src/auth-oauth-url.ts returns the URL from signInWithOAuth. Returning string from Auth would change the published API."
},
{
"rule": "typescript/strict-void-return",
"scope": "scripts/audit-dependencies.mts:run",
"rationale": "util.promisify(execFile) resolves with { stdout, stderr } and rejects with an error that carries both, which this script reads. The rule treats promisify's custom-promisify overload, which takes no callback, as a void callback context.",
"evidence": "https://nodejs.org/api/child_process.html#child_processexecfilefile-args-options-callback documents the promisified result. @types/node declares promisify<TCustom>(fn: CustomPromisify<TCustom>): TCustom; the rule fires even when that overload is selected explicitly."
},
{
"rule": "typescript/strict-void-return",
"scope": "scripts/dependency-audit.test.mts:run",
"rationale": "util.promisify(execFile) resolves with { stdout, stderr } and rejects with an error that carries both, which this script reads. The rule treats promisify's custom-promisify overload, which takes no callback, as a void callback context.",
"evidence": "https://nodejs.org/api/child_process.html#child_processexecfilefile-args-options-callback documents the promisified result. @types/node declares promisify<TCustom>(fn: CustomPromisify<TCustom>): TCustom; the rule fires even when that overload is selected explicitly."
},
{
"rule": "typescript/strict-void-return",
"scope": "scripts/test-package-quickstart.mts:run",
"rationale": "util.promisify(execFile) resolves with { stdout, stderr } and rejects with an error that carries both, which this script reads. The rule treats promisify's custom-promisify overload, which takes no callback, as a void callback context.",
"evidence": "https://nodejs.org/api/child_process.html#child_processexecfilefile-args-options-callback documents the promisified result. @types/node declares promisify<TCustom>(fn: CustomPromisify<TCustom>): TCustom; the rule fires even when that overload is selected explicitly."
},
{
"rule": "typescript/no-unnecessary-type-parameters",
"scope": "test/fixtures/published-api/durable.d.ts:Functions.invoke",
"rationale": "The fixture records the published declarations, and removing the type parameter would break the public API that lets callers name it.",
"evidence": "maintainers/type-compatibility.md describes test/fixtures/published-api.d.ts as the frozen consumer regression fixture. public-api-compatibility.d.ts requires dist to match it exactly, so dropping a type parameter here fails that comparison."
},
{
"rule": "typescript/no-unnecessary-type-parameters",
"scope": "test/fixtures/published-api/durable.d.ts:Durable.start",
"rationale": "The fixture records the published declarations, and removing the type parameter would break the public API that lets callers name it.",
"evidence": "maintainers/type-compatibility.md describes test/fixtures/published-api.d.ts as the frozen consumer regression fixture. public-api-compatibility.d.ts requires dist to match it exactly, so dropping a type parameter here fails that comparison."
},
{
"rule": "typescript/no-unnecessary-type-parameters",
"scope": "test/fixtures/public-api-compatibility.d.ts:Exact",
"rationale": "Exact compares two types by asking whether two generic signatures, each using its own type parameter once, are identical. That single use is what makes the check exact for optionality and readonly modifiers.",
"evidence": "https://github.com/microsoft/TypeScript/issues/27024#issuecomment-421529650 describes this equality check. Mutual assignability accepts the optionality changes that maintainers/type-compatibility.md says this fixture must reject."
},
{
"rule": "typescript/no-deprecated",
"scope": "test/fixtures/public-api-compatibility.d.ts:PublishedTypes.InsertBuilder",
"rationale": "The fixture checks that the deprecated InsertBuilder alias is still published unchanged, which it can only do by naming the alias.",
"evidence": "src/sdk-public-types-database.ts marks InsertBuilder @deprecated in favour of MutationBuilder, and test/fixtures/published-api/database.d.ts still publishes it. Without this comparison the alias could change unnoticed before the next major release."
},
{
"rule": "typescript/no-deprecated",
"scope": "test/fixtures/public-api-compatibility.d.ts:PublishedTypes.UpdateBuilder",
"rationale": "The fixture checks that the deprecated UpdateBuilder alias is still published unchanged, which it can only do by naming the alias.",
"evidence": "src/sdk-public-types-database.ts marks UpdateBuilder @deprecated in favour of MutationBuilder, and test/fixtures/published-api/database.d.ts still publishes it. Without this comparison the alias could change unnoticed before the next major release."
},
{
"rule": "typescript/no-deprecated",
"scope": "test/fixtures/public-api-compatibility.d.ts:PublishedTypes.DeleteBuilder",
"rationale": "The fixture checks that the deprecated DeleteBuilder alias is still published unchanged, which it can only do by naming the alias.",
"evidence": "src/sdk-public-types-database.ts marks DeleteBuilder @deprecated in favour of MutationBuilder, and test/fixtures/published-api/database.d.ts still publishes it. Without this comparison the alias could change unnoticed before the next major release."
},
{
"rule": "typescript/no-deprecated",
"scope": "test/fixtures/public-api-compatibility.d.ts:EsmPublishedTypes.InsertBuilder",
"rationale": "The fixture checks that the deprecated InsertBuilder alias is still published unchanged, which it can only do by naming the alias.",
"evidence": "src/sdk-public-types-database.ts marks InsertBuilder @deprecated in favour of MutationBuilder, and test/fixtures/published-api/database.d.ts still publishes it. Without this comparison the alias could change unnoticed before the next major release."
},
{
"rule": "typescript/no-deprecated",
"scope": "test/fixtures/public-api-compatibility.d.ts:EsmPublishedTypes.UpdateBuilder",
"rationale": "The fixture checks that the deprecated UpdateBuilder alias is still published unchanged, which it can only do by naming the alias.",
"evidence": "src/sdk-public-types-database.ts marks UpdateBuilder @deprecated in favour of MutationBuilder, and test/fixtures/published-api/database.d.ts still publishes it. Without this comparison the alias could change unnoticed before the next major release."
},
{
"rule": "typescript/no-deprecated",
"scope": "test/fixtures/public-api-compatibility.d.ts:EsmPublishedTypes.DeleteBuilder",
"rationale": "The fixture checks that the deprecated DeleteBuilder alias is still published unchanged, which it can only do by naming the alias.",
"evidence": "src/sdk-public-types-database.ts marks DeleteBuilder @deprecated in favour of MutationBuilder, and test/fixtures/published-api/database.d.ts still publishes it. Without this comparison the alias could change unnoticed before the next major release."
},
{
"rule": "eslint/no-await-in-loop",
"scope": "examples/durable-order-pipeline/volcano/functions/orders-api/index.js:submitOrder",
"rationale": "Order items are inserted one at a time so the first failed insert stops the order there, and the items after it are never written.",
"evidence": "Inserting them concurrently would write every valid item before the failure surfaced, leaving more orphaned order_items rows behind a request that still fails, and would send one request per item at once."
},
{
"rule": "pnpm audit",
"scope": "GHSA-gcqx-w48m-w2h4:deepmerge@4.3.1",
"rationale": "deepmerge 4.3.1 is the latest release and has no fix. It is reached only through Jest (jest-config), which merges this repository's own Jest configuration: config defaults with overrides, and a preset's globals. No caller input reaches it, and the SDK package does not depend on it.",
"evidence": "https://github.com/advisories/GHSA-gcqx-w48m-w2h4 lists no patched version; npm lists 4.3.1 as latest. jest-config 30.5.2 calls deepmerge only in mergeConfig and for preset globals. Approved by Marco Palladino on 2026-10-28. Remove this entry when deepmerge publishes a fix; the audit fails while it names an advisory pnpm no longer reports."
}
]