From 68e930a7caeed8f69dd59dfde12ec39135fdb6e4 Mon Sep 17 00:00:00 2001
From: will Farrell
-
+
-
+
AWS service streams for CloudWatch Logs, DynamoDB, DynamoDB Streams, Kinesis, Lambda, S3, SNS, and SQS.
@@ -18,10 +18,10 @@
-
+
-
+
You can read the documentation at: https://datastream.js.org
diff --git a/packages/aws/client.js b/packages/aws/client.js index 17b665c..f5e2040 100644 --- a/packages/aws/client.js +++ b/packages/aws/client.js @@ -1,11 +1,30 @@ // Copyright 2026 will Farrell, and datastream contributors. // SPDX-License-Identifier: MIT + +// AWS regions that expose FIPS 140-2/140-3 validated endpoints. This includes +// the US/Canada commercial regions and BOTH GovCloud regions (which most need +// FIPS and were previously, incorrectly, excluded). +const fipsRegions = new Set([ + "us-east-1", + "us-east-2", + "us-west-1", + "us-west-2", + "ca-central-1", + "ca-west-1", + "us-gov-east-1", + "us-gov-west-1", +]); + +export const awsRegionSupportsFips = (region) => fipsRegions.has(region); + export const awsClientDefaults = { - useFipsEndpoint: [ - "us-east-1", - "us-east-2", - "us-west-1", - "us-west-2", - "ca-central-1", - ].includes(process.env.AWS_REGION), + // Lazy getter so AWS_REGION is resolved when a client is constructed rather + // than frozen at module-import time (test harnesses / lazy config set it + // after import). + get useFipsEndpoint() { + // Guard the global `process` access so this shared module can also be + // imported in non-node runtimes (browsers/edge) where `process` is + // undefined; there it simply resolves to the non-FIPS default. + return awsRegionSupportsFips(globalThis.process?.env?.AWS_REGION); + }, }; diff --git a/packages/aws/client.test.js b/packages/aws/client.test.js new file mode 100644 index 0000000..13fee9e --- /dev/null +++ b/packages/aws/client.test.js @@ -0,0 +1,110 @@ +import { deepStrictEqual } from "node:assert"; +import test from "node:test"; + +let variant = "unknown"; +for (const execArgv of process.execArgv) { + const flag = "--conditions="; + if (execArgv.includes(flag)) { + variant = execArgv.replace(flag, ""); + } +} + +// client.js has no build step (shipped as source); import it directly. +const { awsClientDefaults, awsRegionSupportsFips } = await import( + `file://${new URL("./client.js", import.meta.url).pathname}` +); + +test(`${variant}: awsClientDefaults.useFipsEndpoint resolves AWS_REGION lazily`, (_t) => { + const original = process.env.AWS_REGION; + try { + process.env.AWS_REGION = "eu-west-1"; + deepStrictEqual(awsClientDefaults.useFipsEndpoint, false); + + // Changing AWS_REGION after import must be reflected (not frozen at import) + process.env.AWS_REGION = "us-east-1"; + deepStrictEqual(awsClientDefaults.useFipsEndpoint, true); + } finally { + if (original === undefined) { + delete process.env.AWS_REGION; + } else { + process.env.AWS_REGION = original; + } + } +}); + +test(`${variant}: awsRegionSupportsFips includes GovCloud regions`, (_t) => { + deepStrictEqual(awsRegionSupportsFips("us-gov-east-1"), true); + deepStrictEqual(awsRegionSupportsFips("us-gov-west-1"), true); + deepStrictEqual(awsRegionSupportsFips("ca-central-1"), true); + deepStrictEqual(awsRegionSupportsFips("eu-west-1"), false); + deepStrictEqual(awsRegionSupportsFips(undefined), false); +}); + +// In a browser/edge runtime `process` is undefined; reading process.env +// directly throws ReferenceError at module load / first client construction. +// The getter must tolerate a missing `process` global (web parity). +test(`${variant}: awsClientDefaults.useFipsEndpoint does not throw when process is undefined (browser)`, (_t) => { + const original = globalThis.process; + try { + // Simulate a browser global scope where `process` does not exist. + globalThis.process = undefined; + deepStrictEqual(awsClientDefaults.useFipsEndpoint, false); + } finally { + globalThis.process = original; + } +}); + +// client.js is shipped as raw source (no build step; not an export), so there is +// no client.node.mjs to import. Exercise the same source module to assert the +// full FIPS region set, the lookup function and the lazy getter. +const built = await import( + `file://${new URL("./client.js", import.meta.url).pathname}` +); + +test(`${variant}: built awsRegionSupportsFips matches the exact FIPS region set`, (_t) => { + // Every region that must be FIPS-capable (kills StringLiteral mutants that + // blank an individual region, and the Set/array-declaration mutants). + for (const region of [ + "us-east-1", + "us-east-2", + "us-west-1", + "us-west-2", + "ca-central-1", + "ca-west-1", + "us-gov-east-1", + "us-gov-west-1", + ]) { + deepStrictEqual(built.awsRegionSupportsFips(region), true); + } + // Regions NOT in the set must be false (kills the `() => undefined` mutant, + // which would make every lookup falsy/undefined rather than a real boolean). + deepStrictEqual(built.awsRegionSupportsFips("eu-west-1"), false); + deepStrictEqual(built.awsRegionSupportsFips("ap-southeast-2"), false); + deepStrictEqual(built.awsRegionSupportsFips(undefined), false); +}); + +test(`${variant}: built awsClientDefaults.useFipsEndpoint reflects AWS_REGION lazily`, (_t) => { + const original = process.env.AWS_REGION; + try { + process.env.AWS_REGION = "us-west-1"; + deepStrictEqual(built.awsClientDefaults.useFipsEndpoint, true); + process.env.AWS_REGION = "eu-central-1"; + deepStrictEqual(built.awsClientDefaults.useFipsEndpoint, false); + } finally { + if (original === undefined) { + delete process.env.AWS_REGION; + } else { + process.env.AWS_REGION = original; + } + } +}); + +test(`${variant}: built awsClientDefaults.useFipsEndpoint tolerates a missing process global`, (_t) => { + const original = globalThis.process; + try { + globalThis.process = undefined; + deepStrictEqual(built.awsClientDefaults.useFipsEndpoint, false); + } finally { + globalThis.process = original; + } +}); diff --git a/packages/aws/cloudwatch-logs.js b/packages/aws/cloudwatch-logs.js index 90c1bb0..46290b3 100644 --- a/packages/aws/cloudwatch-logs.js +++ b/packages/aws/cloudwatch-logs.js @@ -5,6 +5,7 @@ import { FilterLogEventsCommand, GetLogEventsCommand, } from "@aws-sdk/client-cloudwatch-logs"; +import { timeout } from "@datastream/core"; import { awsClientDefaults } from "./client.js"; let client = new CloudWatchLogsClient(awsClientDefaults); @@ -19,7 +20,6 @@ export const awsCloudWatchLogsGetLogEventsStream = async ( const { pollingActive, pollingDelay = 1000, ...cwlOptions } = options; cwlOptions.startFromHead ??= true; async function* command(opts) { - let previousToken; let expectMore = true; while (expectMore) { const response = await client.send(new GetLogEventsCommand(opts), { @@ -29,16 +29,18 @@ export const awsCloudWatchLogsGetLogEventsStream = async ( for (const item of events) { yield item; } - const tokenUnchanged = - response.nextForwardToken === previousToken || - response.nextForwardToken === opts.nextToken; - previousToken = response.nextForwardToken; + // CloudWatch echoes the token you sent (opts.nextToken) back as + // nextForwardToken once there are no further events, so an unchanged + // token is the end-of-page / caught-up signal. + const tokenUnchanged = response.nextForwardToken === opts.nextToken; opts.nextToken = response.nextForwardToken; if (tokenUnchanged) { if (pollingActive) { if (pollingDelay > 0) { - await new Promise((resolve) => setTimeout(resolve, pollingDelay)); + // Abortable idle wait: rejects immediately and clears the + // timer when streamOptions.signal aborts mid-delay. + await timeout(pollingDelay, { signal: streamOptions.signal }); } } else { expectMore = false; diff --git a/packages/aws/cloudwatch-logs.test.js b/packages/aws/cloudwatch-logs.test.js index 40c1342..dd4ec33 100644 --- a/packages/aws/cloudwatch-logs.test.js +++ b/packages/aws/cloudwatch-logs.test.js @@ -1,11 +1,11 @@ -import { deepStrictEqual } from "node:assert"; +import { deepStrictEqual, rejects } from "node:assert"; import test from "node:test"; import { CloudWatchLogsClient, FilterLogEventsCommand, GetLogEventsCommand, } from "@aws-sdk/client-cloudwatch-logs"; -import { +import cwlDefault, { awsCloudWatchLogsFilterLogEventsStream, awsCloudWatchLogsGetLogEventsStream, awsCloudWatchLogsSetClient, @@ -152,6 +152,41 @@ test(`${variant}: awsCloudWatchLogsGetLogEventsStream should delay polling when deepStrictEqual(output, [{ message: "log1" }]); }); +test(`${variant}: awsCloudWatchLogsGetLogEventsStream should abort the idle poll delay on signal`, async (_t) => { + const client = mockClient(CloudWatchLogsClient); + awsCloudWatchLogsSetClient(client); + + // Same token every call => tokenUnchanged => enters the idle poll delay. + client.on(GetLogEventsCommand).resolves({ + events: [], + nextForwardToken: "same-token", + }); + + const controller = new AbortController(); + const options = { + logGroupName: "/test/group", + logStreamName: "stream1", + pollingActive: true, + pollingDelay: 60_000, + }; + const stream = await awsCloudWatchLogsGetLogEventsStream(options, { + signal: controller.signal, + }); + + const consuming = (async () => { + for await (const _item of stream) { + // no events ever arrive + } + })(); + + await new Promise((resolve) => setImmediate(resolve)); + controller.abort(); + + await rejects(consuming, (error) => { + return error.cause?.code === "AbortError" || /Abort/i.test(error.message); + }); +}); + // --- FilterLogEventsStream --- test(`${variant}: awsCloudWatchLogsFilterLogEventsStream should get events`, async (_t) => { @@ -222,3 +257,208 @@ test(`${variant}: awsCloudWatchLogsGetLogEventsStream should pass signal to clie const calls = client.commandCalls(GetLogEventsCommand); deepStrictEqual(calls[0].args[1]?.abortSignal, controller.signal); }); + +// *** startFromHead default & options passthrough *** // +test(`${variant}: awsCloudWatchLogsGetLogEventsStream defaults startFromHead to true`, async (_t) => { + const client = mockClient(CloudWatchLogsClient); + awsCloudWatchLogsSetClient(client); + client + .on(GetLogEventsCommand) + .resolves({ events: [], nextForwardToken: "t" }); + + const options = { logGroupName: "g", logStreamName: "s" }; + const stream = await awsCloudWatchLogsGetLogEventsStream(options); + await streamToArray(stream); + + const input = client.commandCalls(GetLogEventsCommand)[0].args[0].input; + // Defaulted via `??=`: a `&&=` mutant would leave it undefined (because + // undefined &&= true stays undefined). + deepStrictEqual(input.startFromHead, true); + // Caller options are passed through to the command. + deepStrictEqual(input.logGroupName, "g"); + deepStrictEqual(input.logStreamName, "s"); +}); + +test(`${variant}: awsCloudWatchLogsGetLogEventsStream keeps an explicit startFromHead=false`, async (_t) => { + const client = mockClient(CloudWatchLogsClient); + awsCloudWatchLogsSetClient(client); + client + .on(GetLogEventsCommand) + .resolves({ events: [], nextForwardToken: "t" }); + + const options = { + logGroupName: "g", + logStreamName: "s", + startFromHead: false, + }; + const stream = await awsCloudWatchLogsGetLogEventsStream(options); + await streamToArray(stream); + + // `??=` must NOT overwrite an explicit false. A plain `=` mutant would force + // it back to true. + const input = client.commandCalls(GetLogEventsCommand)[0].args[0].input; + deepStrictEqual(input.startFromHead, false); +}); + +test(`${variant}: awsCloudWatchLogsFilterLogEventsStream passes options through and paginates on nextToken`, async (_t) => { + const client = mockClient(CloudWatchLogsClient); + awsCloudWatchLogsSetClient(client); + client + .on(FilterLogEventsCommand) + .resolvesOnce({ events: [{ message: "a" }], nextToken: "n2" }) + .resolvesOnce({ events: [{ message: "b" }] }); + + const options = { logGroupName: "g", filterPattern: "ERROR" }; + const stream = await awsCloudWatchLogsFilterLogEventsStream(options); + const output = await streamToArray(stream); + + deepStrictEqual(output, [{ message: "a" }, { message: "b" }]); + const calls = client.commandCalls(FilterLogEventsCommand); + // Two calls: pagination continued because the first response had a nextToken + // (kills the `expectMore = !!nextToken` related behavior) and stopped when the + // second had none. + deepStrictEqual(calls.length, 2); + // Options spread through to the command (kills the `command({})` mutant). + deepStrictEqual(calls[0].args[0].input.logGroupName, "g"); + deepStrictEqual(calls[0].args[0].input.filterPattern, "ERROR"); +}); + +test(`${variant}: awsCloudWatchLogsFilterLogEventsStream stops after a single page when no nextToken`, async (_t) => { + const client = mockClient(CloudWatchLogsClient); + awsCloudWatchLogsSetClient(client); + // No nextToken on the only response => exactly one call. + client.on(FilterLogEventsCommand).resolves({ events: [{ message: "a" }] }); + + const stream = await awsCloudWatchLogsFilterLogEventsStream({ + logGroupName: "g", + }); + const output = await streamToArray(stream); + + deepStrictEqual(output, [{ message: "a" }]); + deepStrictEqual(client.commandCalls(FilterLogEventsCommand).length, 1); +}); + +test(`${variant}: awsCloudWatchLogsFilterLogEventsStream forwards abortSignal to client.send`, async (_t) => { + const client = mockClient(CloudWatchLogsClient); + awsCloudWatchLogsSetClient(client); + client.on(FilterLogEventsCommand).resolves({ events: [{ message: "a" }] }); + + const controller = new AbortController(); + const stream = await awsCloudWatchLogsFilterLogEventsStream( + { logGroupName: "g" }, + { signal: controller.signal }, + ); + await streamToArray(stream); + + const calls = client.commandCalls(FilterLogEventsCommand); + deepStrictEqual(calls[0].args[1]?.abortSignal, controller.signal); +}); + +// *** setClient swap *** // +test(`${variant}: awsCloudWatchLogsSetClient routes to the new client`, async (_t) => { + const first = mockClient(CloudWatchLogsClient); + awsCloudWatchLogsSetClient(first); + first.on(FilterLogEventsCommand).resolves({ events: [] }); + + const second = mockClient(CloudWatchLogsClient); + second.on(FilterLogEventsCommand).resolves({ events: [] }); + awsCloudWatchLogsSetClient(second); + + const stream = await awsCloudWatchLogsFilterLogEventsStream({ + logGroupName: "g", + }); + await streamToArray(stream); + + deepStrictEqual(second.commandCalls(FilterLogEventsCommand).length, 1); + deepStrictEqual(first.commandCalls(FilterLogEventsCommand).length, 0); +}); + +// setClient must STORE the passed client (mockClient hides instance identity via +// prototype patching). A plain stub proves the stored reference is used; a +// `setClient(){}` mutant leaves the prior client in place. +test(`${variant}: awsCloudWatchLogsSetClient stores the passed client reference`, async (_t) => { + let calls = 0; + const stub = { + send: async () => { + calls++; + return { events: [{ message: "stub" }] }; + }, + }; + awsCloudWatchLogsSetClient(stub); + + const stream = await awsCloudWatchLogsFilterLogEventsStream({ + logGroupName: "g", + }); + const output = await streamToArray(stream); + + deepStrictEqual(output, [{ message: "stub" }]); + deepStrictEqual(calls, 1); +}); + +// GetLogEvents stops as soon as nextForwardToken equals the token that was sent +// (opts.nextToken), even on the very first call when the caller resumes from a +// known token. Pins `nextForwardToken === opts.nextToken` (a `false`/always-loop +// mutant would never stop; this also kills the unchanged-token guard). +test(`${variant}: awsCloudWatchLogsGetLogEventsStream stops when the echoed token equals the sent token`, async (_t) => { + const client = mockClient(CloudWatchLogsClient); + awsCloudWatchLogsSetClient(client); + // Caller resumes from "tokenX"; CloudWatch immediately echoes it back -> done. + client.on(GetLogEventsCommand).resolves({ + events: [{ message: "log1" }], + nextForwardToken: "tokenX", + }); + + const options = { + logGroupName: "g", + logStreamName: "s", + nextToken: "tokenX", + }; + const stream = await awsCloudWatchLogsGetLogEventsStream(options); + const output = await streamToArray(stream); + + deepStrictEqual(output, [{ message: "log1" }]); + // Exactly one call: the echoed token matched the sent token on the first page. + deepStrictEqual(client.commandCalls(GetLogEventsCommand).length, 1); +}); + +// pollingActive with pollingDelay === 0 must NOT schedule a timer: the +// `pollingDelay > 0` guard is false. A `true` or `>= 0` mutant would await +// timeout(0); under un-ticked mock timers the consumer would never reach the +// later (changed-token) event. +test(`${variant}: awsCloudWatchLogsGetLogEventsStream pollingDelay 0 schedules no timer`, async (t) => { + t.mock.timers.enable({ apis: ["setTimeout"] }); + const client = mockClient(CloudWatchLogsClient); + awsCloudWatchLogsSetClient(client); + client + .on(GetLogEventsCommand) + // caught-up page: token unchanged from the (undefined) sent token? No - + // send a repeated token so tokenUnchanged is true and we enter the polling + // branch, then a fresh token + event without any timer tick. + .resolvesOnce({ events: [], nextForwardToken: "t1" }) + .resolvesOnce({ events: [], nextForwardToken: "t1" }) + .resolvesOnce({ events: [{ message: "log1" }], nextForwardToken: "t2" }) + .resolves({ events: [], nextForwardToken: "t2" }); + + const options = { + logGroupName: "g", + logStreamName: "s", + pollingActive: true, + pollingDelay: 0, + }; + const stream = await awsCloudWatchLogsGetLogEventsStream(options); + + const output = []; + for await (const item of stream) { + output.push(item); + if (output.length >= 1) break; + } + deepStrictEqual(output, [{ message: "log1" }]); +}); + +test(`${variant}: cloudwatch-logs default export exposes all stream functions`, (_t) => { + deepStrictEqual(Object.keys(cwlDefault).sort(), [ + "filterLogEventsStream", + "getLogEventsStream", + "setClient", + ]); +}); diff --git a/packages/aws/dynamodb-streams.js b/packages/aws/dynamodb-streams.js index a1c219f..cf06704 100644 --- a/packages/aws/dynamodb-streams.js +++ b/packages/aws/dynamodb-streams.js @@ -4,6 +4,7 @@ import { DynamoDBStreamsClient, GetRecordsCommand, } from "@aws-sdk/client-dynamodb-streams"; +import { timeout } from "@datastream/core"; import { awsClientDefaults } from "./client.js"; let client = new DynamoDBStreamsClient(awsClientDefaults); @@ -30,7 +31,9 @@ export const awsDynamoDBStreamsGetRecordsStream = async ( expectMore = opts.ShardIterator !== null && (pollingActive || records.length > 0); if (pollingActive && records.length === 0 && pollingDelay > 0) { - await new Promise((resolve) => setTimeout(resolve, pollingDelay)); + // Abortable idle wait: rejects immediately and clears the timer + // when streamOptions.signal aborts mid-delay. + await timeout(pollingDelay, { signal: streamOptions.signal }); } } } diff --git a/packages/aws/dynamodb-streams.test.js b/packages/aws/dynamodb-streams.test.js index 4af7917..3a05547 100644 --- a/packages/aws/dynamodb-streams.test.js +++ b/packages/aws/dynamodb-streams.test.js @@ -1,10 +1,10 @@ -import { deepStrictEqual } from "node:assert"; +import { deepStrictEqual, rejects } from "node:assert"; import test from "node:test"; import { DynamoDBStreamsClient, GetRecordsCommand, } from "@aws-sdk/client-dynamodb-streams"; -import { +import ddbStreamsDefault, { awsDynamoDBStreamsGetRecordsStream, awsDynamoDBStreamsSetClient, } from "@datastream/aws/dynamodb-streams"; @@ -159,6 +159,38 @@ test(`${variant}: awsDynamoDBStreamsGetRecordsStream should delay polling when p deepStrictEqual(output, [{ eventID: "1" }]); }); +test(`${variant}: awsDynamoDBStreamsGetRecordsStream should abort the idle poll delay on signal`, async (_t) => { + const client = mockClient(DynamoDBStreamsClient); + awsDynamoDBStreamsSetClient(client); + + client + .on(GetRecordsCommand) + .resolves({ Records: [], NextShardIterator: "i" }); + + const controller = new AbortController(); + const options = { + ShardIterator: "iter1", + pollingActive: true, + pollingDelay: 60_000, + }; + const stream = await awsDynamoDBStreamsGetRecordsStream(options, { + signal: controller.signal, + }); + + const consuming = (async () => { + for await (const _item of stream) { + // no records ever arrive + } + })(); + + await new Promise((resolve) => setImmediate(resolve)); + controller.abort(); + + await rejects(consuming, (error) => { + return error.cause?.code === "AbortError" || /Abort/i.test(error.message); + }); +}); + // *** AbortSignal *** // test(`${variant}: awsDynamoDBStreamsGetRecordsStream should pass signal to client`, async (_t) => { const client = mockClient(DynamoDBStreamsClient); @@ -178,3 +210,152 @@ test(`${variant}: awsDynamoDBStreamsGetRecordsStream should pass signal to clien const calls = client.commandCalls(GetRecordsCommand); deepStrictEqual(calls[0].args[1]?.abortSignal, controller.signal); }); + +// *** options spread through to the command *** // +test(`${variant}: awsDynamoDBStreamsGetRecordsStream passes Limit through to GetRecords`, async (_t) => { + const client = mockClient(DynamoDBStreamsClient); + awsDynamoDBStreamsSetClient(client); + client + .on(GetRecordsCommand) + .resolvesOnce({ Records: [{ eventID: "1" }], NextShardIterator: null }); + + const stream = await awsDynamoDBStreamsGetRecordsStream({ + ShardIterator: "shard-abc", + Limit: 25, + }); + await streamToArray(stream); + + // `opts.ShardIterator` is reassigned inside the loop and captured by + // reference, so assert on `Limit` (not mutated) -- it proves the caller + // options were spread through (a `command({})` mutant would drop it). + const input = client.commandCalls(GetRecordsCommand)[0].args[0].input; + deepStrictEqual(input.Limit, 25); +}); + +// *** setClient swap *** // +test(`${variant}: awsDynamoDBStreamsSetClient routes to the new client`, async (_t) => { + const first = mockClient(DynamoDBStreamsClient); + awsDynamoDBStreamsSetClient(first); + first + .on(GetRecordsCommand) + .resolves({ Records: [], NextShardIterator: null }); + + const second = mockClient(DynamoDBStreamsClient); + second + .on(GetRecordsCommand) + .resolves({ Records: [], NextShardIterator: null }); + awsDynamoDBStreamsSetClient(second); + + const stream = await awsDynamoDBStreamsGetRecordsStream({ + ShardIterator: "i", + }); + await streamToArray(stream); + + deepStrictEqual(second.commandCalls(GetRecordsCommand).length, 1); + deepStrictEqual(first.commandCalls(GetRecordsCommand).length, 0); +}); + +// setClient must STORE the passed client; a plain stub (prototype-mock-proof) +// proves the stored reference is used. A `setClient(){}` mutant leaves the prior +// client in place. +test(`${variant}: awsDynamoDBStreamsSetClient stores the passed client reference`, async (_t) => { + let calls = 0; + const stub = { + send: async () => { + calls++; + return { Records: [{ eventID: "stub" }], NextShardIterator: null }; + }, + }; + awsDynamoDBStreamsSetClient(stub); + + const stream = await awsDynamoDBStreamsGetRecordsStream({ + ShardIterator: "iter1", + }); + const output = await streamToArray(stream); + + deepStrictEqual(output, [{ eventID: "stub" }]); + deepStrictEqual(calls, 1); +}); + +// *** idle-wait guard conjuncts *** // +test(`${variant}: awsDynamoDBStreamsGetRecordsStream does not delay when records are present`, async (t) => { + t.mock.timers.enable({ apis: ["setTimeout"] }); + const client = mockClient(DynamoDBStreamsClient); + awsDynamoDBStreamsSetClient(client); + // Records always present so the `records.length === 0` conjunct is false and + // no timer is scheduled. A `true` mutant on that conjunct would delay after + // every (non-empty) poll and the consumer would stall on the mock timer. + client.on(GetRecordsCommand).resolves({ + Records: [{ eventID: "1" }], + NextShardIterator: "iter-next", + }); + + const options = { + ShardIterator: "iter1", + pollingActive: true, + pollingDelay: 60_000, + }; + const stream = await awsDynamoDBStreamsGetRecordsStream(options); + + const output = []; + for await (const item of stream) { + output.push(item); + if (output.length >= 3) break; + } + deepStrictEqual(output.length, 3); +}); + +test(`${variant}: awsDynamoDBStreamsGetRecordsStream pollingDelay 0 schedules no timer`, async (t) => { + t.mock.timers.enable({ apis: ["setTimeout"] }); + const client = mockClient(DynamoDBStreamsClient); + awsDynamoDBStreamsSetClient(client); + // pollingActive, empty records, pollingDelay === 0: `pollingDelay > 0` is false + // so no idle wait. A `> 0` -> `true` or `>= 0` mutant would await timeout(0) + // which the un-ticked mock timer never resolves. + client + .on(GetRecordsCommand) + .resolvesOnce({ Records: [], NextShardIterator: "iter2" }) + .resolves({ Records: [{ eventID: "1" }], NextShardIterator: "iter3" }); + + const options = { + ShardIterator: "iter1", + pollingActive: true, + pollingDelay: 0, + }; + const stream = await awsDynamoDBStreamsGetRecordsStream(options); + + const output = []; + for await (const item of stream) { + output.push(item); + if (output.length >= 1) break; + } + deepStrictEqual(output, [{ eventID: "1" }]); +}); + +test(`${variant}: awsDynamoDBStreamsGetRecordsStream non-polling empty page ends without an idle wait`, async (t) => { + t.mock.timers.enable({ apis: ["setTimeout"] }); + const client = mockClient(DynamoDBStreamsClient); + awsDynamoDBStreamsSetClient(client); + // Not polling: an empty page ends the stream WITHOUT entering the idle wait. + // The `&&` -> `||` mutant makes `pollingActive || records.length === 0` true on + // the empty page, scheduling a (default 1000ms) timeout the un-ticked mock + // timer never resolves -> the stream would hang instead of completing. + client + .on(GetRecordsCommand) + .resolvesOnce({ Records: [{ eventID: "1" }], NextShardIterator: "iter2" }) + .resolves({ Records: [], NextShardIterator: "iter3" }); + + const stream = await awsDynamoDBStreamsGetRecordsStream({ + ShardIterator: "iter1", + }); + const output = await streamToArray(stream); + + deepStrictEqual(output, [{ eventID: "1" }]); +}); + +test(`${variant}: dynamodb-streams default export exposes all stream functions`, (_t) => { + deepStrictEqual(Object.keys(ddbStreamsDefault).sort(), [ + "getRecordsStream", + "setClient", + ]); +}); diff --git a/packages/aws/dynamodb.js b/packages/aws/dynamodb.js index 5459659..50cf46a 100644 --- a/packages/aws/dynamodb.js +++ b/packages/aws/dynamodb.js @@ -17,6 +17,22 @@ export const awsDynamoDBSetClient = (ddbClient, _translateConfig) => { }; awsDynamoDBSetClient(client); +// UnprocessedItems/UnprocessedKeys are throttling-driven; a near-zero early +// delay (3^0 == 1ms) just hammers the table. Apply a floor so the first retries +// give capacity time to recover, while preserving the ~59sec cap (3^10). +const DYNAMODB_BACKOFF_FLOOR_MS = 50; +const DYNAMODB_BACKOFF_CAP_MS = 3 ** 10; +// streamOptions is always supplied by the callers (getItem / batchWrite, which +// receive the stream's streamOptions defaulting to {}), so it is never nullish. +const dynamodbBackoff = (retryCount, streamOptions) => + timeout( + Math.min( + DYNAMODB_BACKOFF_CAP_MS, + Math.max(DYNAMODB_BACKOFF_FLOOR_MS, 3 ** retryCount), + ), + { signal: streamOptions.signal }, + ); + // options = {TableName, ...} export const awsDynamoDBQueryStream = async (options, streamOptions = {}) => { @@ -26,7 +42,7 @@ export const awsDynamoDBQueryStream = async (options, streamOptions = {}) => { const response = await client.send(new QueryCommand(opts), { abortSignal: streamOptions.signal, }); - for (const item of response.Items) { + for (const item of response.Items ?? []) { yield item; } opts.ExclusiveStartKey = response.LastEvaluatedKey; @@ -43,7 +59,7 @@ export const awsDynamoDBScanStream = async (options, streamOptions = {}) => { const response = await client.send(new ScanCommand(opts), { abortSignal: streamOptions.signal, }); - for (const item of response.Items) { + for (const item of response.Items ?? []) { yield item; } opts.ExclusiveStartKey = response.LastEvaluatedKey; @@ -92,11 +108,11 @@ export const awsDynamoDBGetItemStream = async (options, streamOptions = {}) => { }), { abortSignal: streamOptions.signal }, ); - for (const item of response.Responses[options.TableName]) { + for (const item of response.Responses?.[options.TableName] ?? []) { yield item; } const UnprocessedKeys = - response?.UnprocessedKeys?.[options.TableName]?.Keys ?? []; + response.UnprocessedKeys?.[options.TableName]?.Keys ?? []; if (!UnprocessedKeys.length) { break; } @@ -110,7 +126,7 @@ export const awsDynamoDBGetItemStream = async (options, streamOptions = {}) => { }); } - await timeout(3 ** retryCount, { signal: streamOptions.signal }); // 3^10 == 59sec + await dynamodbBackoff(retryCount, streamOptions); retryCount++; keys = UnprocessedKeys; } @@ -171,7 +187,8 @@ const dynamodbBatchWrite = async ( [options.TableName]: batch, }, }), - { abortSignal: streamOptions?.signal }, + // streamOptions is always supplied by put/delete (defaulting to {}). + { abortSignal: streamOptions.signal }, ); if (UnprocessedItems?.[options.TableName]?.length) { if (retryCount >= retryMaxCount) { @@ -183,7 +200,7 @@ const dynamodbBatchWrite = async ( }); } - await timeout(3 ** retryCount, { signal: streamOptions?.signal }); // 3^10 == 59sec + await dynamodbBackoff(retryCount, streamOptions); return dynamodbBatchWrite( options, UnprocessedItems[options.TableName], diff --git a/packages/aws/dynamodb.test.js b/packages/aws/dynamodb.test.js index 3ceb6af..a97d56e 100644 --- a/packages/aws/dynamodb.test.js +++ b/packages/aws/dynamodb.test.js @@ -626,6 +626,435 @@ test(`${variant}: awsDynamoDBGetItemStream should reject when Keys.length exceed ); }); +// *** empty-page / fully-throttled guards *** // +test(`${variant}: awsDynamoDBQueryStream should handle a page with no Items`, async (_t) => { + const client = mockClient(DynamoDBClient); + awsDynamoDBSetClient(client); + client + .on(QueryCommand, { TableName: "TableName" }) + .resolvesOnce({ + // filtered page: no Items but still paginating + Count: 0, + LastEvaluatedKey: { key: "a" }, + }) + .resolvesOnce({ + Items: [{ key: "b", value: 2 }], + }); + + const options = { TableName: "TableName" }; + const stream = await awsDynamoDBQueryStream(options); + const output = await streamToArray(stream); + + deepStrictEqual(output, [{ key: "b", value: 2 }]); +}); + +test(`${variant}: awsDynamoDBScanStream should handle a page with no Items`, async (_t) => { + const client = mockClient(DynamoDBClient); + awsDynamoDBSetClient(client); + client + .on(ScanCommand, { TableName: "TableName" }) + .resolvesOnce({ + Count: 0, + LastEvaluatedKey: { key: "a" }, + }) + .resolvesOnce({ + Items: [{ key: "b", value: 2 }], + }); + + const options = { TableName: "TableName" }; + const stream = await awsDynamoDBScanStream(options); + const output = await streamToArray(stream); + + deepStrictEqual(output, [{ key: "b", value: 2 }]); +}); + +test(`${variant}: awsDynamoDBGetItemStream should handle fully-throttled batch (empty Responses)`, async (_t) => { + const client = mockClient(DynamoDBClient); + awsDynamoDBSetClient(client); + client + .on(BatchGetItemCommand, { + RequestItems: { TableName: { Keys: [{ key: "a" }] } }, + }) + .resolvesOnce({ + // entire batch throttled: Responses has no entry for the table + Responses: {}, + UnprocessedKeys: { TableName: { Keys: [{ key: "a" }] } }, + }) + .resolvesOnce({ + Responses: { TableName: [{ key: "a", value: 1 }] }, + UnprocessedKeys: {}, + }); + + const options = { TableName: "TableName", Keys: [{ key: "a" }] }; + const stream = await awsDynamoDBGetItemStream(options); + const output = await streamToArray(stream); + + deepStrictEqual(output, [{ key: "a", value: 1 }]); +}); + +// *** backoff is abortable: aborting during the backoff wait rejects *** // +test(`${variant}: awsDynamoDBGetItemStream aborts during retry backoff`, async (_t) => { + const client = mockClient(DynamoDBClient); + awsDynamoDBSetClient(client); + // Always throttled so the stream enters the (real-timer) backoff wait. + client.on(BatchGetItemCommand).resolves({ + Responses: {}, + UnprocessedKeys: { TableName: { Keys: [{ key: "a" }] } }, + }); + + const controller = new AbortController(); + const options = { TableName: "TableName", Keys: [{ key: "a" }] }; + const stream = await awsDynamoDBGetItemStream(options, { + signal: controller.signal, + }); + + const consuming = streamToArray(stream); + // Let the first throttled batch settle and enter the backoff timer, then + // abort. The backoff timeout was given `{ signal }`, so it must reject + // promptly. A `{}` mutant (dropping the signal) would let the backoff run to + // completion and keep retrying, so this would hang instead of rejecting. + await new Promise((resolve) => setImmediate(resolve)); + controller.abort(); + + await rejects(consuming, (error) => { + return error.cause?.code === "AbortError" || /Abort/i.test(error.message); + }); +}); + +// *** backoff floor: the first retry waits at least 50ms (not 3^0 == 1ms) *** // +test(`${variant}: awsDynamoDBGetItemStream first retry backoff is floored at 50ms`, async (t) => { + t.mock.timers.enable({ apis: ["setTimeout"] }); + + const client = mockClient(DynamoDBClient); + awsDynamoDBSetClient(client); + client + .on(BatchGetItemCommand) + .resolvesOnce({ + Responses: {}, + UnprocessedKeys: { TableName: { Keys: [{ key: "a" }] } }, + }) + .resolves({ + Responses: { TableName: [{ key: "a", value: 1 }] }, + UnprocessedKeys: {}, + }); + + const options = { TableName: "TableName", Keys: [{ key: "a" }] }; + const stream = await awsDynamoDBGetItemStream(options); + const consuming = streamToArray(stream); + + // Let the first (throttled) batch settle and enter the backoff timer. + await new Promise((resolve) => setImmediate(resolve)); + // 3^0 == 1ms would already fire; the 50ms floor means the retry must still be + // pending at 1ms (kills the Math.max -> Math.min floor mutant and the + // arrow-body removal). + t.mock.timers.tick(1); + await new Promise((resolve) => setImmediate(resolve)); + deepStrictEqual(client.commandCalls(BatchGetItemCommand).length, 1); + + t.mock.timers.tick(49); + const output = await consuming; + deepStrictEqual(output, [{ key: "a", value: 1 }]); + deepStrictEqual(client.commandCalls(BatchGetItemCommand).length, 2); +}); + +// *** setClient swap *** // +test(`${variant}: awsDynamoDBSetClient routes subsequent sends to the new client`, async (_t) => { + const first = mockClient(DynamoDBClient); + awsDynamoDBSetClient(first); + first.on(QueryCommand).resolves({ Items: [{ key: "stale" }] }); + + const second = mockClient(DynamoDBClient); + second.on(QueryCommand).resolves({ Items: [{ key: "fresh" }] }); + awsDynamoDBSetClient(second); + + const stream = await awsDynamoDBQueryStream({ TableName: "T" }); + const output = await streamToArray(stream); + + deepStrictEqual(output, [{ key: "fresh" }]); + deepStrictEqual(second.commandCalls(QueryCommand).length, 1); + deepStrictEqual(first.commandCalls(QueryCommand).length, 0); +}); + +// setClient must STORE the passed client; a plain stub (prototype-mock-proof) +// proves the stored reference is used. A `setClient(){}` mutant leaves the prior +// client in place. +test(`${variant}: awsDynamoDBSetClient stores the passed client reference`, async (_t) => { + let calls = 0; + const stub = { + send: async () => { + calls++; + return { Items: [{ key: "stub" }] }; + }, + }; + awsDynamoDBSetClient(stub); + + const stream = await awsDynamoDBQueryStream({ TableName: "T" }); + const output = await streamToArray(stream); + + deepStrictEqual(output, [{ key: "stub" }]); + deepStrictEqual(calls, 1); +}); + +// *** abortSignal forwarding on each read command (kills the `{}` options mutant) *** // +test(`${variant}: awsDynamoDBQueryStream forwards abortSignal to client.send`, async (_t) => { + const client = mockClient(DynamoDBClient); + awsDynamoDBSetClient(client); + client.on(QueryCommand).resolves({ Items: [{ key: "a" }] }); + + const controller = new AbortController(); + const stream = await awsDynamoDBQueryStream( + { TableName: "T" }, + { signal: controller.signal }, + ); + await streamToArray(stream); + + const calls = client.commandCalls(QueryCommand); + deepStrictEqual(calls[0].args[1]?.abortSignal, controller.signal); +}); + +test(`${variant}: awsDynamoDBScanStream forwards abortSignal to client.send`, async (_t) => { + const client = mockClient(DynamoDBClient); + awsDynamoDBSetClient(client); + client.on(ScanCommand).resolves({ Items: [{ key: "a" }] }); + + const controller = new AbortController(); + const stream = await awsDynamoDBScanStream( + { TableName: "T" }, + { signal: controller.signal }, + ); + await streamToArray(stream); + + const calls = client.commandCalls(ScanCommand); + deepStrictEqual(calls[0].args[1]?.abortSignal, controller.signal); +}); + +test(`${variant}: awsDynamoDBExecuteStatementStream forwards abortSignal to client.send`, async (_t) => { + const client = mockClient(DynamoDBClient); + awsDynamoDBSetClient(client); + client.on(ExecuteStatementCommand).resolves({ Items: [{ key: "a" }] }); + + const controller = new AbortController(); + const stream = await awsDynamoDBExecuteStatementStream( + { Statement: "SELECT" }, + { signal: controller.signal }, + ); + await streamToArray(stream); + + const calls = client.commandCalls(ExecuteStatementCommand); + deepStrictEqual(calls[0].args[1]?.abortSignal, controller.signal); +}); + +test(`${variant}: awsDynamoDBGetItemStream forwards abortSignal to client.send`, async (_t) => { + const client = mockClient(DynamoDBClient); + awsDynamoDBSetClient(client); + client + .on(BatchGetItemCommand) + .resolves({ Responses: { T: [{ key: "a" }] }, UnprocessedKeys: {} }); + + const controller = new AbortController(); + const stream = await awsDynamoDBGetItemStream( + { TableName: "T", Keys: [{ key: "a" }] }, + { signal: controller.signal }, + ); + await streamToArray(stream); + + const calls = client.commandCalls(BatchGetItemCommand); + deepStrictEqual(calls[0].args[1]?.abortSignal, controller.signal); +}); + +// *** executeStatement yields nothing when the response has no Items field *** // +test(`${variant}: awsDynamoDBExecuteStatementStream yields nothing for a response without Items`, async (_t) => { + const client = mockClient(DynamoDBClient); + awsDynamoDBSetClient(client); + // No Items field at all: the `response.Items ?? []` default must be an EMPTY + // array. A `["Stryker was here"]` mutant would yield that sentinel. + client.on(ExecuteStatementCommand).resolves({}); + + const stream = await awsDynamoDBExecuteStatementStream({ + Statement: "SELECT", + }); + const output = await streamToArray(stream); + + deepStrictEqual(output, []); +}); + +// *** Keys boundary: exactly 100 is allowed (strict `>`) *** // +test(`${variant}: awsDynamoDBGetItemStream allows exactly 100 Keys`, async (_t) => { + const client = mockClient(DynamoDBClient); + awsDynamoDBSetClient(client); + client + .on(BatchGetItemCommand) + .resolves({ Responses: { T: [] }, UnprocessedKeys: {} }); + + // Exactly 100 must NOT throw (strict `>`); a `>=` mutant would reject it. + const options = { TableName: "T", Keys: new Array(100).fill({ key: "x" }) }; + const stream = await awsDynamoDBGetItemStream(options); + const output = await streamToArray(stream); + deepStrictEqual(output, []); +}); + +// *** getItem with no Keys (optional chaining on options.Keys) *** // +test(`${variant}: awsDynamoDBGetItemStream tolerates options without Keys`, async (_t) => { + const client = mockClient(DynamoDBClient); + awsDynamoDBSetClient(client); + client + .on(BatchGetItemCommand) + .resolves({ Responses: { T: [{ key: "a" }] }, UnprocessedKeys: {} }); + + // No Keys property: the `options.Keys?.length > 100` guard must short-circuit + // via the optional chain. A non-optional `options.Keys.length` mutant throws. + const stream = await awsDynamoDBGetItemStream({ TableName: "T" }); + const output = await streamToArray(stream); + deepStrictEqual(output, [{ key: "a" }]); +}); + +// *** getItem tolerates a response missing Responses / UnprocessedKeys *** // +test(`${variant}: awsDynamoDBGetItemStream tolerates a response with neither Responses nor UnprocessedKeys`, async (_t) => { + const client = mockClient(DynamoDBClient); + awsDynamoDBSetClient(client); + // Bare response: `response.Responses?.[T]` and `response?.UnprocessedKeys?.[T]?.Keys` + // optional chains must yield [] (no items, no retry). Non-optional mutants + // (`response.Responses[T]`, `response.UnprocessedKeys`, `response?.UnprocessedKeys[T]`) + // would throw a TypeError reading a property of undefined. + client.on(BatchGetItemCommand).resolves({}); + + const stream = await awsDynamoDBGetItemStream({ + TableName: "T", + Keys: [{ key: "a" }], + }); + const output = await streamToArray(stream); + deepStrictEqual(output, []); +}); + +// *** getItem retry accounting: retryMaxCount honoured, error cause populated *** // +test(`${variant}: awsDynamoDBGetItemStream throws after exactly retryMaxCount retries with cause`, async (_t) => { + const client = mockClient(DynamoDBClient); + awsDynamoDBSetClient(client); + // Always throttled. retryMaxCount 1: attempt #1 (retryCount 0, 0 >= 1 false -> + // backoff, retryCount -> 1), attempt #2 (1 >= 1 true -> throw). Exactly 2 calls. + // A `>` mutant would need retryCount > 1 (3 calls); a `--` mutant on the + // counter would never reach the cap (retry forever -> timeout). + client.on(BatchGetItemCommand).resolves({ + Responses: {}, + UnprocessedKeys: { T: { Keys: [{ key: "a" }] } }, + }); + + await rejects( + async () => + streamToArray( + await awsDynamoDBGetItemStream({ + TableName: "T", + Keys: [{ key: "a" }], + retryMaxCount: 1, + }), + ), + (error) => { + deepStrictEqual( + error.message, + "awsDynamoDBBatchGetItem has UnprocessedKeys", + ); + // `{}` mutants on the error options / cause would drop these fields. + deepStrictEqual(error.cause.UnprocessedKeysCount, 1); + deepStrictEqual(error.cause.TableName, "T"); + return true; + }, + ); + deepStrictEqual(client.commandCalls(BatchGetItemCommand).length, 2); +}); + +// *** getItem: retryMaxCount ?? 10 must use nullish coalescing (not &&) *** // +test(`${variant}: awsDynamoDBGetItemStream honours an explicit retryMaxCount of 2`, async (_t) => { + const client = mockClient(DynamoDBClient); + awsDynamoDBSetClient(client); + // retryMaxCount 2: `2 ?? 10` === 2 (throw after 3 calls). A `2 && 10` mutant + // yields 10 -> 11 calls (and a huge cumulative backoff -> timeout). Assert the + // exact call count pins the coalescing operator. + client.on(BatchGetItemCommand).resolves({ + Responses: {}, + UnprocessedKeys: { T: { Keys: [{ key: "a" }] } }, + }); + + await rejects( + async () => + streamToArray( + await awsDynamoDBGetItemStream({ + TableName: "T", + Keys: [{ key: "a" }], + retryMaxCount: 2, + }), + ), + { message: "awsDynamoDBBatchGetItem has UnprocessedKeys" }, + ); + deepStrictEqual(client.commandCalls(BatchGetItemCommand).length, 3); +}); + +// *** batchWrite: response with no UnprocessedItems is a success *** // +test(`${variant}: awsDynamoDBPutItemStream treats a response without UnprocessedItems as success`, async (_t) => { + const client = mockClient(DynamoDBClient); + awsDynamoDBSetClient(client); + // Bare response (no UnprocessedItems): the `UnprocessedItems?.[T]?.length` + // optional chain must be falsy (no retry). A non-optional mutant throws. + client.on(BatchWriteItemCommand).resolves({}); + + const output = await pipeline([ + createReadableStream([{ key: "a", value: 1 }]), + awsDynamoDBPutItemStream({ TableName: "T" }), + ]); + deepStrictEqual(output, {}); + deepStrictEqual(client.commandCalls(BatchWriteItemCommand).length, 1); +}); + +// *** batchWrite retry accounting: retryMaxCount honoured, counter increments, +// error cause populated, recursion uses retryCount + 1 *** // +test(`${variant}: awsDynamoDBPutItemStream throws after exactly retryMaxCount retries with cause`, async (_t) => { + const client = mockClient(DynamoDBClient); + awsDynamoDBSetClient(client); + // Always returns UnprocessedItems. retryMaxCount 1 -> throw after 2 calls. + // `>` mutant -> 3 calls; `retryCount + 1` -> `- 1` mutant never reaches the cap + // (recurses forever -> timeout). + client.on(BatchWriteItemCommand).resolves({ + UnprocessedItems: { T: [{ PutRequest: { Item: { key: "a" } } }] }, + }); + + await rejects( + () => + pipeline([ + createReadableStream([{ key: "a" }]), + awsDynamoDBPutItemStream({ TableName: "T", retryMaxCount: 1 }), + ]), + (error) => { + deepStrictEqual( + error.message, + "awsDynamoDBBatchWriteItem has UnprocessedItems", + ); + deepStrictEqual(error.cause.UnprocessedItemsCount, 1); + deepStrictEqual(error.cause.TableName, "T"); + return true; + }, + ); + deepStrictEqual(client.commandCalls(BatchWriteItemCommand).length, 2); +}); + +test(`${variant}: awsDynamoDBPutItemStream honours an explicit retryMaxCount of 2`, async (_t) => { + const client = mockClient(DynamoDBClient); + awsDynamoDBSetClient(client); + // retryMaxCount 2: `2 ?? 10` === 2 -> throw after 3 calls. A `2 && 10` mutant + // yields 10 -> many more calls (huge backoff -> timeout). + client.on(BatchWriteItemCommand).resolves({ + UnprocessedItems: { T: [{ PutRequest: { Item: { key: "a" } } }] }, + }); + + await rejects( + () => + pipeline([ + createReadableStream([{ key: "a" }]), + awsDynamoDBPutItemStream({ TableName: "T", retryMaxCount: 2 }), + ]), + { message: "awsDynamoDBBatchWriteItem has UnprocessedItems" }, + ); + deepStrictEqual(client.commandCalls(BatchWriteItemCommand).length, 3); +}); + test(`${variant}: default export should include all stream functions`, (_t) => { deepStrictEqual(Object.keys(dynamodbDefault).sort(), [ "deleteItemStream", diff --git a/packages/aws/kinesis.js b/packages/aws/kinesis.js index aa82d64..a057ab2 100644 --- a/packages/aws/kinesis.js +++ b/packages/aws/kinesis.js @@ -5,9 +5,51 @@ import { KinesisClient, PutRecordsCommand, } from "@aws-sdk/client-kinesis"; -import { createWritableStream } from "@datastream/core"; +import { createWritableStream, timeout } from "@datastream/core"; import { awsClientDefaults } from "./client.js"; +// PutRecords limits: <=500 records, <=5 MiB aggregate, <=1 MiB per record. +const KINESIS_MAX_RECORDS = 500; +const KINESIS_MAX_RECORD_BYTES = 1024 * 1024; // 1 MiB +// 5 MiB aggregate with headroom for request framing. +const KINESIS_MAX_BATCH_BYTES = 5 * 1024 * 1024 - 64 * 1024; + +// Partial failures are overwhelmingly throttling-driven +// (ProvisionedThroughputExceeded); a near-zero early delay (3^0 == 1ms) just +// hammers the throttled stream. Apply a floor so the first retries give +// capacity time to recover, while preserving the ~59sec cap (3^10). +const BACKOFF_FLOOR_MS = 50; +const BACKOFF_CAP_MS = 3 ** 10; +// streamOptions is always supplied by the exported stream function (defaulting +// to {}), so it is never nullish here. +const backoff = (retryCount, streamOptions) => + timeout( + Math.min(BACKOFF_CAP_MS, Math.max(BACKOFF_FLOOR_MS, 3 ** retryCount)), + { + signal: streamOptions.signal, + }, + ); + +const _textEncoder = new TextEncoder(); +const _byteLength = (value) => + typeof value === "string" + ? _textEncoder.encode(value).byteLength + : value.byteLength; + +const recordByteLength = (record) => { + let bytes = 0; + if (record.Data != null) { + bytes += _byteLength(record.Data); + } + if (record.PartitionKey != null) { + bytes += _byteLength(record.PartitionKey); + } + if (record.ExplicitHashKey != null) { + bytes += _byteLength(record.ExplicitHashKey); + } + return bytes; +}; + let client = new KinesisClient(awsClientDefaults); export const awsKinesisSetClient = (kinesisClient) => { client = kinesisClient; @@ -32,7 +74,9 @@ export const awsKinesisGetRecordsStream = async ( expectMore = opts.ShardIterator !== null && (pollingActive || records.length > 0); if (pollingActive && records.length === 0 && pollingDelay > 0) { - await new Promise((resolve) => setTimeout(resolve, pollingDelay)); + // Abortable idle wait: rejects immediately and clears the timer + // when streamOptions.signal aborts mid-delay. + await timeout(pollingDelay, { signal: streamOptions.signal }); } } } @@ -40,19 +84,60 @@ export const awsKinesisGetRecordsStream = async ( }; export const awsKinesisPutRecordsStream = (options, streamOptions = {}) => { + const { retryMaxCount = 10, ...putOptions } = options; let batch = []; - const send = () => { - options.Records = batch; + let batchBytes = 0; + const send = async () => { + if (!batch.length) { + return; + } + let records = batch; batch = []; - return client.send(new PutRecordsCommand(options)); + batchBytes = 0; + let retryCount = 0; + while (true) { + const response = await client.send( + new PutRecordsCommand({ ...putOptions, Records: records }), + { abortSignal: streamOptions.signal }, + ); + if (!response.FailedRecordCount) { + return; + } + // Retry only the records whose result entry carries an ErrorCode. + const results = response.Records ?? []; + const failed = records.filter( + (_record, index) => results[index]?.ErrorCode, + ); + if (!failed.length) { + return; + } + if (retryCount >= retryMaxCount) { + throw new Error("awsKinesisPutRecords has failed records", { + cause: results.filter((result) => result.ErrorCode), + }); + } + await backoff(retryCount, streamOptions); + retryCount++; + records = failed; + } }; const write = async (chunk) => { - if (batch.length === 500) { + const chunkBytes = recordByteLength(chunk); + if (chunkBytes > KINESIS_MAX_RECORD_BYTES) { + throw new Error("awsKinesisPutRecords record exceeds 1MiB limit", { + cause: { bytes: chunkBytes, limit: KINESIS_MAX_RECORD_BYTES }, + }); + } + if ( + batch.length === KINESIS_MAX_RECORDS || + (batch.length && batchBytes + chunkBytes > KINESIS_MAX_BATCH_BYTES) + ) { await send(); } batch.push(chunk); + batchBytes += chunkBytes; }; - const final = () => (batch.length ? send() : undefined); + const final = () => send(); return createWritableStream(write, final, streamOptions); }; diff --git a/packages/aws/kinesis.test.js b/packages/aws/kinesis.test.js index 1ee45a5..22b3b88 100644 --- a/packages/aws/kinesis.test.js +++ b/packages/aws/kinesis.test.js @@ -1,4 +1,4 @@ -import { deepStrictEqual } from "node:assert"; +import { deepStrictEqual, rejects } from "node:assert"; import test from "node:test"; import { GetRecordsCommand, @@ -189,6 +189,229 @@ test(`${variant}: awsKinesisPutRecordsStream should handle empty input`, async ( deepStrictEqual(result, {}); }); +// *** PutRecords partial failure (data loss) *** // +test(`${variant}: awsKinesisPutRecordsStream should retry failed records on partial failure`, async (_t) => { + const client = mockClient(KinesisClient); + awsKinesisSetClient(client); + + const input = [ + { Data: "a", PartitionKey: "a" }, + { Data: "b", PartitionKey: "b" }, + ]; + const options = { StreamName: "test-stream" }; + + client + .on(PutRecordsCommand) + .resolvesOnce({ + FailedRecordCount: 1, + Records: [ + { SequenceNumber: "1" }, + { ErrorCode: "ProvisionedThroughputExceededException" }, + ], + }) + .resolvesOnce({ + FailedRecordCount: 0, + Records: [{ SequenceNumber: "2" }], + }); + + const stream = [ + createReadableStream(input), + awsKinesisPutRecordsStream(options), + ]; + await pipeline(stream); + + const calls = client.commandCalls(PutRecordsCommand); + deepStrictEqual(calls.length, 2); + // The retry must resubmit only the failed record (b) + deepStrictEqual(calls[1].args[0].input.Records, [ + { Data: "b", PartitionKey: "b" }, + ]); +}); + +test(`${variant}: awsKinesisPutRecordsStream should throw when records keep failing`, async (_t) => { + const client = mockClient(KinesisClient); + awsKinesisSetClient(client); + + const input = [{ Data: "a", PartitionKey: "a" }]; + const options = { StreamName: "test-stream", retryMaxCount: 0 }; + + client.on(PutRecordsCommand).resolves({ + FailedRecordCount: 1, + Records: [{ ErrorCode: "InternalFailure", ErrorMessage: "boom" }], + }); + + const stream = [ + createReadableStream(input), + awsKinesisPutRecordsStream(options), + ]; + await rejects(() => pipeline(stream), { + message: "awsKinesisPutRecords has failed records", + }); +}); + +test(`${variant}: awsKinesisPutRecordsStream should flush when aggregate bytes exceed 5MiB`, async (_t) => { + const client = mockClient(KinesisClient); + awsKinesisSetClient(client); + + client.on(PutRecordsCommand).resolves({ FailedRecordCount: 0 }); + + // 8 records just under 1 MiB each => ~8 MiB total, well below 500 count + // but over the 5 MiB aggregate limit, forcing multiple flushes. + const big = "x".repeat(1024 * 1024 - 1024); + const input = Array.from({ length: 8 }, (_v, i) => ({ + Data: big, + PartitionKey: `${i}`, + })); + const options = { StreamName: "test-stream" }; + + const stream = [ + createReadableStream(input), + awsKinesisPutRecordsStream(options), + ]; + await pipeline(stream); + + const calls = client.commandCalls(PutRecordsCommand); + // ~8 MiB cannot fit in a single 5 MiB request -> multiple flushes + deepStrictEqual(calls.length > 1, true); + // And no single flush may carry more than the 5 MiB aggregate + for (const call of calls) { + deepStrictEqual(call.args[0].input.Records.length <= 5, true); + } +}); + +test(`${variant}: awsKinesisPutRecordsStream should count ExplicitHashKey toward record size`, async (_t) => { + const client = mockClient(KinesisClient); + awsKinesisSetClient(client); + client.on(PutRecordsCommand).resolves({ FailedRecordCount: 0 }); + + const input = [ + { Data: "a", PartitionKey: "p", ExplicitHashKey: "123456789" }, + ]; + const options = { StreamName: "test-stream" }; + const stream = [ + createReadableStream(input), + awsKinesisPutRecordsStream(options), + ]; + await pipeline(stream); + + deepStrictEqual(client.commandCalls(PutRecordsCommand).length, 1); +}); + +test(`${variant}: awsKinesisPutRecordsStream should not retry when FailedRecordCount has no ErrorCode entries`, async (_t) => { + const client = mockClient(KinesisClient); + awsKinesisSetClient(client); + // Defensive: count says failures but no entry carries an ErrorCode. + client.on(PutRecordsCommand).resolves({ + FailedRecordCount: 1, + Records: [{ SequenceNumber: "1" }], + }); + + const input = [{ Data: "a", PartitionKey: "a" }]; + const options = { StreamName: "test-stream" }; + const stream = [ + createReadableStream(input), + awsKinesisPutRecordsStream(options), + ]; + await pipeline(stream); + + // No ErrorCode => no retry + deepStrictEqual(client.commandCalls(PutRecordsCommand).length, 1); +}); + +test(`${variant}: awsKinesisPutRecordsStream should reject a single record over 1MiB`, async (_t) => { + const client = mockClient(KinesisClient); + awsKinesisSetClient(client); + + client.on(PutRecordsCommand).resolves({ FailedRecordCount: 0 }); + + const tooBig = "x".repeat(1024 * 1024 + 1); + const input = [{ Data: tooBig, PartitionKey: "k" }]; + const options = { StreamName: "test-stream" }; + + const stream = [ + createReadableStream(input), + awsKinesisPutRecordsStream(options), + ]; + await rejects(() => pipeline(stream), { + message: "awsKinesisPutRecords record exceeds 1MiB limit", + }); +}); + +test(`${variant}: awsKinesisPutRecordsStream should not mutate caller options`, async (_t) => { + const client = mockClient(KinesisClient); + awsKinesisSetClient(client); + client.on(PutRecordsCommand).resolves({ FailedRecordCount: 0 }); + + const options = { StreamName: "test-stream" }; + const optionsCopy = { ...options }; + const input = [{ Data: "a", PartitionKey: "a" }]; + + const stream = [ + createReadableStream(input), + awsKinesisPutRecordsStream(options), + ]; + await pipeline(stream); + + deepStrictEqual(options, optionsCopy); +}); + +test(`${variant}: awsKinesisPutRecordsStream should forward abort signal to client.send`, async (_t) => { + const client = mockClient(KinesisClient); + awsKinesisSetClient(client); + client.on(PutRecordsCommand).resolves({ FailedRecordCount: 0 }); + + const controller = new AbortController(); + const input = [{ Data: "a", PartitionKey: "a" }]; + const stream = [ + createReadableStream(input), + awsKinesisPutRecordsStream( + { StreamName: "test-stream" }, + { signal: controller.signal }, + ), + ]; + await pipeline(stream); + + const calls = client.commandCalls(PutRecordsCommand); + deepStrictEqual(calls[0].args[1]?.abortSignal, controller.signal); +}); + +test(`${variant}: awsKinesisGetRecordsStream should abort the idle poll delay on signal`, async (_t) => { + const client = mockClient(KinesisClient); + awsKinesisSetClient(client); + + // Always empty so the poller enters the idle pollingDelay wait. + client + .on(GetRecordsCommand) + .resolves({ Records: [], NextShardIterator: "i" }); + + const controller = new AbortController(); + const options = { + ShardIterator: "iter1", + pollingActive: true, + // Large delay: if the timer is not abort-aware the consumer would hang + // far longer than this test's window. + pollingDelay: 60_000, + }; + const stream = await awsKinesisGetRecordsStream(options, { + signal: controller.signal, + }); + + const consuming = (async () => { + for await (const _item of stream) { + // no records ever arrive + } + })(); + + // Let the generator reach the idle delay, then abort. The abortable timeout + // must reject promptly instead of waiting out the 60s delay. + await new Promise((resolve) => setImmediate(resolve)); + controller.abort(); + + await rejects(consuming, (error) => { + return error.cause?.code === "AbortError" || /Abort/i.test(error.message); + }); +}); + // *** AbortSignal *** // test(`${variant}: awsKinesisGetRecordsStream should pass signal to client`, async (_t) => { const client = mockClient(KinesisClient); @@ -208,3 +431,666 @@ test(`${variant}: awsKinesisGetRecordsStream should pass signal to client`, asyn const calls = client.commandCalls(GetRecordsCommand); deepStrictEqual(calls[0].args[1]?.abortSignal, controller.signal); }); + +// *** Batch byte-cap boundary (KINESIS_MAX_BATCH_BYTES = 5MiB - 64KiB) *** // +test(`${variant}: awsKinesisPutRecordsStream splits at the 5MiB-64KiB aggregate cap, not 5MiB`, async (_t) => { + const client = mockClient(KinesisClient); + awsKinesisSetClient(client); + client.on(PutRecordsCommand).resolves({ FailedRecordCount: 0 }); + + // Each record is 128KiB Data + 1-byte PartitionKey = 131,073 bytes, chosen so + // the real cap (5MiB - 64KiB = 5,177,344) and a mutated `+64KiB` cap + // (5,308,416) disagree on where to split: + // real cap: 39 records = 5,111,847 (fits); 40th = 5,242,920 (> cap) + // -> flush after 39 + // +64KiB: 40 records = 5,242,920 (fits); 41st = 5,373,993 (> cap) + // -> flush after 40 + // Multiplicative mutants (`*1024/1024`, `5/1024*1024`) drive the cap negative + // so every record after the first flushes -> a completely different shape. + const each = 128 * 1024; // 131,072 bytes of Data + const data = "x".repeat(each); + const input = Array.from({ length: 41 }, (_v, i) => ({ + Data: data, + PartitionKey: `${i % 10}`, // single-char key => 1 byte + })); + const options = { StreamName: "test-stream" }; + await pipeline([ + createReadableStream(input), + awsKinesisPutRecordsStream(options), + ]); + + const calls = client.commandCalls(PutRecordsCommand); + deepStrictEqual(calls.length, 2); + // The true cap splits after exactly 39 records. + deepStrictEqual(calls[0].args[0].input.Records.length, 39); + deepStrictEqual(calls[1].args[0].input.Records.length, 2); +}); + +test(`${variant}: awsKinesisPutRecordsStream keeps two small records under the cap in one batch`, async (_t) => { + const client = mockClient(KinesisClient); + awsKinesisSetClient(client); + client.on(PutRecordsCommand).resolves({ FailedRecordCount: 0 }); + + // Two tiny records: well under both the count and byte caps -> single flush. + const input = [ + { Data: "a", PartitionKey: "1" }, + { Data: "b", PartitionKey: "2" }, + ]; + await pipeline([ + createReadableStream(input), + awsKinesisPutRecordsStream({ StreamName: "test-stream" }), + ]); + + const calls = client.commandCalls(PutRecordsCommand); + deepStrictEqual(calls.length, 1); + deepStrictEqual(calls[0].args[0].input.Records.length, 2); +}); + +// *** Per-record 1MiB boundary (strict `>` not `>=`) *** // +test(`${variant}: awsKinesisPutRecordsStream accepts a record exactly at the 1MiB limit`, async (_t) => { + const client = mockClient(KinesisClient); + awsKinesisSetClient(client); + client.on(PutRecordsCommand).resolves({ FailedRecordCount: 0 }); + + // Exactly 1 MiB of single-byte chars (1 byte each in UTF-8), no PartitionKey, + // so byteLength === KINESIS_MAX_RECORD_BYTES. With strict `>` this is allowed; + // a `>=` mutant would wrongly reject it. + const exact = "x".repeat(1024 * 1024); + const input = [{ Data: exact }]; + await pipeline([ + createReadableStream(input), + awsKinesisPutRecordsStream({ StreamName: "test-stream" }), + ]); + + deepStrictEqual(client.commandCalls(PutRecordsCommand).length, 1); +}); + +// *** recordByteLength counts PartitionKey & ExplicitHashKey *** // +test(`${variant}: awsKinesisPutRecordsStream counts PartitionKey bytes toward the 1MiB limit`, async (_t) => { + const client = mockClient(KinesisClient); + awsKinesisSetClient(client); + client.on(PutRecordsCommand).resolves({ FailedRecordCount: 0 }); + + // Data alone is exactly 1MiB (allowed), but adding a non-empty PartitionKey + // pushes the record over 1MiB -> must reject. This proves PartitionKey is + // summed in (the `if (record.PartitionKey != null)` block and `+=`). + const data = "x".repeat(1024 * 1024); + const input = [{ Data: data, PartitionKey: "pk" }]; + await rejects( + () => + pipeline([ + createReadableStream(input), + awsKinesisPutRecordsStream({ StreamName: "test-stream" }), + ]), + { message: "awsKinesisPutRecords record exceeds 1MiB limit" }, + ); +}); + +test(`${variant}: awsKinesisPutRecordsStream counts ExplicitHashKey bytes toward the 1MiB limit`, async (_t) => { + const client = mockClient(KinesisClient); + awsKinesisSetClient(client); + client.on(PutRecordsCommand).resolves({ FailedRecordCount: 0 }); + + // Data exactly 1MiB; a non-empty ExplicitHashKey tips it over -> reject. + // Proves the ExplicitHashKey branch and its `+=` (a `-=` mutant would keep + // it under the limit and the record would be accepted). + const data = "x".repeat(1024 * 1024); + const input = [{ Data: data, PartitionKey: "p", ExplicitHashKey: "h" }]; + await rejects( + () => + pipeline([ + createReadableStream(input), + awsKinesisPutRecordsStream({ StreamName: "test-stream" }), + ]), + { message: "awsKinesisPutRecords record exceeds 1MiB limit" }, + ); +}); + +// *** Failure cause only carries ErrorCode entries *** // +test(`${variant}: awsKinesisPutRecordsStream error cause lists only failed (ErrorCode) records`, async (_t) => { + const client = mockClient(KinesisClient); + awsKinesisSetClient(client); + + client.on(PutRecordsCommand).resolves({ + FailedRecordCount: 1, + Records: [ + { SequenceNumber: "ok-1" }, + { ErrorCode: "InternalFailure", ErrorMessage: "boom" }, + ], + }); + + const input = [ + { Data: "a", PartitionKey: "a" }, + { Data: "b", PartitionKey: "b" }, + ]; + const options = { StreamName: "test-stream", retryMaxCount: 0 }; + await rejects( + () => + pipeline([ + createReadableStream(input), + awsKinesisPutRecordsStream(options), + ]), + (error) => { + deepStrictEqual(error.message, "awsKinesisPutRecords has failed records"); + // cause must be filtered to only the ErrorCode-bearing entry. + deepStrictEqual(error.cause, [ + { ErrorCode: "InternalFailure", ErrorMessage: "boom" }, + ]); + return true; + }, + ); +}); + +// *** Count cap split at exactly 500 records *** // +test(`${variant}: awsKinesisPutRecordsStream flushes at exactly 500 records`, async (_t) => { + const client = mockClient(KinesisClient); + awsKinesisSetClient(client); + client.on(PutRecordsCommand).resolves({ FailedRecordCount: 0 }); + + // 501 tiny records: count cap (500) forces exactly one mid-stream flush of + // 500, then a final flush of 1. Proves `=== 500` (not 499/501) and that the + // count check, not bytes, triggers here. + const input = Array.from({ length: 501 }, (_v, i) => ({ + Data: "x", + PartitionKey: `${i}`, + })); + await pipeline([ + createReadableStream(input), + awsKinesisPutRecordsStream({ StreamName: "test-stream" }), + ]); + + const calls = client.commandCalls(PutRecordsCommand); + deepStrictEqual(calls.length, 2); + deepStrictEqual(calls[0].args[0].input.Records.length, 500); + deepStrictEqual(calls[1].args[0].input.Records.length, 1); +}); + +// *** Backoff floor: first retry waits >= 50ms, not 3^0 == 1ms *** // +test(`${variant}: awsKinesisPutRecordsStream first retry backoff is floored at 50ms`, async (t) => { + t.mock.timers.enable({ apis: ["setTimeout"] }); + + const client = mockClient(KinesisClient); + awsKinesisSetClient(client); + client + .on(PutRecordsCommand) + .resolvesOnce({ + FailedRecordCount: 1, + Records: [{ ErrorCode: "ProvisionedThroughputExceededException" }], + }) + .resolves({ FailedRecordCount: 0 }); + + const input = [{ Data: "a", PartitionKey: "a" }]; + const consuming = pipeline([ + createReadableStream(input), + awsKinesisPutRecordsStream({ StreamName: "test-stream" }), + ]); + + // Let the first send + failure happen, entering the backoff timer. + await new Promise((resolve) => setImmediate(resolve)); + // 3^0 == 1ms would already have elapsed; the floor means the retry must + // still be pending after 1ms but fire by 50ms. + t.mock.timers.tick(1); + await new Promise((resolve) => setImmediate(resolve)); + deepStrictEqual(client.commandCalls(PutRecordsCommand).length, 1); + t.mock.timers.tick(49); + await consuming; + deepStrictEqual(client.commandCalls(PutRecordsCommand).length, 2); +}); + +// *** setClient swaps the active client *** // +test(`${variant}: awsKinesisSetClient routes subsequent sends to the new client`, async (_t) => { + const first = mockClient(KinesisClient); + awsKinesisSetClient(first); + first.on(PutRecordsCommand).resolves({ FailedRecordCount: 0 }); + + const second = mockClient(KinesisClient); + second.on(PutRecordsCommand).resolves({ FailedRecordCount: 0 }); + // Swap before any send: only `second` should receive the command. If + // setClient's body were removed, the stale `first` would be used. + awsKinesisSetClient(second); + + await pipeline([ + createReadableStream([{ Data: "a", PartitionKey: "a" }]), + awsKinesisPutRecordsStream({ StreamName: "test-stream" }), + ]); + + deepStrictEqual(second.commandCalls(PutRecordsCommand).length, 1); + deepStrictEqual(first.commandCalls(PutRecordsCommand).length, 0); +}); + +// *** GetRecords stops when NextShardIterator becomes null (shard closed) *** // +test(`${variant}: awsKinesisGetRecordsStream stops polling when NextShardIterator is null even with pollingActive`, async (_t) => { + const client = mockClient(KinesisClient); + awsKinesisSetClient(client); + + // A closed shard returns a null NextShardIterator: the generator must stop + // regardless of pollingActive. If `ShardIterator !== null` were dropped from + // the expectMore condition, pollingActive would loop forever. + client.on(GetRecordsCommand).resolves({ + Records: [{ Data: "a" }], + NextShardIterator: null, + }); + + const options = { + ShardIterator: "iter1", + pollingActive: true, + pollingDelay: 0, + }; + const stream = await awsKinesisGetRecordsStream(options); + const output = await streamToArray(stream); + + deepStrictEqual(output, [{ Data: "a" }]); + // Exactly one GetRecords call: the null iterator ends the loop. + deepStrictEqual(client.commandCalls(GetRecordsCommand).length, 1); +}); + +test(`${variant}: awsKinesisGetRecordsStream without pollingActive stops once records run out`, async (_t) => { + const client = mockClient(KinesisClient); + awsKinesisSetClient(client); + + // Non-null iterator but empty Records and no pollingActive: expectMore must + // become false (records.length > 0 is false). A surviving mutant that forces + // the loop true would call GetRecords forever. + client + .on(GetRecordsCommand) + .resolvesOnce({ Records: [{ Data: "a" }], NextShardIterator: "iter2" }) + .resolves({ Records: [], NextShardIterator: "iter3" }); + + const options = { ShardIterator: "iter1" }; + const stream = await awsKinesisGetRecordsStream(options); + const output = await streamToArray(stream); + + deepStrictEqual(output, [{ Data: "a" }]); + // First call returns a record (keep going), second returns empty (stop). + deepStrictEqual(client.commandCalls(GetRecordsCommand).length, 2); +}); + +// *** setClient stores the reference (not just prototype-mocked behavior) *** // +test(`${variant}: awsKinesisSetClient stores the passed client reference`, async (_t) => { + // mockClient patches the SDK prototype, hiding instance identity; a plain + // stub proves the stored reference is the one actually used to send. A + // `setClient(){}` mutant would leave the previous client in place and the + // stub's send would never run. + let calls = 0; + const stub = { + send: async () => { + calls++; + return { Records: [{ Data: "stub" }], NextShardIterator: null }; + }, + }; + awsKinesisSetClient(stub); + + const stream = await awsKinesisGetRecordsStream({ ShardIterator: "iter1" }); + const output = await streamToArray(stream); + + deepStrictEqual(output, [{ Data: "stub" }]); + deepStrictEqual(calls, 1); +}); + +// *** getRecords forwards the caller options (spread, not {}) to the command *** // +test(`${variant}: awsKinesisGetRecordsStream forwards ShardIterator to GetRecords`, async (_t) => { + // Capture the ShardIterator at send time: the generator mutates opts.ShardIterator + // to the (null) NextShardIterator AFTER the await, so we must read it synchronously + // inside send. A `command({})` object-literal mutant starts with an empty opts and + // the first command would carry ShardIterator === undefined. + let firstShardIterator = "unset"; + const stub = { + send: (command) => { + if (firstShardIterator === "unset") { + firstShardIterator = command.input.ShardIterator; + } + return Promise.resolve({ + Records: [{ Data: "a" }], + NextShardIterator: null, + }); + }, + }; + awsKinesisSetClient(stub); + + const stream = await awsKinesisGetRecordsStream({ + ShardIterator: "iter-xyz", + }); + await streamToArray(stream); + + deepStrictEqual(firstShardIterator, "iter-xyz"); +}); + +// *** polling delay guard: each conjunct of the idle-wait condition *** // +test(`${variant}: awsKinesisGetRecordsStream does not delay when records are present (pollingActive)`, async (t) => { + t.mock.timers.enable({ apis: ["setTimeout"] }); + const client = mockClient(KinesisClient); + awsKinesisSetClient(client); + // Always returns records: the idle-wait `records.length === 0` conjunct is + // false, so no timeout should ever be scheduled. A `true` mutant on that + // conjunct would delay between every (non-empty) poll and the consumer would + // stall on the (un-ticked) mock timer. + client.on(GetRecordsCommand).resolves({ + Records: [{ Data: "a" }], + NextShardIterator: "iter-next", + }); + + const options = { + ShardIterator: "iter1", + pollingActive: true, + pollingDelay: 60_000, + }; + const stream = await awsKinesisGetRecordsStream(options); + + const output = []; + for await (const item of stream) { + output.push(item); + if (output.length >= 3) break; + } + deepStrictEqual(output.length, 3); +}); + +test(`${variant}: awsKinesisGetRecordsStream pollingDelay 0 schedules no timer`, async (t) => { + t.mock.timers.enable({ apis: ["setTimeout"] }); + const client = mockClient(KinesisClient); + awsKinesisSetClient(client); + // pollingActive with empty records but pollingDelay === 0: the `pollingDelay > 0` + // guard is false so no idle wait runs. A `> 0` -> `true` or `>= 0` mutant would + // schedule a timeout(0) that the un-ticked mock timer never resolves, stalling + // the consumer (which would otherwise reach the 2nd record immediately). + client + .on(GetRecordsCommand) + .resolvesOnce({ Records: [], NextShardIterator: "iter2" }) + .resolves({ Records: [{ Data: "a" }], NextShardIterator: "iter3" }); + + const options = { + ShardIterator: "iter1", + pollingActive: true, + pollingDelay: 0, + }; + const stream = await awsKinesisGetRecordsStream(options); + + const output = []; + for await (const item of stream) { + output.push(item); + if (output.length >= 1) break; + } + deepStrictEqual(output, [{ Data: "a" }]); +}); + +test(`${variant}: awsKinesisGetRecordsStream non-polling empty page ends without an idle wait`, async (t) => { + t.mock.timers.enable({ apis: ["setTimeout"] }); + const client = mockClient(KinesisClient); + awsKinesisSetClient(client); + // Not polling: an empty page must end the stream WITHOUT entering the idle + // wait. The `&&` -> `||` mutant makes `pollingActive || records.length === 0` + // true on the empty page, scheduling a (default 1000ms) timeout the un-ticked + // mock timer never resolves -> the stream would hang instead of completing. + client + .on(GetRecordsCommand) + .resolvesOnce({ Records: [{ Data: "a" }], NextShardIterator: "iter2" }) + .resolves({ Records: [], NextShardIterator: "iter3" }); + + const stream = await awsKinesisGetRecordsStream({ ShardIterator: "iter1" }); + const output = await streamToArray(stream); + + deepStrictEqual(output, [{ Data: "a" }]); +}); + +// *** record byte accounting *** // +test(`${variant}: awsKinesisPutRecordsStream accepts a record with no Data field`, async (_t) => { + const client = mockClient(KinesisClient); + awsKinesisSetClient(client); + client.on(PutRecordsCommand).resolves({ FailedRecordCount: 0 }); + + // No Data property: the `record.Data != null` guard must skip the Data byte + // count. An `if (true)` mutant would call _byteLength(undefined) and throw. + const input = [{ PartitionKey: "p" }]; + await pipeline([ + createReadableStream(input), + awsKinesisPutRecordsStream({ StreamName: "test-stream" }), + ]); + deepStrictEqual(client.commandCalls(PutRecordsCommand).length, 1); +}); + +test(`${variant}: awsKinesisPutRecordsStream counts ExplicitHashKey as the deciding byte`, async (_t) => { + const client = mockClient(KinesisClient); + awsKinesisSetClient(client); + client.on(PutRecordsCommand).resolves({ FailedRecordCount: 0 }); + + // Data is EXACTLY 1MiB (allowed on its own, no PartitionKey). The 1-byte + // ExplicitHashKey is the ONLY thing tipping the record over 1MiB, so the + // `if (record.ExplicitHashKey != null)` branch (and its `+=`) must run. A + // `false`/`{}` mutant skips it and the record would be wrongly accepted. + const data = "x".repeat(1024 * 1024); + const input = [{ Data: data, ExplicitHashKey: "h" }]; + await rejects( + () => + pipeline([ + createReadableStream(input), + awsKinesisPutRecordsStream({ StreamName: "test-stream" }), + ]), + { message: "awsKinesisPutRecords record exceeds 1MiB limit" }, + ); +}); + +test(`${variant}: awsKinesisPutRecordsStream measures non-string Data by byteLength`, async (_t) => { + const client = mockClient(KinesisClient); + awsKinesisSetClient(client); + client.on(PutRecordsCommand).resolves({ FailedRecordCount: 0 }); + + // A Uint8Array exactly at the 1MiB limit must be accepted via .byteLength. + // The `typeof value === "string"` branch must be FALSE here; a `true` mutant + // would TextEncoder.encode() the typed array (encoding its iterable/UTF-8 view + // rather than measuring byteLength) and the boundary check would shift. + const exact = new Uint8Array(1024 * 1024); + await pipeline([ + createReadableStream([{ Data: exact }]), + awsKinesisPutRecordsStream({ StreamName: "test-stream" }), + ]); + deepStrictEqual(client.commandCalls(PutRecordsCommand).length, 1); + + const over = new Uint8Array(1024 * 1024 + 1); + await rejects( + () => + pipeline([ + createReadableStream([{ Data: over }]), + awsKinesisPutRecordsStream({ StreamName: "test-stream" }), + ]), + { message: "awsKinesisPutRecords record exceeds 1MiB limit" }, + ); +}); + +test(`${variant}: awsKinesisPutRecordsStream oversize error cause carries bytes and limit`, async (_t) => { + const client = mockClient(KinesisClient); + awsKinesisSetClient(client); + client.on(PutRecordsCommand).resolves({ FailedRecordCount: 0 }); + + const tooBig = "x".repeat(1024 * 1024 + 1); + await rejects( + () => + pipeline([ + createReadableStream([{ Data: tooBig, PartitionKey: "k" }]), + awsKinesisPutRecordsStream({ StreamName: "test-stream" }), + ]), + (error) => { + deepStrictEqual( + error.message, + "awsKinesisPutRecords record exceeds 1MiB limit", + ); + // `{}` mutant on the cause object would drop these fields. bytes counts + // Data (1MiB+1) plus the 1-byte PartitionKey. + deepStrictEqual(error.cause.limit, 1024 * 1024); + deepStrictEqual(error.cause.bytes, 1024 * 1024 + 2); + return true; + }, + ); +}); + +// *** success short-circuit: a stray ErrorCode with FailedRecordCount 0 must not retry *** // +test(`${variant}: awsKinesisPutRecordsStream does not retry when FailedRecordCount is 0`, async (_t) => { + const client = mockClient(KinesisClient); + awsKinesisSetClient(client); + // FailedRecordCount 0 but a stray ErrorCode entry: the `if (!FailedRecordCount)` + // early return must fire so we do NOT loop into the filter-and-retry path. A + // `false` mutant (or removed return block) would see the ErrorCode and retry. + client.on(PutRecordsCommand).resolves({ + FailedRecordCount: 0, + Records: [{ ErrorCode: "ShouldBeIgnored" }], + }); + + await pipeline([ + createReadableStream([{ Data: "a", PartitionKey: "a" }]), + awsKinesisPutRecordsStream({ StreamName: "test-stream" }), + ]); + deepStrictEqual(client.commandCalls(PutRecordsCommand).length, 1); +}); + +// *** results indexing tolerates a short Records array (optional chaining) *** // +test(`${variant}: awsKinesisPutRecordsStream tolerates a results array shorter than records`, async (_t) => { + const client = mockClient(KinesisClient); + awsKinesisSetClient(client); + // Two records sent, but the response Records array has a single entry. The + // failed-records filter indexes results[1] which is undefined; the + // `results[index]?.ErrorCode` optional chain must guard it. A non-optional + // `results[index].ErrorCode` mutant throws a TypeError on index 1. + client + .on(PutRecordsCommand) + .resolvesOnce({ + FailedRecordCount: 1, + Records: [{ ErrorCode: "ProvisionedThroughputExceededException" }], + }) + .resolves({ FailedRecordCount: 0 }); + + await pipeline([ + createReadableStream([ + { Data: "a", PartitionKey: "a" }, + { Data: "b", PartitionKey: "b" }, + ]), + awsKinesisPutRecordsStream({ StreamName: "test-stream" }), + ]); + + const calls = client.commandCalls(PutRecordsCommand); + deepStrictEqual(calls.length, 2); + // Only the first record (the one with an ErrorCode) is retried. + deepStrictEqual(calls[1].args[0].input.Records, [ + { Data: "a", PartitionKey: "a" }, + ]); +}); + +// *** retryCount must increment so retryMaxCount is eventually reached *** // +test(`${variant}: awsKinesisPutRecordsStream stops retrying after retryMaxCount`, async (_t) => { + const client = mockClient(KinesisClient); + awsKinesisSetClient(client); + // Persistent failure with retryMaxCount 2: retryCount must climb 0->1->2 and + // throw after 3 attempts. A `retryCount--` mutant would drive it negative, + // never reach the cap, and retry forever (test timeout = killed). + client.on(PutRecordsCommand).resolves({ + FailedRecordCount: 1, + Records: [{ ErrorCode: "InternalFailure" }], + }); + + await rejects( + () => + pipeline([ + createReadableStream([{ Data: "a", PartitionKey: "a" }]), + awsKinesisPutRecordsStream({ + StreamName: "test-stream", + retryMaxCount: 2, + }), + ]), + { message: "awsKinesisPutRecords has failed records" }, + ); + // 1 initial + 2 retries = 3 attempts. + deepStrictEqual(client.commandCalls(PutRecordsCommand).length, 3); +}); + +// *** aggregate byte cap is 5MiB - 64KiB (subtract 64*1024, not 64/1024) *** // +test(`${variant}: awsKinesisPutRecordsStream cap subtracts 64KiB (not 64/1024)`, async (_t) => { + const client = mockClient(KinesisClient); + awsKinesisSetClient(client); + client.on(PutRecordsCommand).resolves({ FailedRecordCount: 0 }); + + // Real cap = 5*1024*1024 - 64*1024 = 5,177,344. A `64 / 1024` mutant makes the + // cap ~5,242,879.94 (essentially 5MiB). Five 1,048,001-byte records sum to + // 5,240,005 which is OVER the real cap (so the 5th forces a flush after 4) but + // UNDER the mutated cap (so all five would batch together). + const data = "x".repeat(1_048_000); // 1,048,000 Data + 1-byte PartitionKey + const input = Array.from({ length: 5 }, (_v, i) => ({ + Data: data, + PartitionKey: `${i % 10}`, + })); + await pipeline([ + createReadableStream(input), + awsKinesisPutRecordsStream({ StreamName: "test-stream" }), + ]); + + const calls = client.commandCalls(PutRecordsCommand); + deepStrictEqual(calls.length, 2); + deepStrictEqual(calls[0].args[0].input.Records.length, 4); + deepStrictEqual(calls[1].args[0].input.Records.length, 1); +}); + +// *** byte-cap boundary uses strict `>` (equal-to-cap stays in the batch) *** // +test(`${variant}: awsKinesisPutRecordsStream keeps a batch summing exactly to the cap`, async (_t) => { + const client = mockClient(KinesisClient); + awsKinesisSetClient(client); + client.on(PutRecordsCommand).resolves({ FailedRecordCount: 0 }); + + // 65,536-byte records (65,535 Data + 1-byte PartitionKey). 79 of them sum to + // exactly the cap (79 * 65,536 = 5,177,344). With strict `>` the 79th stays in + // the batch (flush happens only when the 80th would exceed the cap) -> first + // flush carries 79. A `>=` mutant flushes one record early -> 78. + const data = "x".repeat(65_535); + const input = Array.from({ length: 80 }, (_v, i) => ({ + Data: data, + PartitionKey: `${i % 10}`, + })); + await pipeline([ + createReadableStream(input), + awsKinesisPutRecordsStream({ StreamName: "test-stream" }), + ]); + + const calls = client.commandCalls(PutRecordsCommand); + deepStrictEqual(calls.length, 2); + deepStrictEqual(calls[0].args[0].input.Records.length, 79); + deepStrictEqual(calls[1].args[0].input.Records.length, 1); +}); + +// *** putRecords backoff is abortable (signal forwarded to the timeout) *** // +test(`${variant}: awsKinesisPutRecordsStream aborts during retry backoff`, async (_t) => { + const client = mockClient(KinesisClient); + awsKinesisSetClient(client); + // Persistent partial failure so the stream enters the (real-timer) backoff. + client.on(PutRecordsCommand).resolves({ + FailedRecordCount: 1, + Records: [{ ErrorCode: "ProvisionedThroughputExceededException" }], + }); + + let sends = 0; + client.on(PutRecordsCommand).callsFake(() => { + sends++; + return Promise.resolve({ + FailedRecordCount: 1, + Records: [{ ErrorCode: "ProvisionedThroughputExceededException" }], + }); + }); + + const controller = new AbortController(); + const consuming = pipeline([ + createReadableStream([{ Data: "a", PartitionKey: "a" }]), + awsKinesisPutRecordsStream( + { StreamName: "test-stream" }, + { signal: controller.signal }, + ), + ]); + + // Let the first send fail and enter the backoff timer, then abort. + await new Promise((resolve) => setImmediate(resolve)); + controller.abort(); + + await rejects(consuming, (error) => { + return error.cause?.code === "AbortError" || /Abort/i.test(error.message); + }); + + // The backoff timeout was given `{ signal }`, so the abort rejects the pending + // backoff immediately and NO further PutRecords is issued. A `{}` mutant + // (dropping the signal) leaves the backoff running so it wakes and retries + // repeatedly during this window -> far more than one send. + await new Promise((resolve) => setTimeout(resolve, 300)); + deepStrictEqual(sends, 1); +}); diff --git a/packages/aws/lambda.js b/packages/aws/lambda.js index 45bc198..c89e256 100644 --- a/packages/aws/lambda.js +++ b/packages/aws/lambda.js @@ -20,13 +20,18 @@ export const awsLambdaReadableStream = (lambdaOptions, streamOptions = {}) => { }; export const awsLambdaResponseStream = awsLambdaReadableStream; +// Fail-fast across the array form: a send() rejection or an InvokeComplete +// ErrorCode terminates the generator and later invocations do not run. The +// thrown Error's cause carries the offending FunctionName/index so consumers +// can identify which invocation failed. async function* awsLambdaGenerator(lambdaOptions, streamOptions = {}) { if (!Array.isArray(lambdaOptions)) { lambdaOptions = [lambdaOptions]; } - for (const options of lambdaOptions) { - const response = await defaultClient.send( - new InvokeWithResponseStreamCommand(options), + for (let index = 0; index < lambdaOptions.length; index++) { + const { client, ...invokeOptions } = lambdaOptions[index]; + const response = await (client ?? defaultClient).send( + new InvokeWithResponseStreamCommand(invokeOptions), { abortSignal: streamOptions.signal }, ); for await (const chunk of response.EventStream) { @@ -34,7 +39,11 @@ async function* awsLambdaGenerator(lambdaOptions, streamOptions = {}) { yield chunk.PayloadChunk.Payload; } else if (chunk?.InvokeComplete?.ErrorCode) { throw new Error(chunk.InvokeComplete.ErrorCode, { - cause: chunk.InvokeComplete.ErrorDetails, + cause: { + FunctionName: invokeOptions.FunctionName, + index, + ErrorDetails: chunk.InvokeComplete.ErrorDetails, + }, }); } } diff --git a/packages/aws/lambda.test.js b/packages/aws/lambda.test.js index 5323cbe..d492d10 100644 --- a/packages/aws/lambda.test.js +++ b/packages/aws/lambda.test.js @@ -73,7 +73,8 @@ if (variant === "node") { strictEqual(true, false); } catch (e) { strictEqual(e.message, "ErrorCode"); - strictEqual(e.cause, "ErrorDetails"); + strictEqual(e.cause.ErrorDetails, "ErrorDetails"); + strictEqual(e.cause.index, 0); } }); @@ -147,6 +148,95 @@ if (variant === "node") { deepStrictEqual(calls[0].args[1]?.abortSignal, controller.signal); }); + test(`${variant}: awsLambdaReadableStream should use per-call client option`, async (_t) => { + // default client must NOT be used when options.client is supplied + const defaultClientMock = mockClient(LambdaClient); + awsLambdaSetClient(defaultClientMock); + defaultClientMock + .on(InvokeWithResponseStreamCommand) + .rejects(new Error("default client should not be called")); + + const perCallClient = mockClient(LambdaClient); + const encoder = new TextEncoder(); + const decoder = new TextDecoder(); + perCallClient.on(InvokeWithResponseStreamCommand).resolves({ + EventStream: createReadableStream([ + { PayloadChunk: { Payload: encoder.encode("z") } }, + ]), + }); + + let result = ""; + for await (const chunk of await awsLambdaReadableStream({ + FunctionName: "f", + client: perCallClient, + })) { + result += decoder.decode(chunk); + } + + deepStrictEqual(result, "z"); + deepStrictEqual( + perCallClient.commandCalls(InvokeWithResponseStreamCommand).length, + 1, + ); + deepStrictEqual( + defaultClientMock.commandCalls(InvokeWithResponseStreamCommand).length, + 0, + ); + }); + + test(`${variant}: awsLambdaReadableStream should not send client field as invoke input`, async (_t) => { + const perCallClient = mockClient(LambdaClient); + const encoder = new TextEncoder(); + perCallClient.on(InvokeWithResponseStreamCommand).resolves({ + EventStream: createReadableStream([ + { PayloadChunk: { Payload: encoder.encode("ok") } }, + ]), + }); + + for await (const _chunk of await awsLambdaReadableStream({ + FunctionName: "f", + client: perCallClient, + })) { + // consume + } + + const calls = perCallClient.commandCalls(InvokeWithResponseStreamCommand); + deepStrictEqual(calls[0].args[0].input.client, undefined); + deepStrictEqual(calls[0].args[0].input.FunctionName, "f"); + }); + + test(`${variant}: awsLambdaReadableStream should include FunctionName in error cause`, async (_t) => { + const client = mockClient(LambdaClient); + awsLambdaSetClient(client); + + client + .on(InvokeWithResponseStreamCommand, { FunctionName: "fn1" }) + .resolves({ + EventStream: createReadableStream([ + { + InvokeComplete: { + ErrorCode: "Unhandled", + ErrorDetails: "boom", + }, + }, + ]), + }); + + try { + for await (const _chunk of await awsLambdaReadableStream([ + { FunctionName: "fn1" }, + ])) { + // consume + } + strictEqual(true, false); + } catch (e) { + strictEqual(e.message, "Unhandled"); + strictEqual(e.cause.FunctionName, "fn1"); + strictEqual(e.cause.index, 0); + strictEqual(e.cause.ErrorDetails, "boom"); + } + }); + test(`${variant}: default export should include all stream functions`, (_t) => { deepStrictEqual(Object.keys(lambdaDefault).sort(), [ "readableStream", @@ -154,4 +244,127 @@ if (variant === "node") { "setClient", ]); }); + + // A non-payload, non-complete event must be silently skipped: neither yielded + // nor treated as an error. Pins the `chunk?.PayloadChunk?.Payload` / + // `chunk?.InvokeComplete?.ErrorCode` guards and the `else if (...)` condition + // (an `else if (true)` mutant would throw on the empty frame). + test(`${variant}: awsLambdaReadableStream skips frames with neither PayloadChunk nor InvokeComplete`, async (_t) => { + const client = mockClient(LambdaClient); + awsLambdaSetClient(client); + + const encoder = new TextEncoder(); + const decoder = new TextDecoder(); + // A null/undefined frame must be tolerated by the leading `chunk?.` guards: + // dropping the optional chain (`chunk.PayloadChunk` / `chunk.InvokeComplete`) + // would throw a TypeError on these frames. + client.on(InvokeWithResponseStreamCommand).resolves({ + EventStream: createReadableStream([ + null, + undefined, + {}, + { SomethingElse: { foo: "bar" } }, + { PayloadChunk: { Payload: encoder.encode("ok") } }, + { InvokeComplete: {} }, + ]), + }); + + let result = ""; + for await (const chunk of await awsLambdaReadableStream({ + FunctionName: "f", + })) { + result += decoder.decode(chunk); + } + deepStrictEqual(result, "ok"); + }); + + // An InvokeComplete WITHOUT an ErrorCode must NOT throw (success completion). + // Kills the `else if (true)` mutant which would throw on every complete. + test(`${variant}: awsLambdaReadableStream treats InvokeComplete without ErrorCode as success`, async (_t) => { + const client = mockClient(LambdaClient); + awsLambdaSetClient(client); + + const encoder = new TextEncoder(); + const decoder = new TextDecoder(); + client.on(InvokeWithResponseStreamCommand).resolves({ + EventStream: createReadableStream([ + { PayloadChunk: { Payload: encoder.encode("done") } }, + { InvokeComplete: { LogResult: "..." } }, + ]), + }); + + let result = ""; + for await (const chunk of await awsLambdaReadableStream({ + FunctionName: "f", + })) { + result += decoder.decode(chunk); + } + deepStrictEqual(result, "done"); + }); + + // setClient must STORE the passed client as the module default. mockClient + // patches the SDK prototype (so instance identity is invisible to it); use a + // plain stub whose own send() proves the stored reference is actually used. A + // `setClient(){}` mutant leaves the original default in place and the stub's + // send is never called. + test(`${variant}: awsLambdaSetClient stores the passed client as the default`, async (_t) => { + const encoder = new TextEncoder(); + const decoder = new TextDecoder(); + let calls = 0; + const stub = { + send: async () => { + calls++; + return { + EventStream: createReadableStream([ + { PayloadChunk: { Payload: encoder.encode("stub") } }, + ]), + }; + }, + }; + awsLambdaSetClient(stub); + + let result = ""; + for await (const chunk of await awsLambdaReadableStream({ + FunctionName: "f", + })) { + result += decoder.decode(chunk); + } + deepStrictEqual(result, "stub"); + deepStrictEqual(calls, 1); + }); + + // setClient swaps the module default used when no per-call client is given. + test(`${variant}: awsLambdaSetClient routes to the newly set default client`, async (_t) => { + const first = mockClient(LambdaClient); + awsLambdaSetClient(first); + first + .on(InvokeWithResponseStreamCommand) + .rejects(new Error("stale default client should not be used")); + + const encoder = new TextEncoder(); + const decoder = new TextDecoder(); + const second = mockClient(LambdaClient); + second.on(InvokeWithResponseStreamCommand).resolves({ + EventStream: createReadableStream([ + { PayloadChunk: { Payload: encoder.encode("new") } }, + ]), + }); + awsLambdaSetClient(second); + + let result = ""; + for await (const chunk of await awsLambdaReadableStream({ + FunctionName: "f", + })) { + result += decoder.decode(chunk); + } + deepStrictEqual(result, "new"); + deepStrictEqual( + second.commandCalls(InvokeWithResponseStreamCommand).length, + 1, + ); + deepStrictEqual( + first.commandCalls(InvokeWithResponseStreamCommand).length, + 0, + ); + }); } diff --git a/packages/aws/package.json b/packages/aws/package.json index fb9bd3e..a222990 100644 --- a/packages/aws/package.json +++ b/packages/aws/package.json @@ -120,17 +120,43 @@ "types": "./sqs.d.ts", "default": "./sqs.web.mjs" } + }, + "./msk-iam": { + "node": { + "import": { + "types": "./msk-iam.d.ts", + "default": "./msk-iam.node.mjs" + } + }, + "import": { + "types": "./msk-iam.d.ts", + "default": "./msk-iam.web.mjs" + } + }, + "./glue-schema-registry": { + "node": { + "import": { + "types": "./glue-schema-registry.d.ts", + "default": "./glue-schema-registry.node.mjs" + } + }, + "import": { + "types": "./glue-schema-registry.d.ts", + "default": "./glue-schema-registry.web.mjs" + } } }, "types": "index.d.ts", "files": [ "*.mjs", "*.map", - "*.d.ts" + "*.d.ts", + "client.js" ], "scripts": { "test": "npm run test:unit", "test:unit": "node --test --conditions=node", + "test:mutation": "cd ../.. && MUTATE_PACKAGE=\"$(basename \"$OLDPWD\")\" stryker run", "test:benchmark": "node __benchmarks__/index.js" }, "license": "MIT", @@ -167,13 +193,14 @@ "@aws-sdk/client-cloudwatch-logs": "^3.0.0", "@aws-sdk/client-dynamodb": "^3.0.0", "@aws-sdk/client-dynamodb-streams": "^3.0.0", + "@aws-sdk/client-glue": "^3.0.0", "@aws-sdk/client-kinesis": "^3.0.0", "@aws-sdk/client-lambda": "^3.0.0", "@aws-sdk/client-s3": "^3.0.0", "@aws-sdk/client-sns": "^3.0.0", "@aws-sdk/client-sqs": "^3.0.0", - "@aws-sdk/client-ssm": "^3.0.0", - "@aws-sdk/lib-storage": "^3.0.0" + "@aws-sdk/lib-storage": "^3.0.0", + "aws-msk-iam-sasl-signer-js": "^1.0.0" }, "peerDependenciesMeta": { "@aws-sdk/client-cloudwatch-logs": { @@ -185,6 +212,9 @@ "@aws-sdk/client-dynamodb-streams": { "optional": true }, + "@aws-sdk/client-glue": { + "optional": true + }, "@aws-sdk/client-kinesis": { "optional": true }, @@ -200,10 +230,10 @@ "@aws-sdk/client-sqs": { "optional": true }, - "@aws-sdk/client-ssm": { + "@aws-sdk/lib-storage": { "optional": true }, - "@aws-sdk/lib-storage": { + "aws-msk-iam-sasl-signer-js": { "optional": true } }, @@ -211,13 +241,14 @@ "@aws-sdk/client-cloudwatch-logs": "^3.0.0", "@aws-sdk/client-dynamodb": "^3.0.0", "@aws-sdk/client-dynamodb-streams": "^3.0.0", + "@aws-sdk/client-glue": "^3.0.0", "@aws-sdk/client-kinesis": "^3.0.0", "@aws-sdk/client-lambda": "^3.0.0", "@aws-sdk/client-s3": "^3.0.0", "@aws-sdk/client-sns": "^3.0.0", "@aws-sdk/client-sqs": "^3.0.0", - "@aws-sdk/client-ssm": "^3.0.0", "@aws-sdk/lib-storage": "^3.0.0", + "aws-msk-iam-sasl-signer-js": "^1.0.0", "aws-sdk-client-mock": "^4.0.0" } } diff --git a/packages/aws/s3.js b/packages/aws/s3.js index b74472d..83a3b5c 100644 --- a/packages/aws/s3.js +++ b/packages/aws/s3.js @@ -24,12 +24,47 @@ export const awsS3GetObjectStream = async (options, streamOptions = {}) => { if (!Body) { throw new Error("S3.GetObject not found", { cause: params }); } - return createReadableStream(Body, streamOptions); + const stream = createReadableStream(Body, streamOptions); + // Tie the SDK Body (live socket-backed readable) lifecycle to the returned + // wrapper: if the consumer errors/aborts, tear down Body so the underlying + // HTTP connection is not leaked. + const teardownBody = () => { + // Node Body is a Readable (destroy); web Body is a WHATWG ReadableStream + // (cancel). Call whichever exists, ignoring teardown errors so releasing + // the socket cannot re-throw on an already-failed Body. + try { + Body.destroy?.(); + } catch {} + try { + Body.cancel?.(); + } catch {} + }; + // Node build: createReadableStream returns a node Readable; clean up on its + // 'error' event (without an error argument, so releasing the socket does not + // re-emit an unhandled 'error' on the already-failed Body). + if (typeof stream?.on === "function") { + stream.on("error", teardownBody); + } + // Web build (and any build given an abort signal): the wrapper is a WHATWG + // ReadableStream with no 'error' event, so wire teardown to the abort signal + // so socket teardown on consumer abort is consistent across builds. + const { signal } = streamOptions; + if (signal) { + if (signal.aborted) { + teardownBody(); + } else { + signal.addEventListener("abort", teardownBody, { once: true }); + } + } + return stream; }; export const awsS3PutObjectStream = (options, streamOptions = {}) => { - const { onProgress, client, tags, ...params } = options; + const { onProgress, client, tags, partSize, queueSize, ...params } = options; const stream = createPassThroughStream(() => {}, streamOptions); + // lib-storage defaults to a 5 MiB partSize and a 10,000-part ceiling + // (~50 GiB max object). Expose partSize/queueSize so callers can raise the + // ceiling for very large streamed objects. const upload = new Upload({ client: client ?? defaultClient, params: { @@ -37,6 +72,8 @@ export const awsS3PutObjectStream = (options, streamOptions = {}) => { Body: stream, }, tags, + partSize, + queueSize, }); if (onProgress) { stream.on("httpUploadProgress", onProgress); diff --git a/packages/aws/s3.test.js b/packages/aws/s3.test.js index 353a173..1d119e8 100644 --- a/packages/aws/s3.test.js +++ b/packages/aws/s3.test.js @@ -1,4 +1,4 @@ -import { deepStrictEqual } from "node:assert"; +import { deepStrictEqual, rejects } from "node:assert"; import test from "node:test"; import { CreateMultipartUploadCommand, @@ -359,6 +359,251 @@ test(`${variant}: awsS3GetObjectStream should pass abort signal to client.send`, deepStrictEqual(calls[0].args[1]?.abortSignal, controller.signal); }); +// setClient must STORE the passed client; a plain stub (prototype-mock-proof) +// proves the stored reference is used. A `setClient(){}` mutant leaves the prior +// client in place and the stub's send would never run. +test(`${variant}: awsS3SetClient stores the passed client reference`, async (_t) => { + let calls = 0; + const stub = { + send: async () => { + calls++; + return { Body: createReadableStream("stub-data") }; + }, + }; + awsS3SetClient(stub); + + const stream = await awsS3GetObjectStream({ Bucket: "b", Key: "k" }); + const output = await streamToString(stream); + + deepStrictEqual(output, "stub-data"); + deepStrictEqual(calls, 1); +}); + +// The "not found" error carries the request params as its cause (kills the `{}` +// object-literal mutant on the error options). +test(`${variant}: awsS3GetObjectStream not-found error cause is the request params`, async (_t) => { + const client = mockClient(S3Client); + awsS3SetClient(client); + client.on(GetObjectCommand).resolves({}); + + const params = { Bucket: "bucket", Key: "missing.ext" }; + await rejects( + () => awsS3GetObjectStream({ ...params }), + (error) => { + deepStrictEqual(error.message, "S3.GetObject not found"); + deepStrictEqual(error.cause, params); + return true; + }, + ); +}); + +// On the node build the returned stream is a Readable; its 'error' event must +// tear down the SDK Body (destroy + cancel) so the socket is released. This pins +// the `if (typeof stream?.on === "function")` wiring, the teardownBody body, the +// try blocks and the `Body.destroy?.()` / `Body.cancel?.()` calls. +test(`${variant}: awsS3GetObjectStream tears down the Body when the stream errors`, async (_t) => { + let destroyed = 0; + let cancelled = 0; + // An async-iterable Body that also exposes destroy()/cancel() spies. + const body = { + async *[Symbol.asyncIterator]() { + yield "chunk"; + }, + destroy() { + destroyed++; + }, + cancel() { + cancelled++; + }, + }; + const stub = { send: async () => ({ Body: body }) }; + awsS3SetClient(stub); + + const stream = await awsS3GetObjectStream({ Bucket: "b", Key: "k" }); + // Emit an error on the returned node Readable -> the wired teardown runs. + await new Promise((resolve) => { + stream.on("error", () => resolve()); + stream.destroy(new Error("boom")); + }); + // Allow the 'error' listener (teardownBody) to run. + await new Promise((resolve) => setImmediate(resolve)); + + deepStrictEqual(destroyed, 1); + deepStrictEqual(cancelled, 1); +}); + +// An abort signal that fires AFTER the stream is created must tear down the Body +// via the addEventListener("abort", ...) wiring. Pins `if (signal)`, the else +// branch, the "abort" event-name literal, and proves teardown is not run eagerly. +test(`${variant}: awsS3GetObjectStream tears down the Body when a later abort fires`, async (_t) => { + let destroyed = 0; + const body = { + async *[Symbol.asyncIterator]() { + yield "chunk"; + }, + destroy() { + destroyed++; + }, + }; + const stub = { send: async () => ({ Body: body }) }; + awsS3SetClient(stub); + + const controller = new AbortController(); + const stream = await awsS3GetObjectStream( + { Bucket: "b", Key: "k" }, + { signal: controller.signal }, + ); + // Not aborted yet: teardown must NOT have run (kills `if (signal.aborted)` -> + // true, which would tear down eagerly). + deepStrictEqual(destroyed, 0); + + controller.abort(); + await new Promise((resolve) => setImmediate(resolve)); + // The "abort" listener fired teardownBody (the underlying Readable may also + // surface the abort via its 'error' event, so teardown can run more than once; + // it is idempotent). The key assertion is that it ran at all post-abort. + deepStrictEqual(destroyed >= 1, true); + + // Cleanup so the test does not leak the open stream. + stream.destroy(); +}); + +// An already-aborted signal tears down the Body eagerly during creation. Pins +// `if (signal.aborted)` (a `false` mutant would skip the eager teardown). +test(`${variant}: awsS3GetObjectStream tears down the Body immediately for a pre-aborted signal`, async (_t) => { + let destroyed = 0; + const body = { + async *[Symbol.asyncIterator]() { + yield "chunk"; + }, + destroy() { + destroyed++; + }, + }; + const stub = { send: async () => ({ Body: body }) }; + awsS3SetClient(stub); + + const controller = new AbortController(); + controller.abort(); + const stream = await awsS3GetObjectStream( + { Bucket: "b", Key: "k" }, + { signal: controller.signal }, + ); + // Eager teardown happened synchronously during the call. + deepStrictEqual(destroyed, 1); + stream.destroy(); +}); + +// onProgress must be wired to the upload's 'httpUploadProgress' event. Pins the +// `if (onProgress)` branch and the "httpUploadProgress" event-name literal. +test(`${variant}: awsS3PutObjectStream forwards httpUploadProgress to onProgress`, async (_t) => { + const client = mockClient(S3Client); + const defaultClient = new S3Client(); + client.config ??= {}; + client.config.requestChecksumCalculation ??= + defaultClient.config.requestChecksumCalculation; + awsS3SetClient(client); + + client + .on(PutObjectCommand) + .rejects() + .on(CreateMultipartUploadCommand) + .resolves({ UploadId: "1" }) + .on(UploadPartCommand) + .resolves({ ETag: "1" }); + + let progressEvents = 0; + const options = { + Bucket: "bucket", + Key: "file.ext", + onProgress: () => { + progressEvents++; + }, + }; + + const stream = awsS3PutObjectStream(options); + // Emitting 'httpUploadProgress' must reach onProgress. A `""` event-name mutant + // or a skipped `if (onProgress)` would never invoke the callback. + stream.emit("httpUploadProgress", { loaded: 1, total: 1 }); + deepStrictEqual(progressEvents, 1); + + const input = "x".repeat(6 * 1024 * 1024); + const result = await pipeline([createReadableStream(input), stream]); + deepStrictEqual(result, {}); +}); + +// An unsupported ChecksumAlgorithm throws with an informative message (pins the +// `if (!algorithm)` branch and the non-empty error template). +test(`${variant}: awsS3ChecksumStream throws for an unsupported ChecksumAlgorithm`, async (_t) => { + let threw; + try { + awsS3ChecksumStream({ ChecksumAlgorithm: "NOPE" }); + } catch (error) { + threw = error; + } + deepStrictEqual(threw?.message, "Unsupported ChecksumAlgorithm: NOPE"); +}); + +// Empty input -> no parts digested -> checksum is the empty string and there are +// zero part checksums. Pins `if (bytes.byteLength)` (a `true` mutant would digest +// the empty buffer), the `else` empty-string branch and that string literal. +test(`${variant}: awsS3ChecksumStream returns empty checksum for empty input`, async (_t) => { + const stream = [createReadableStream([]), awsS3ChecksumStream({})]; + const result = await pipeline(stream); + deepStrictEqual(result.s3.checksum, ""); + deepStrictEqual(result.s3.checksums.length, 0); +}); + +// Single-part input -> exactly one part checksum and the result checksum is that +// single part's base64 (NOT the multi-part composite). Pins `checksums.length > 1` +// (false branch) and `checksums.length === 1`. +test(`${variant}: awsS3ChecksumStream single-part checksum equals the only part`, async (_t) => { + const input = "x".repeat(16_384); + const stream = [ + createReadableStream(input), + awsS3ChecksumStream({ ChecksumAlgorithm: "SHA256" }), + ]; + const result = await pipeline(stream); + deepStrictEqual(result.s3.checksums.length, 1); + // For a single part, checksum === the lone part checksum (no `-N` suffix). + deepStrictEqual(result.s3.checksum, result.s3.checksums[0]); +}); + +// Multi-part input -> composite checksum carries the `-Base64 encoding and decoding streams.
@@ -18,10 +18,10 @@
-
+
-
+
You can read the documentation at: https://datastream.js.org
diff --git a/packages/base64/index.node.js b/packages/base64/index.node.js index 05e9bc4..1093ec6 100644 --- a/packages/base64/index.node.js +++ b/packages/base64/index.node.js @@ -10,6 +10,17 @@ const toBuffer = (chunk) => ? Buffer.from(chunk.buffer, chunk.byteOffset, chunk.byteLength) : Buffer.from(chunk); +// Valid base64 requires length to be a multiple of 4 and only valid alphabet +// chars, with at most 2 trailing '=' padding characters. This rejects short +// fragments like "YQ=" (length 3) and standalone padding like "==" (length 2) +// that Buffer.from leniently accepts but atob() in the Web build rejects. +const VALID_BASE64_RE = /^[A-Za-z0-9+/]*={0,2}$/; +const assertValidBase64 = (s) => { + if (s.length % 4 !== 0 || !VALID_BASE64_RE.test(s)) { + throw new Error(`Invalid base64 string: ${JSON.stringify(s)}`); + } +}; + export const base64EncodeStream = (_options = {}, streamOptions = {}) => { let extra; // Buffer | undefined const transform = (chunk, enqueue) => { @@ -45,10 +56,14 @@ export const base64DecodeStream = (_options = {}, streamOptions = {}) => { extra = s.slice(s.length - remaining); s = s.slice(0, s.length - remaining); } - if (s.length > 0) enqueue(Buffer.from(s, "base64")); + if (s.length > 0) { + assertValidBase64(s); + enqueue(Buffer.from(s, "base64")); + } }; const flush = (enqueue) => { if (extra.length > 0) { + assertValidBase64(extra); enqueue(Buffer.from(extra, "base64")); } }; diff --git a/packages/base64/index.test.js b/packages/base64/index.test.js index 67d8719..da57f11 100644 --- a/packages/base64/index.test.js +++ b/packages/base64/index.test.js @@ -8,6 +8,7 @@ import base64Default, { import { createReadableStream, pipejoin, + pipeline, streamToBuffer, streamToString, } from "@datastream/core"; @@ -102,14 +103,17 @@ test(`${variant}: base64DecodeStream should decode partial base64`, async (_t) = deepStrictEqual(output, "hello"); }); -// Test decode flush with remaining characters +// Test decode flush with a valid padded quartet held across chunks test(`${variant}: base64DecodeStream should flush remaining characters`, async (_t) => { const input = btoa("ab"); // "YWI=" - const chunks = [input.slice(0, 2)]; // Only send "YW" + // Split so that the first chunk contributes only part of a 4-char group; + // the decoder should buffer "YW" and combine with "I=" in the second chunk + // to form the complete valid quartet "YWI=" before decoding. + const chunks = [input.slice(0, 2), input.slice(2)]; // "YW" + "I=" const streams = [createReadableStream(chunks), base64DecodeStream()]; const output = await streamToBuffer(pipejoin(streams)); - deepStrictEqual(output.byteLength, 1); + deepStrictEqual(output.byteLength, 2); // "ab" is 2 bytes }); // *** Binary correctness *** // @@ -150,3 +154,134 @@ test(`${variant}: default export should include all stream functions`, (_t) => { "encodeStream", ]); }); + +// *** Padding validation parity (HIGH finding) *** // +// These malformed inputs must be REJECTED identically on both Node and Web builds. +// "YQ=" is a 3-char fragment (not a multiple of 4) — Node's Buffer.from is lenient +// but atob() throws; after the fix BOTH builds must throw. +const malformedPaddingCases = [ + { input: "YQ=", label: "3-char group with single pad (YQ=)" }, + { input: "Pw=", label: "3-char group with single pad (Pw=)" }, + { input: "QQ=", label: "3-char group with single pad (QQ=)" }, + { input: "==", label: "padding-only (==)" }, + { input: "AAAA==", label: "length-6 with trailing padding (AAAA==)" }, +]; + +for (const { input, label } of malformedPaddingCases) { + test(`${variant}: base64DecodeStream should reject malformed padding: ${label}`, async (_t) => { + let threw = false; + try { + await pipeline([createReadableStream([input]), base64DecodeStream()]); + } catch (_e) { + threw = true; + } + deepStrictEqual( + threw, + true, + `Expected decode of ${JSON.stringify(input)} to throw`, + ); + }); +} + +// Valid padded inputs that must be ACCEPTED on both builds +const validPaddedCases = [ + { + input: "YQ==", + expected: [0x61], + label: "2-char group double-pad (YQ==) -> 'a'", + }, + { + input: "YWI=", + expected: [0x61, 0x62], + label: "3-char group single-pad (YWI=) -> 'ab'", + }, + { + input: "AAAA", + expected: [0x00, 0x00, 0x00], + label: "unpadded 4-char group (AAAA) -> zeros", + }, +]; + +for (const { input, expected, label } of validPaddedCases) { + test(`${variant}: base64DecodeStream should accept valid padded input: ${label}`, async (_t) => { + const streams = [createReadableStream([input]), base64DecodeStream()]; + const output = await streamToBuffer(pipejoin(streams)); + deepStrictEqual(Array.from(output), expected); + }); +} + +// *** Regex anchor coverage *** // +// Inputs with invalid characters at the START or END (length % 4 == 0) must be rejected. +// Without the leading ^ anchor the regex would match a valid suffix and accept '!AAA'. +// Without the trailing $ anchor the regex would match a valid prefix and accept 'AAA!'. +test(`${variant}: base64DecodeStream should reject input with invalid leading char`, async (_t) => { + let threw = false; + try { + await pipeline([createReadableStream(["!AAA"]), base64DecodeStream()]); + } catch (_e) { + threw = true; + } + deepStrictEqual(threw, true, "Expected decode of '!AAA' to throw"); +}); + +test(`${variant}: base64DecodeStream should reject input with invalid trailing char`, async (_t) => { + let threw = false; + try { + await pipeline([createReadableStream(["AAA!"]), base64DecodeStream()]); + } catch (_e) { + threw = true; + } + deepStrictEqual(threw, true, "Expected decode of 'AAA!' to throw"); +}); + +// *** Error message content *** // +// Verify that the thrown error identifies the bad input string (not an empty message). +test(`${variant}: base64DecodeStream error message should include input and label`, async (_t) => { + let errorMessage = ""; + try { + await pipeline([createReadableStream(["!AAA"]), base64DecodeStream()]); + } catch (e) { + errorMessage = e.message; + } + deepStrictEqual( + errorMessage.includes("Invalid base64 string"), + true, + "Error message must contain 'Invalid base64 string'", + ); + deepStrictEqual( + errorMessage.includes("!AAA"), + true, + "Error message must include the bad input", + ); +}); + +// *** Buffer chunk through decode stream *** // +// Passing a Buffer (non-string) chunk exercises the toBuffer().toString('ascii') branch. +// A StringLiteral mutation that replaces 'ascii' with '' causes ERR_UNKNOWN_ENCODING, +// so the correct code must succeed and produce the expected bytes. +test(`${variant}: base64DecodeStream should decode Buffer chunks correctly`, async (_t) => { + const originalText = "Hello, World!"; + const b64 = Buffer.from(originalText).toString("base64"); + // Pass the base64 string as a Buffer chunk (not a plain string) + const streams = [ + createReadableStream([Buffer.from(b64)]), + base64DecodeStream(), + ]; + const output = await streamToBuffer(pipejoin(streams)); + deepStrictEqual(output.toString(), originalText); +}); + +// *** Line-40 slice mutation: cross-boundary extra tracking *** // +// Split a 16-char base64 string at offset 6 (6 % 4 == 2 → remainder=2). +// The correct code stores only the LAST 2 chars as extra; the mutant stores the full +// 6-char string. On the second chunk the mutant concatenates the wrong prefix, +// decoding different bytes (producing "HelHello World!" instead of "Hello World!"). +test(`${variant}: base64DecodeStream should track extra correctly across non-mod4 boundaries`, async (_t) => { + const originalText = "Hello World!"; + const b64 = Buffer.from(originalText).toString("base64"); // 16 chars + // Split so first chunk length is 6 (6 % 4 == 2, non-zero remainder) + const chunks = [b64.slice(0, 6), b64.slice(6)]; + const streams = [createReadableStream(chunks), base64DecodeStream()]; + const output = await streamToBuffer(pipejoin(streams)); + deepStrictEqual(output.toString(), originalText); +}); diff --git a/packages/base64/index.web.js b/packages/base64/index.web.js index 9176bbd..ced3913 100644 --- a/packages/base64/index.web.js +++ b/packages/base64/index.web.js @@ -3,6 +3,18 @@ /* global btoa, atob */ import { createTransformStream } from "@datastream/core"; +// Valid base64 requires length to be a multiple of 4 and only valid alphabet +// chars, with at most 2 trailing '=' padding characters. This rejects short +// fragments like "YQ=" (length 3) and standalone padding like "==" (length 2) +// so that the Web build (atob) and the Node build (Buffer.from) behave +// identically on malformed input. +const VALID_BASE64_RE = /^[A-Za-z0-9+/]*={0,2}$/; +const assertValidBase64 = (s) => { + if (s.length % 4 !== 0 || !VALID_BASE64_RE.test(s)) { + throw new Error(`Invalid base64 string: ${JSON.stringify(s)}`); + } +}; + const utf8Encoder = new TextEncoder(); const toBytes = (chunk) => { @@ -66,10 +78,14 @@ export const base64DecodeStream = (_options = {}, streamOptions = {}) => { extra = s.slice(s.length - remaining); s = s.slice(0, s.length - remaining); } - if (s.length > 0) enqueue(binaryStringToBytes(atob(s))); + if (s.length > 0) { + assertValidBase64(s); + enqueue(binaryStringToBytes(atob(s))); + } }; const flush = (enqueue) => { if (extra.length > 0) { + assertValidBase64(extra); enqueue(binaryStringToBytes(atob(extra))); } }; diff --git a/packages/base64/package.json b/packages/base64/package.json index c543062..d293021 100644 --- a/packages/base64/package.json +++ b/packages/base64/package.json @@ -39,6 +39,7 @@ "scripts": { "test": "npm run test:unit", "test:unit": "node --test", + "test:mutation": "cd ../.. && MUTATE_PACKAGE=\"$(basename \"$OLDPWD\")\" stryker run", "test:benchmark": "node __benchmarks__/index.js" }, "license": "MIT", diff --git a/packages/charset/README.md b/packages/charset/README.md index e0ea83c..982999e 100644 --- a/packages/charset/README.md +++ b/packages/charset/README.md @@ -1,6 +1,6 @@Character encoding and decoding streams.
@@ -18,10 +18,10 @@
-
+
-
+
You can read the documentation at: https://datastream.js.org
diff --git a/packages/charset/decode.node.js b/packages/charset/decode.node.js index 81b9525..135a246 100644 --- a/packages/charset/decode.node.js +++ b/packages/charset/decode.node.js @@ -12,15 +12,20 @@ export const charsetDecodeStream = ({ charset } = {}, streamOptions = {}) => { const conv = iconv.getDecoder(charset); const transform = (chunk, enqueue) => { + // conv.write() always returns a string (never nullish), so a plain + // .length check is enough. The stream is objectMode, so enqueue ignores + // any encoding argument; pass only the chunk. const res = conv.write(chunk); - if (res?.length) { - enqueue(res, "utf8"); + if (res.length) { + enqueue(res); } }; const flush = (enqueue) => { + // conv.end() can return undefined for some decoders (e.g. ISO-8859-1), + // so guard the length read with optional chaining. const res = conv.end(); if (res?.length) { - enqueue(res, "utf8"); + enqueue(res); } }; return createTransformStream(transform, flush, streamOptions); diff --git a/packages/charset/decode.web.js b/packages/charset/decode.web.js index 874e6bb..bbe240a 100644 --- a/packages/charset/decode.web.js +++ b/packages/charset/decode.web.js @@ -2,56 +2,26 @@ // SPDX-License-Identifier: MIT /* global TextDecoderStream */ -const supportedEncodings = new Set([ - "utf-8", - "utf-16le", - "utf-16be", - "ibm866", - "iso-8859-2", - "iso-8859-3", - "iso-8859-4", - "iso-8859-5", - "iso-8859-6", - "iso-8859-7", - "iso-8859-8", - "iso-8859-8-i", - "iso-8859-10", - "iso-8859-13", - "iso-8859-14", - "iso-8859-15", - "iso-8859-16", - "koi8-r", - "koi8-u", - "macintosh", - "windows-874", - "windows-1250", - "windows-1251", - "windows-1252", - "windows-1253", - "windows-1254", - "windows-1255", - "windows-1256", - "windows-1257", - "windows-1258", - "x-mac-cyrillic", - "gbk", - "gb18030", - "big5", - "euc-jp", - "iso-2022-jp", - "shift_jis", - "euc-kr", - "replacement", - "x-user-defined", -]); - export const charsetDecodeStream = ({ charset } = {}, _streamOptions = {}) => { - if (charset !== null && !supportedEncodings.has(charset.toLowerCase())) { + // Default/null charset means UTF-8, matching the node implementation which + // falls back to UTF-8 for unknown/missing encodings instead of crashing. + // `new TextDecoderStream(undefined)` already defaults to UTF-8, so normalise + // null to undefined. + if (charset === null || charset === undefined) { + return new TextDecoderStream(); + } + // Let TextDecoderStream validate the label rather than maintaining a manual + // allowlist that is stricter than the platform (it rejected valid labels such + // as ISO-8859-1 / ISO-8859-9 that TextDecoder accepts). The constructor + // throws a RangeError for genuinely unknown labels; rethrow with the + // package-branded message. + try { + return new TextDecoderStream(charset); + } catch { throw new Error( `charsetDecodeStream: Unsupported web encoding "${charset}"`, ); } - return new TextDecoderStream(charset); }; export default charsetDecodeStream; diff --git a/packages/charset/detect.js b/packages/charset/detect.js index bcd3466..592c21b 100644 --- a/packages/charset/detect.js +++ b/packages/charset/detect.js @@ -22,41 +22,86 @@ const charsetKeys = [ "ISO-8859-5", "ISO-8859-6", "ISO-8859-7", - "ISO-8859-8-I", "ISO-8859-8", "windows-1251", "windows-1256", "windows-1252", "windows-1254", "windows-1250", - "KOIR8-R", + "KOI8-R", "ISO-8859-9", ]; +// Cap the detection sample so we never buffer an unbounded amount of the +// stream. chardet analyses a representative prefix; 64KB is plenty. +const MAX_DETECTION_SAMPLE = 64 * 1024; + +// chardet reports pure-ASCII input as "ASCII" (often at confidence 100). ASCII +// is a strict subset of UTF-8, so fold an ASCII match into the UTF-8 bucket +// rather than discarding the highest-confidence result and reporting a +// spurious ISO-8859-1 winner. +const normaliseMatchName = (name) => (name === "ASCII" ? "UTF-8" : name); + +// Concatenate the sampled Uint8Array chunks without relying on the node-only +// Buffer global, so the shared detect source runs in the browser too. String +// chunks are encoded as UTF-8 bytes via TextEncoder for the same reason. +const concatBytes = (chunks, totalLength) => { + const out = new Uint8Array(totalLength); + let offset = 0; + for (const chunk of chunks) { + out.set(chunk, offset); + offset += chunk.length; + } + return out; +}; + export const charsetDetectStream = ({ resultKey } = {}, streamOptions = {}) => { - const charsets = Object.fromEntries(charsetKeys.map((k) => [k, 0])); - let chunkCount = 0; + // Accumulate a bounded byte sample and run chardet once on the whole sample + // in result(). Running analyse() per-chunk and averaging corrupts results at + // multibyte chunk boundaries (a split sequence mis-detects each fragment). + const sample = []; + let sampleLength = 0; + const encoder = new TextEncoder(); const passThrough = (chunk) => { - const matches = analyse( - typeof chunk === "string" ? Buffer.from(chunk) : chunk, - ); - chunkCount++; - if (matches.length) { - for (const match of matches) { - if (match.name in charsets) { - charsets[match.name] += match.confidence; - } - } - } + const bytes = typeof chunk === "string" ? encoder.encode(chunk) : chunk; + // Keep only the bytes that still fit under the cap. subarray clamps the + // end index to the array length, so this both passes short chunks through + // whole and truncates the one chunk that crosses MAX_DETECTION_SAMPLE; + // once the cap is reached remaining is 0 and the slice is empty, so no + // further bytes are ever sampled. This single bound makes the cap the + // sole gate (no redundant length guard that a slice would mask). + const remaining = MAX_DETECTION_SAMPLE - sampleLength; + const slice = bytes.subarray(0, remaining); + sample.push(slice); + sampleLength += slice.length; }; const stream = createPassThroughStream(passThrough, streamOptions); stream.result = () => { - const divisor = chunkCount || 1; + // No bytes seen: signal "nothing to detect" rather than a phantom guess so + // callers can distinguish empty input from a low-confidence real result. + if (!sampleLength) { + return { + key: resultKey ?? "charset", + value: { charset: undefined, confidence: 0 }, + }; + } + const charsets = Object.fromEntries(charsetKeys.map((k) => [k, 0])); + const matches = analyse(concatBytes(sample, sampleLength)); + for (const match of matches) { + const name = normaliseMatchName(match.name); + if (name in charsets) { + // chardet reports each charset once with a 0..100 confidence; ASCII + // folds into UTF-8, so take the strongest signal for the bucket + // (keeping the result within the 0..100 range rather than summing). + // charsets[name] is seeded to 0 by the allowlist; the ?? 0 fallback + // means that if the membership guard is ever dropped an unsupported + // name folds in at its real confidence (not NaN) and outranks the + // real winner, so the allowlist-filter test fails on that mutant. + charsets[name] = Math.max(charsets[name] ?? 0, match.confidence); + } + } const values = Object.entries(charsets) - .map(([charset, confidence]) => ({ - charset, - confidence: confidence / divisor, - })) + .map(([charset, confidence]) => ({ charset, confidence })) .sort((a, b) => b.confidence - a.confidence); return { key: resultKey ?? "charset", value: values[0] }; }; diff --git a/packages/charset/encode.node.js b/packages/charset/encode.node.js index b167dba..6a12ed6 100644 --- a/packages/charset/encode.node.js +++ b/packages/charset/encode.node.js @@ -11,14 +11,21 @@ export const charsetEncodeStream = ({ charset } = {}, streamOptions = {}) => { const conv = iconv.getEncoder(charset); const transform = (chunk, enqueue) => { + // conv.write() always returns a Buffer (never nullish), so a plain + // .length check is enough here. const res = conv.write(chunk); - if (res?.length) { + if (res.length) { enqueue(res); } }; - const flush = () => { - // iconv-lite encoder.end() always returns undefined, so no flush needed - conv.end(); + const flush = (enqueue) => { + // Stateful encoders (e.g. UTF-7-IMAP) buffer multibyte content and emit + // their trailing shift-out sequence only from end(); mirror decode.node.js + // and enqueue that tail so no data is dropped. + const res = conv.end(); + if (res?.length) { + enqueue(res); + } }; return createTransformStream(transform, flush, streamOptions); }; diff --git a/packages/charset/encode.web.js b/packages/charset/encode.web.js index 21dc5c2..d3b7d0f 100644 --- a/packages/charset/encode.web.js +++ b/packages/charset/encode.web.js @@ -2,8 +2,21 @@ // SPDX-License-Identifier: MIT /* global TextEncoderStream */ +// NOTE: web vs node parity caveat. The browser TextEncoder genuinely only +// supports UTF-8, so the web encoder is UTF-8-only and throws for any other +// charset. This is intentionally asymmetric with charsetDecodeStream (web), +// which accepts every label TextDecoder supports (UTF-16, ISO-8859-1, ...), and +// with the node encoder, which supports the full iconv set. A detect->encode +// pipeline that selects a non-UTF-8 charset works under node but throws under +// web; callers targeting the browser must encode to UTF-8. export const charsetEncodeStream = ({ charset } = {}, _streamOptions = {}) => { - if (charset !== null && charset.toUpperCase() !== "UTF-8") { + // Default/null charset means UTF-8, matching the node implementation. Only a + // non-UTF-8 charset is rejected; calling with no charset must not throw. + if ( + charset !== null && + charset !== undefined && + String(charset).toUpperCase() !== "UTF-8" + ) { throw new Error( `charsetEncodeStream: Web only supports UTF-8 encoding, got "${charset}"`, ); diff --git a/packages/charset/index.test.js b/packages/charset/index.test.js index b8bf89e..8122ad4 100644 --- a/packages/charset/index.test.js +++ b/packages/charset/index.test.js @@ -13,6 +13,7 @@ import { streamToArray, streamToString, } from "@datastream/core"; +import iconv from "iconv-lite"; let variant = "unknown"; for (const execArgv of process.execArgv) { @@ -262,6 +263,25 @@ test(`${variant}: charsetDecodeStream should handle unsupported charset`, async deepStrictEqual(output, "test"); }); +// *** stateful-encoder flush: encoders such as UTF-7-IMAP buffer multibyte +// content and emit the trailing shift sequence ONLY from end(); the flush +// handler must enqueue conv.end()'s return value or that tail is lost. *** // +test(`${variant}: charsetEncodeStream should flush trailing bytes of a stateful encoder (UTF-7-IMAP)`, async (_t) => { + const original = "Hello 世界"; + const streams = [ + createReadableStream([original]), + charsetEncodeStream({ charset: "UTF-7-IMAP" }), + ]; + + const stream = pipejoin(streams); + const output = await streamToArray(stream); + const encoded = Buffer.concat(output.map((c) => Buffer.from(c))); + + // Round-trip through iconv to confirm the full multibyte content survived. + const decoded = iconv.decode(encoded, "UTF-7-IMAP"); + deepStrictEqual(decoded, original); +}); + test(`${variant}: charsetEncodeStream should handle ISO-8859-8-I charset`, async (_t) => { const input = ["test"]; const streams = [ @@ -324,6 +344,37 @@ test(`${variant}: charsetDetectStream should identify UTF-8 for multibyte input` ok(value.confidence > 0, `confidence ${value.confidence} should be > 0`); }); +// *** ascii-classification: pure ASCII text (the most common input) must NOT +// be misreported as a high-confidence ISO-8859-1; ASCII is UTF-8-compatible +// so it should fold into UTF-8 rather than being dropped. *** // +test(`${variant}: charsetDetectStream should classify pure ASCII text as UTF-8`, async (_t) => { + for (const text of ["Hello World", "Test content", "abc", "1234567890"]) { + const streams = [ + createReadableStream([Buffer.from(text)]), + charsetDetectStream(), + ]; + await pipeline(streams); + const { value } = streams[1].result(); + strictEqual( + value.charset, + "UTF-8", + `ASCII text ${JSON.stringify(text)} should classify as UTF-8, got ${value.charset}@${value.confidence}`, + ); + ok(value.confidence > 0, `confidence ${value.confidence} should be > 0`); + } +}); + +// *** empty-input sentinel: an empty stream ran detection on zero bytes; the +// result must signal "nothing to detect" rather than a phantom UTF-8 guess. *** // +test(`${variant}: charsetDetectStream should signal unknown for empty input`, async (_t) => { + const streams = [createReadableStream([]), charsetDetectStream()]; + await pipeline(streams); + const { key, value } = streams[1].result(); + strictEqual(key, "charset"); + strictEqual(value.charset, undefined); + strictEqual(value.confidence, 0); +}); + // *** charsetDetectStream concurrent isolation regression *** // test(`${variant}: charsetDetectStream instances should not share state`, async (_t) => { const input1 = [Buffer.from("Hello World")]; @@ -386,3 +437,757 @@ if (variant === "webstream") { } }); } + +// *** detect-per-chunk-analyse: detection must be accurate across multibyte +// chunk boundaries (buffer for detection, do not average per-chunk) *** // +test(`${variant}: charsetDetectStream should detect UTF-8 when a multibyte char is split across chunks`, async (_t) => { + // A 3-byte UTF-8 character split mid-sequence so the first chunk is a single + // leading byte. Per-chunk analysis mis-detects the fragments (chunk1 -> + // UTF-32LE, chunk2 -> Shift_JIS) and averaging flips the winner away from + // UTF-8; whole-sample analysis must still confidently report UTF-8. + const full = Buffer.from("テスト", "utf8"); + const chunk1 = full.subarray(0, 1); + const chunk2 = full.subarray(1); + + const streams = [ + createReadableStream([chunk1, chunk2]), + charsetDetectStream(), + ]; + + await pipeline(streams); + const { value } = streams[1].result(); + + strictEqual(value.charset, "UTF-8"); + ok(value.confidence > 0, `confidence ${value.confidence} should be > 0`); +}); + +// *** koi8r-key-typo: KOI8-R encoded Cyrillic must be detected as KOI8-R +// (the accumulator key must match chardet's output name) *** // +test(`${variant}: charsetDetectStream should detect KOI8-R Cyrillic text`, async (_t) => { + // "Привет, как дела? ..." encoded as KOI8-R (single-byte Cyrillic). + // Byte sequence produced by iconv-lite koi8-r encode of the Russian text. + const koi8rBytes = Buffer.from([ + 0xf0, 0xd2, 0xc9, 0xd7, 0xc5, 0xd4, 0x2c, 0x20, 0xcb, 0xc1, 0xcb, 0x20, + 0xc4, 0xc5, 0xcc, 0xc1, 0x3f, 0x20, 0xfa, 0xd4, 0xcf, 0x20, 0xd4, 0xc5, + 0xd3, 0xd4, 0xcf, 0xd7, 0xd9, 0xca, 0x20, 0xd4, 0xc5, 0xcb, 0xd3, 0xd4, + 0x20, 0xce, 0xc1, 0x20, 0xd2, 0xd5, 0xd3, 0xd3, 0xcb, 0xcf, 0xcd, 0x20, + 0xd1, 0xda, 0xd9, 0xcb, 0xc5, 0x2e, + ]); + const streams = [createReadableStream([koi8rBytes]), charsetDetectStream()]; + + await pipeline(streams); + const { value } = streams[1].result(); + + strictEqual(value.charset, "KOI8-R"); + ok(value.confidence > 0, `confidence ${value.confidence} should be > 0`); +}); + +// *** web-specific fixes: import the web sources directly. A bare +// "@datastream/charset" import always resolves to the node build, so the +// *.web.js code paths are exercised by importing them by file URL. *** // +const decodeWeb = await import( + `file://${new URL("./decode.web.js", import.meta.url).pathname}` +); +const encodeWeb = await import( + `file://${new URL("./encode.web.js", import.meta.url).pathname}` +); +// detect.js is a single cross-platform source built for both node and web. To +// prove it is web-safe we import the source directly and run it with the +// node-only `Buffer` global removed, simulating a browser runtime. +const detectSource = await import( + `file://${new URL("./detect.js", import.meta.url).pathname}` +); + +const webStreamToString = async (stream, inputs) => { + const reader = stream.readable.getReader(); + const writer = stream.writable.getWriter(); + const collected = []; + const pump = (async () => { + while (true) { + const { done, value } = await reader.read(); + if (done) break; + collected.push(value); + } + })(); + for (const input of inputs) { + await writer.write(input); + } + await writer.close(); + await pump; + return collected.join(""); +}; + +const webStreamToBytes = async (stream, inputs) => { + const reader = stream.readable.getReader(); + const writer = stream.writable.getWriter(); + const collected = []; + const pump = (async () => { + while (true) { + const { done, value } = await reader.read(); + if (done) break; + collected.push(value); + } + })(); + for (const input of inputs) { + await writer.write(input); + } + await writer.close(); + await pump; + return Buffer.concat(collected.map((c) => Buffer.from(c))); +}; + +// *** web-default-charset-crash: no-arg / null charset must fall back to +// UTF-8 like node, not throw *** // +test(`${variant}: web charsetDecodeStream should default to UTF-8 with no charset`, async (_t) => { + const stream = decodeWeb.charsetDecodeStream(); + const output = await webStreamToString(stream, [Buffer.from("Test", "utf8")]); + strictEqual(output, "Test"); +}); + +test(`${variant}: web charsetDecodeStream should treat null charset as UTF-8`, async (_t) => { + const stream = decodeWeb.charsetDecodeStream({ charset: null }); + const output = await webStreamToString(stream, [ + Buffer.from("Hello", "utf8"), + ]); + strictEqual(output, "Hello"); +}); + +test(`${variant}: web charsetEncodeStream should default to UTF-8 with no charset`, async (_t) => { + const stream = encodeWeb.charsetEncodeStream(); + const output = await webStreamToBytes(stream, ["Test"]); + deepStrictEqual(output, Buffer.from("Test", "utf8")); +}); + +test(`${variant}: web charsetEncodeStream should treat null charset as UTF-8`, async (_t) => { + const stream = encodeWeb.charsetEncodeStream({ charset: null }); + const output = await webStreamToBytes(stream, ["Hello"]); + deepStrictEqual(output, Buffer.from("Hello", "utf8")); +}); + +// *** web-decode-allowlist-too-strict: ISO-8859-1 / ISO-8859-9 are accepted +// by TextDecoder and emitted by the detector, so decode must accept them *** // +test(`${variant}: web charsetDecodeStream should accept ISO-8859-1`, async (_t) => { + // 0xE9 is "é" in ISO-8859-1 (latin1). + const stream = decodeWeb.charsetDecodeStream({ charset: "ISO-8859-1" }); + const output = await webStreamToString(stream, [Buffer.from([0xe9])]); + strictEqual(output, "é"); +}); + +test(`${variant}: web charsetDecodeStream should accept ISO-8859-9`, async (_t) => { + const stream = decodeWeb.charsetDecodeStream({ charset: "ISO-8859-9" }); + const output = await webStreamToString(stream, [ + Buffer.from("abc", "latin1"), + ]); + strictEqual(output, "abc"); +}); + +test(`${variant}: web charsetDecodeStream should still reject genuinely unknown encodings`, async (_t) => { + try { + decodeWeb.charsetDecodeStream({ charset: "INVALID-CHARSET-999" }); + throw new Error("Expected error"); + } catch (e) { + ok( + e.message.includes("Unsupported web encoding"), + `unexpected error: ${e.message}`, + ); + } +}); + +// Run fn with the node-only `Buffer` global removed so any reference to it +// throws ReferenceError, simulating a browser runtime. createReadableStream / +// pipeline themselves do not depend on the Buffer global, so any +// "Buffer is not defined" comes from detect.js itself. +const withoutBuffer = async (fn) => { + const saved = globalThis.Buffer; + // Remove the global entirely (not just set undefined) so any reference to + // the bare `Buffer` identifier throws ReferenceError, matching a browser. + Reflect.deleteProperty(globalThis, "Buffer"); + try { + return await fn(); + } finally { + globalThis.Buffer = saved; + } +}; + +const driveDetect = async (inputs) => { + const streams = [ + createReadableStream(inputs), + detectSource.charsetDetectStream(), + ]; + await pipeline(streams); + return streams[1].result(); +}; + +// *** web-detect-buffer-crash: detect must not reference the node-only Buffer +// global in the web build. Exercise the source with BOTH a Uint8Array chunk +// and a string chunk (both pass through the byte-collection path that +// previously called Buffer.from / Buffer.concat) while Buffer is absent. *** // +test(`${variant}: web charsetDetectStream should detect ASCII without referencing Buffer`, async (_t) => { + const { key, value } = await withoutBuffer(() => + driveDetect([new TextEncoder().encode("Hello World")]), + ); + strictEqual(key, "charset"); + strictEqual(value.charset, "UTF-8"); + ok(value.confidence > 0, `confidence ${value.confidence} should be > 0`); +}); + +test(`${variant}: web charsetDetectStream should accept string chunks without Buffer`, async (_t) => { + const { value } = await withoutBuffer(() => driveDetect(["Test content"])); + strictEqual(value.charset, "UTF-8"); +}); + +test(`${variant}: web charsetDetectStream should signal unknown for empty input`, async (_t) => { + const { value } = await withoutBuffer(() => driveDetect([])); + strictEqual(value.charset, undefined); + strictEqual(value.confidence, 0); +}); + +// *** charset key string mutations: each charset name in the allowlist must be +// correct so that chardet results are stored under the right key and the +// top-confidence charset is reported accurately. Mutating any name to "" means +// the chardet result is lost and a wrong (zero-confidence) charset wins. *** // + +test(`${variant}: charsetDetectStream should detect UTF-16BE`, async (_t) => { + // UTF-16BE BOM + "Hello World" + const bytes = Buffer.from([ + 0xfe, 0xff, 0x00, 0x48, 0x00, 0x65, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x6f, + 0x00, 0x20, 0x00, 0x57, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x6c, 0x00, 0x64, + ]); + const streams = [createReadableStream([bytes]), charsetDetectStream()]; + await pipeline(streams); + const { value } = streams[1].result(); + strictEqual(value.charset, "UTF-16BE"); + ok(value.confidence > 0); +}); + +test(`${variant}: charsetDetectStream should detect UTF-16LE`, async (_t) => { + // UTF-16LE BOM + "Hello World" + const bytes = Buffer.from([ + 0xff, 0xfe, 0x48, 0x00, 0x65, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x6f, 0x00, + 0x20, 0x00, 0x57, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x6c, 0x00, 0x64, 0x00, + ]); + const streams = [createReadableStream([bytes]), charsetDetectStream()]; + await pipeline(streams); + const { value } = streams[1].result(); + strictEqual(value.charset, "UTF-16LE"); + ok(value.confidence > 0); +}); + +test(`${variant}: charsetDetectStream should detect UTF-32BE`, async (_t) => { + // UTF-32BE encoding of "Hello World" + const bytes = Buffer.from([ + 0, 0, 0, 72, 0, 0, 0, 101, 0, 0, 0, 108, 0, 0, 0, 108, 0, 0, 0, 111, 0, 0, + 0, 32, 0, 0, 0, 87, 0, 0, 0, 111, 0, 0, 0, 114, 0, 0, 0, 108, 0, 0, 0, 100, + ]); + const streams = [createReadableStream([bytes]), charsetDetectStream()]; + await pipeline(streams); + const { value } = streams[1].result(); + strictEqual(value.charset, "UTF-32BE"); + strictEqual(value.confidence, 100); +}); + +test(`${variant}: charsetDetectStream should detect UTF-32LE`, async (_t) => { + // UTF-32LE encoding of "Hello World" + const bytes = Buffer.from([ + 72, 0, 0, 0, 101, 0, 0, 0, 108, 0, 0, 0, 108, 0, 0, 0, 111, 0, 0, 0, 32, 0, + 0, 0, 87, 0, 0, 0, 111, 0, 0, 0, 114, 0, 0, 0, 108, 0, 0, 0, 100, 0, 0, 0, + ]); + const streams = [createReadableStream([bytes]), charsetDetectStream()]; + await pipeline(streams); + const { value } = streams[1].result(); + strictEqual(value.charset, "UTF-32LE"); + strictEqual(value.confidence, 100); +}); + +test(`${variant}: charsetDetectStream should detect Shift_JIS`, async (_t) => { + // Shift_JIS: "\u3053\u308C\u306F\u30C6\u30B9\u30C8\u3067\u3059\u3002\u65E5\u672C\u8A9E" + const bytes = Buffer.from([ + 130, 177, 130, 234, 130, 205, 131, 101, 131, 88, 131, 103, 130, 197, 130, + 183, 129, 66, 147, 250, 150, 123, 140, 234, + ]); + const streams = [createReadableStream([bytes]), charsetDetectStream()]; + await pipeline(streams); + const { value } = streams[1].result(); + strictEqual(value.charset, "Shift_JIS"); + strictEqual(value.confidence, 100); +}); + +test(`${variant}: charsetDetectStream should detect EUC-JP`, async (_t) => { + // EUC-JP: "\u3053\u308C\u306F\u30C6\u30B9\u30C8\u3067\u3059\u3002\u65E5\u672C\u8A9E" + const bytes = Buffer.from([ + 164, 179, 164, 236, 164, 207, 165, 198, 165, 185, 165, 200, 164, 199, 164, + 185, 161, 163, 198, 252, 203, 220, 184, 236, + ]); + const streams = [createReadableStream([bytes]), charsetDetectStream()]; + await pipeline(streams); + const { value } = streams[1].result(); + strictEqual(value.charset, "EUC-JP"); + strictEqual(value.confidence, 100); +}); + +test(`${variant}: charsetDetectStream should detect EUC-KR`, async (_t) => { + // EUC-KR: "\uC548\uB155\uD558\uC138\uC694 \uD55C\uAD6D\uC5B4 \uD14D\uC2A4\uD2B8" + const bytes = Buffer.from([ + 190, 200, 179, 231, 199, 207, 188, 188, 191, 228, 32, 199, 209, 177, 185, + 190, 238, 32, 197, 216, 189, 186, 198, 174, + ]); + const streams = [createReadableStream([bytes]), charsetDetectStream()]; + await pipeline(streams); + const { value } = streams[1].result(); + strictEqual(value.charset, "EUC-KR"); + strictEqual(value.confidence, 100); +}); + +test(`${variant}: charsetDetectStream should detect Big5`, async (_t) => { + // Big5: "\u9019\u662F\u6E2C\u8A66\u3002\u7E41\u9AD4\u4E2D\u6587\u6587\u672C" + const bytes = Buffer.from([ + 179, 111, 172, 79, 180, 250, 184, 213, 161, 67, 193, 99, 197, 233, 164, 164, + 164, 229, 164, 229, 165, 187, + ]); + const streams = [createReadableStream([bytes]), charsetDetectStream()]; + await pipeline(streams); + const { value } = streams[1].result(); + strictEqual(value.charset, "Big5"); + strictEqual(value.confidence, 100); +}); + +test(`${variant}: charsetDetectStream should detect GB18030`, async (_t) => { + // GB18030: "\u8FD9\u662F\u6D4B\u8BD5\u3002\u7B80\u4F53\u4E2D\u6587\u6587\u672C" + const bytes = Buffer.from([ + 213, 226, 202, 199, 178, 226, 202, 212, 161, 163, 188, 242, 204, 229, 214, + 208, 206, 196, 206, 196, 177, 190, + ]); + const streams = [createReadableStream([bytes]), charsetDetectStream()]; + await pipeline(streams); + const { value } = streams[1].result(); + strictEqual(value.charset, "GB18030"); + strictEqual(value.confidence, 100); +}); + +test(`${variant}: charsetDetectStream should detect ISO-2022-JP`, async (_t) => { + // ISO-2022-JP escape-sequence encoded Japanese + const bytes = Buffer.from([ + 0x1b, 0x24, 0x42, 0x46, 0x7c, 0x38, 0x6b, 0x4c, 0x68, 0x1b, 0x28, 0x42, + ]); + const streams = [createReadableStream([bytes]), charsetDetectStream()]; + await pipeline(streams); + const { value } = streams[1].result(); + strictEqual(value.charset, "ISO-2022-JP"); + ok(value.confidence > 0); +}); + +test(`${variant}: charsetDetectStream should detect ISO-2022-KR`, async (_t) => { + // ISO-2022-KR escape-sequence encoded Korean + const bytes = Buffer.from([ + 0x1b, 0x24, 0x29, 0x43, 0x0e, 0x4a, 0x49, 0x4e, 0x59, 0x0f, + ]); + const streams = [createReadableStream([bytes]), charsetDetectStream()]; + await pipeline(streams); + const { value } = streams[1].result(); + strictEqual(value.charset, "ISO-2022-KR"); + ok(value.confidence > 0); +}); + +test(`${variant}: charsetDetectStream should detect ISO-2022-CN`, async (_t) => { + // ISO-2022-CN escape-sequence encoded Chinese + const bytes = Buffer.from([ + 0x1b, 0x24, 0x29, 0x41, 0x0e, 0x32, 0x36, 0x33, 0x37, 0x0f, + ]); + const streams = [createReadableStream([bytes]), charsetDetectStream()]; + await pipeline(streams); + const { value } = streams[1].result(); + strictEqual(value.charset, "ISO-2022-CN"); + ok(value.confidence > 0); +}); + +test(`${variant}: charsetDetectStream should detect ISO-8859-1`, async (_t) => { + // ISO-8859-1: "La s\u00E9r\u00E9nade de pain fran\u00E7ais \u00E9tait tr\u00E8s \u00E9l\u00E9gante" + const bytes = Buffer.from([ + 0x4c, 0x61, 0x20, 0x73, 0xe9, 0x72, 0xe9, 0x6e, 0x61, 0x64, 0x65, 0x20, + 0x64, 0x65, 0x20, 0x70, 0x61, 0x69, 0x6e, 0x20, 0x66, 0x72, 0x61, 0xee, + 0xe7, 0x61, 0x69, 0x73, 0x20, 0xe9, 0x74, 0xe0, 0x69, 0x74, 0x20, 0x74, + 0x72, 0xe8, 0x73, 0x20, 0xe9, 0x6c, 0xe9, 0x67, 0x61, 0x6e, 0x74, 0x65, + 0x20, 0x63, 0x61, 0x72, 0x20, 0x65, 0x6c, 0x6c, 0x65, 0x20, 0x65, 0x73, + 0x74, 0x20, 0x74, 0x72, 0xe8, 0x73, 0x20, 0x62, 0x6f, 0x6e, 0x6e, 0x65, + ]); + const streams = [createReadableStream([bytes]), charsetDetectStream()]; + await pipeline(streams); + const { value } = streams[1].result(); + strictEqual(value.charset, "ISO-8859-1"); + ok(value.confidence > 0); +}); + +test(`${variant}: charsetDetectStream should detect ISO-8859-2`, async (_t) => { + // ISO-8859-2: Polish "Polskie znaki: szcz\u0119\u015Bcie, \u017Ar\u00F3d\u0142o, ni\u017C, b\u0142\u0105d" + const bytes = Buffer.from([ + 80, 111, 108, 115, 107, 105, 101, 32, 122, 110, 97, 107, 105, 58, 32, 115, + 122, 99, 122, 234, 182, 99, 105, 101, 44, 32, 188, 114, 243, 100, 179, 111, + 44, 32, 110, 105, 191, 44, 32, 98, 179, 177, 100, 44, 32, 243, 119, 44, 32, + 179, 177, 107, 97, 44, 32, 112, 114, 122, 121, 115, 122, 179, 111, 182, 230, + 46, + ]); + const streams = [createReadableStream([bytes]), charsetDetectStream()]; + await pipeline(streams); + const { value } = streams[1].result(); + strictEqual(value.charset, "ISO-8859-2"); + ok(value.confidence > 0); +}); + +test(`${variant}: charsetDetectStream should detect ISO-8859-5`, async (_t) => { + // ISO-8859-5: Cyrillic "\u042D\u0442\u043E \u0442\u0435\u0441\u0442\u043E\u0432\u044B\u0439 \u0442\u0435\u043A\u0441\u0442 \u043D\u0430 \u0440\u0443\u0441\u0441\u043A\u043E\u043C" + const bytes = Buffer.from([ + 205, 226, 222, 32, 226, 213, 225, 226, 222, 210, 235, 217, 32, 226, 213, + 218, 225, 226, 32, 221, 208, 32, 224, 227, 225, 225, 218, 222, 220, 32, 239, + 215, 235, 218, 213, + ]); + const streams = [createReadableStream([bytes]), charsetDetectStream()]; + await pipeline(streams); + const { value } = streams[1].result(); + strictEqual(value.charset, "ISO-8859-5"); + ok(value.confidence > 0); +}); + +test(`${variant}: charsetDetectStream should detect ISO-8859-6`, async (_t) => { + // ISO-8859-6: Arabic long text + const bytes = Buffer.from([ + 231, 208, 199, 32, 230, 213, 32, 217, 209, 200, 234, 46, 32, 199, 228, 230, + 213, 32, 199, 228, 217, 209, 200, 234, 32, 228, 228, 199, 206, 202, 200, + 199, 209, 46, 32, 199, 228, 199, 206, 202, 200, 199, 209, 32, 229, 231, 229, + 32, 204, 207, 199, 235, 46, 32, 230, 213, 32, 199, 206, 202, 200, 199, 209, + 32, 217, 209, 200, 234, 32, 229, 215, 232, 228, 46, + ]); + const streams = [createReadableStream([bytes]), charsetDetectStream()]; + await pipeline(streams); + const { value } = streams[1].result(); + strictEqual(value.charset, "ISO-8859-6"); + ok(value.confidence > 0); +}); + +test(`${variant}: charsetDetectStream should detect ISO-8859-7`, async (_t) => { + // ISO-8859-7: Greek "\u0391\u03C5\u03C4\u03CC \u03B5\u03AF\u03BD\u03B1\u03B9 \u03B5\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03CC \u03BA\u03B5\u03AF\u03BC\u03B5\u03BD\u03BF" + const bytes = Buffer.from([ + 193, 245, 244, 252, 32, 229, 223, 237, 225, 233, 32, 229, 235, 235, 231, + 237, 233, 234, 252, 32, 234, 229, 223, 236, 229, 237, 239, + ]); + const streams = [createReadableStream([bytes]), charsetDetectStream()]; + await pipeline(streams); + const { value } = streams[1].result(); + strictEqual(value.charset, "ISO-8859-7"); + ok(value.confidence > 0); +}); + +test(`${variant}: charsetDetectStream should detect ISO-8859-8`, async (_t) => { + // ISO-8859-8: Hebrew "\u05D6\u05D4\u05D5 \u05D8\u05E7\u05E1\u05D8 \u05D1\u05D3\u05D9\u05E7\u05D4 \u05D1\u05E2\u05D1\u05E8\u05D9\u05EA" + const bytes = Buffer.from([ + 230, 228, 229, 32, 232, 247, 241, 232, 32, 225, 227, 233, 247, 228, 32, 225, + 242, 225, 248, 233, 250, + ]); + const streams = [createReadableStream([bytes]), charsetDetectStream()]; + await pipeline(streams); + const { value } = streams[1].result(); + strictEqual(value.charset, "ISO-8859-8"); + ok(value.confidence > 0); +}); + +test(`${variant}: charsetDetectStream should detect ISO-8859-9`, async (_t) => { + // ISO-8859-9: Turkish "Bu T\u00FCrk\u00E7e bir test metni G\u00FC\u015F\u0130\u00D6\u00C7\u015E\u0130" + const bytes = Buffer.from([ + 66, 117, 32, 84, 252, 114, 107, 231, 101, 32, 98, 105, 114, 32, 116, 101, + 115, 116, 32, 109, 101, 116, 110, 105, 32, 71, 252, 254, 221, 214, 199, 222, + 221, + ]); + const streams = [createReadableStream([bytes]), charsetDetectStream()]; + await pipeline(streams); + const { value } = streams[1].result(); + strictEqual(value.charset, "ISO-8859-9"); + ok(value.confidence > 0); +}); + +test(`${variant}: charsetDetectStream should detect windows-1251`, async (_t) => { + // windows-1251: Cyrillic "\u041F\u0440\u0438\u0432\u0435\u0442 \u043C\u0438\u0440 \u042D\u0442\u043E \u0442\u0435\u0441\u0442\u043E\u0432\u044B\u0439 \u0442\u0435\u043A\u0441\u0442 \u043D\u0430 \u0440\u0443\u0441\u0441\u043A\u043E\u043C" + const bytes = Buffer.from([ + 207, 240, 232, 226, 229, 242, 32, 236, 232, 240, 32, 221, 242, 238, 32, 242, + 229, 241, 242, 238, 226, 251, 233, 32, 242, 229, 234, 241, 242, 32, 237, + 224, 32, 240, 243, 241, 241, 234, 238, 236, + ]); + const streams = [createReadableStream([bytes]), charsetDetectStream()]; + await pipeline(streams); + const { value } = streams[1].result(); + strictEqual(value.charset, "windows-1251"); + ok(value.confidence > 0); +}); + +test(`${variant}: charsetDetectStream should detect windows-1252`, async (_t) => { + // windows-1252 specific code points in 0x80-0x9F range (EUR, ellipsis, quotes, dashes) + const bytes = Buffer.from([ + 0x80, 0x85, 0x93, 0x94, 0x96, 0x97, 0x20, 0x48, 0x65, 0x6c, 0x6c, 0x6f, + 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x20, 0x54, 0x65, 0x73, 0x74, + ]); + const streams = [createReadableStream([bytes]), charsetDetectStream()]; + await pipeline(streams); + const { value } = streams[1].result(); + strictEqual(value.charset, "windows-1252"); + ok(value.confidence > 0); +}); + +test(`${variant}: charsetDetectStream should detect windows-1250`, async (_t) => { + // windows-1250: Polish "Polskie znaki: szcz\u0119\u015Bcie, \u017Ar\u00F3d\u0142o, ni\u017C, b\u0142\u0105d" + const bytes = Buffer.from([ + 80, 111, 108, 115, 107, 105, 101, 32, 122, 110, 97, 107, 105, 58, 32, 115, + 122, 99, 122, 234, 156, 99, 105, 101, 44, 32, 159, 114, 243, 100, 179, 111, + 44, 32, 110, 105, 191, 44, 32, 98, 179, 185, 100, 44, 32, 243, 119, 44, 32, + 179, 185, 107, 97, 44, 32, 112, 114, 122, 121, 115, 122, 179, 111, 156, 230, + 46, + ]); + const streams = [createReadableStream([bytes]), charsetDetectStream()]; + await pipeline(streams); + const { value } = streams[1].result(); + strictEqual(value.charset, "windows-1250"); + ok(value.confidence > 0); +}); + +test(`${variant}: charsetDetectStream should detect windows-1256`, async (_t) => { + // windows-1256: Arabic long text + const bytes = Buffer.from([ + 229, 208, 199, 32, 228, 213, 32, 199, 206, 202, 200, 199, 209, 32, 200, 199, + 225, 225, 219, 201, 32, 199, 225, 218, 209, 200, 237, 201, 46, 32, 199, 225, + 223, 202, 199, 200, 201, 32, 199, 225, 218, 209, 200, 237, 201, 32, 204, + 227, 237, 225, 201, 32, 230, 227, 218, 222, 207, 201, 46, + ]); + const streams = [createReadableStream([bytes]), charsetDetectStream()]; + await pipeline(streams); + const { value } = streams[1].result(); + strictEqual(value.charset, "windows-1256"); + ok(value.confidence > 0); +}); + +// *** detect-string-chunk: a string chunk must be encoded to bytes via +// TextEncoder so detection works correctly. Mutating typeof chunk === "string" +// to false causes the string to be passed raw to Uint8Array.set(), which +// silently writes zeros and detection returns garbage/undefined charset. *** // +test(`${variant}: charsetDetectStream should correctly detect charset from a string chunk`, async (_t) => { + // String chunk passed directly (not as Buffer). The passThrough function must + // encode it to bytes; if the typeof guard is removed the result is zeros. + const streams = [ + createReadableStream(["Hello World Test Content"]), + charsetDetectStream(), + ]; + await pipeline(streams); + const { value } = streams[1].result(); + strictEqual( + value.charset, + "UTF-8", + `string chunk should detect UTF-8, got ${value.charset}`, + ); + ok( + value.confidence > 0, + `confidence ${value.confidence} should be > 0 for string input`, + ); +}); + +// *** decode-valid-charset-preserved: when iconv.encodingExists(charset) is +// true the fallback to UTF-8 must NOT fire. Mutating the guard to if(true) +// would always reset charset to UTF-8, breaking decodes of other charsets. *** // +test(`${variant}: charsetDecodeStream should preserve non-UTF-8 charset (not fall back)`, async (_t) => { + // 0xE9 0xE0 0xE8 are "\u00E9\u00E0\u00E8" in ISO-8859-1; as UTF-8 these bytes are invalid + // and would be replaced with the Unicode replacement character U+FFFD. + const iso1bytes = Buffer.from([0xe9, 0xe0, 0xe8]); + const streams = [ + createReadableStream([iso1bytes]), + charsetDecodeStream({ charset: "ISO-8859-1" }), + ]; + const stream = pipejoin(streams); + const output = await streamToString(stream); + // Correct ISO-8859-1 decode yields "\u00E9\u00E0\u00E8" + strictEqual(output, "\u00E9\u00E0\u00E8"); + // If charset were wrongly replaced with UTF-8, output would contain U+FFFD + strictEqual(output.includes("\uFFFD"), false); +}); + +// *** decode-transform-empty-guard: conv.write() returns "" for partial +// multi-byte sequences; if the if(res?.length) guard is removed, empty strings +// are enqueued as extra chunks. A test counting chunks catches the mutant. *** // +test(`${variant}: charsetDecodeStream should not emit empty chunks for partial multi-byte sequences`, async (_t) => { + // U+1F600 emoji is 4 bytes in UTF-8: F0 9F 98 80. + // Split into 4 x 1-byte chunks so the first three write() calls return "". + // With guard: only 1 non-empty chunk ("\uD83D\uDE00") is enqueued. + // Without guard (if true): 4 chunks (3 x "" + "\uD83D\uDE00") are enqueued. + const emojiBytes = Buffer.from("\uD83D\uDE00", "utf8"); + const byteChunks = [ + emojiBytes.subarray(0, 1), + emojiBytes.subarray(1, 2), + emojiBytes.subarray(2, 3), + emojiBytes.subarray(3, 4), + ]; + const streams = [ + createReadableStream(byteChunks), + charsetDecodeStream({ charset: "UTF-8" }), + ]; + const stream = pipejoin(streams); + const output = await streamToArray(stream); + // Exactly one chunk: the complete emoji string + strictEqual(output.length, 1); + strictEqual(output[0], "\uD83D\uDE00"); +}); + +// *** encode-transform-empty-guard: conv.write() returns a 0-length Buffer for +// empty string chunks; if the guard is removed, empty Buffers are enqueued. +// A test checking the exact chunk count catches this mutant. *** // +test(`${variant}: charsetEncodeStream should not emit empty chunks for empty string inputs`, async (_t) => { + // Mix of empty strings and real content. Each empty string encodes to a + // 0-length Buffer. With guard: only the 2 non-empty inputs produce chunks. + // Without guard (if true): 5 chunks (3 x empty Buffer + 2 real). + const streams = [ + createReadableStream(["", "Hello", "", "World", ""]), + charsetEncodeStream({ charset: "UTF-8" }), + ]; + const stream = pipejoin(streams); + const output = await streamToArray(stream); + strictEqual(output.length, 2); + deepStrictEqual(output[0], Buffer.from("Hello")); + deepStrictEqual(output[1], Buffer.from("World")); +}); + +// *** detect-sample-cap: the passThrough must stop accumulating after +// MAX_DETECTION_SAMPLE (65536) bytes so memory is bounded and detection uses +// only the representative prefix. Mutating the guard to if(false) removes the +// cap entirely. This test confirms the stream completes without error and the +// sample cap code path is exercised. *** // +test(`${variant}: charsetDetectStream should handle input at and beyond MAX_DETECTION_SAMPLE`, async (_t) => { + // Send exactly MAX_DETECTION_SAMPLE + 1 bytes of ASCII content. + // Real code: returns early after 65536 bytes; extra byte is not sampled. + const MAX = 64 * 1024; // 65536 + const chunk1 = Buffer.alloc(MAX, 65); // 65536 x "A" + const chunk2 = Buffer.from([65]); // one more "A" + const streams = [ + createReadableStream([chunk1, chunk2]), + charsetDetectStream(), + ]; + await pipeline(streams); + const { value } = streams[1].result(); + strictEqual(value.charset, "UTF-8"); + ok(value.confidence > 0); +}); + +// *** slice-overflow: when a single chunk is larger than MAX_DETECTION_SAMPLE, +// the real code must truncate to exactly MAX bytes. Mutants that skip the +// truncation (if(false) conditional, MAX+sampleLength arithmetic, <=remaining +// comparison) all append the overflow bytes to the sample, which shifts +// chardet's answer from UTF-8 (ASCII prefix) to KOI8-R (Cyrillic overflow). *** // +test(`${variant}: charsetDetectStream should truncate a single oversized chunk to MAX_DETECTION_SAMPLE`, async (_t) => { + // Build a single chunk: first MAX bytes are pure ASCII (→ UTF-8 when capped), + // followed by 32 KB of KOI8-R Cyrillic bytes (→ KOI8-R when overflow leaks). + const MAX = 64 * 1024; + const koi8rPattern = Buffer.from([ + 0xf0, 0xd2, 0xc9, 0xd7, 0xc5, 0xd4, 0x2c, 0x20, 0xcb, 0xc1, 0xcb, 0x20, + 0xc4, 0xc5, 0xcc, 0xc1, 0x3f, 0x20, 0xfa, 0xd4, 0xcf, 0x20, 0xd4, 0xc5, + 0xd3, 0xd4, 0xcf, 0xd7, 0xd9, 0xca, 0x20, 0xd4, 0xc5, 0xcb, 0xd3, 0xd4, + 0x20, 0xce, 0xc1, 0x20, 0xd2, 0xd5, 0xd3, 0xd3, 0xcb, 0xcf, 0xcd, 0x20, + 0xd1, 0xda, 0xd9, 0xcb, 0xc5, 0x2e, + ]); + const overflow = Buffer.alloc(32 * 1024); + for (let i = 0; i < overflow.length; i++) + overflow[i] = koi8rPattern[i % koi8rPattern.length]; + + const singleChunk = Buffer.concat([Buffer.alloc(MAX, 0x41), overflow]); + const streams = [createReadableStream([singleChunk]), charsetDetectStream()]; + await pipeline(streams); + const { value } = streams[1].result(); + + // Real code caps at MAX bytes (pure ASCII → UTF-8 @ confidence 100). + // Any overflow mutant includes KOI8-R bytes and detects KOI8-R instead. + strictEqual( + value.charset, + "UTF-8", + `oversized chunk: expected UTF-8 but got ${value.charset}@${value.confidence}`, + ); + strictEqual(value.confidence, 100); +}); + +// *** charsets-allowlist-windows-1254: chardet can report "windows-1254" +// (Turkish encoding with c1 bytes). The charsetKeys array must contain the +// exact string "windows-1254" so the match is stored and wins. Mutating the +// key to "" means chardet's result is discarded and windows-1250 wins instead. *** // +test(`${variant}: charsetDetectStream should detect windows-1254`, async (_t) => { + // windows-1254 Turkish text with c1-range bytes (0x80-0x9F) that force the + // windows-1254 detector over ISO-8859-9. Bytes produced by: + // iconv.encode('Türkçe metin ...', 'windows-1254') plus c1 bytes. + const bytes = Buffer.from([ + 128, 156, 157, 158, 145, 146, 147, 148, 84, 252, 114, 107, 231, 101, 32, + 109, 101, 116, 105, 110, 32, 254, 105, 105, 114, 32, 107, 97, 108, 101, 109, + 32, 246, 240, 114, 101, 116, 109, 101, 110, 32, 103, 252, 122, 101, 108, 32, + 231, 111, 99, 117, 107, 32, 100, 252, 110, 121, 97, 32, 97, 105, 108, 101, + 128, 156, 157, 158, 145, 146, 147, 148, + ]); + const streams = [createReadableStream([bytes]), charsetDetectStream()]; + await pipeline(streams); + const { value } = streams[1].result(); + strictEqual(value.charset, "windows-1254"); + ok(value.confidence > 0); +}); + +// *** charsets-allowlist-filter: the "name in charsets" guard must filter +// chardet results to only the charsets listed in charsetKeys. Mutating the +// guard to "if(true)" lets unknown charset names (e.g. "windows-1255") bypass +// the filter and potentially win at high confidence, displacing the real winner +// from the charsetKeys allowlist. *** // +test(`${variant}: charsetDetectStream should filter chardet results to charsetKeys allowlist`, async (_t) => { + // windows-1255 Hebrew bytes with c1 bytes. chardet returns "windows-1255" @ + // confidence 71 as the top match. "windows-1255" is NOT in charsetKeys, so + // the real code discards it; GB18030 wins at 10 from the in-allowlist matches. + // With if(true) mutant, "windows-1255" leaks through and wins at 71. + const bytes = Buffer.from([ + 128, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 249, 236, 229, 237, + 32, 242, 229, 236, 237, 128, 131, 132, 133, 134, 135, 136, 137, 138, 139, + 140, 249, 236, 229, 237, 32, 242, 229, 236, 237, + ]); + const streams = [createReadableStream([bytes]), charsetDetectStream()]; + await pipeline(streams); + const { value } = streams[1].result(); + // Real code: windows-1255 discarded → GB18030 wins at confidence 10. + // Mutant (if true): windows-1255 leaks → wins at confidence 71. + strictEqual( + value.charset, + "GB18030", + `expected GB18030 (in-allowlist winner) but got ${value.charset}@${value.confidence}`, + ); +}); + +// *** remaining-arithmetic: "remaining = MAX - sampleLength" bounds how many +// bytes of each subsequent chunk are stored. Mutating to MAX + sampleLength +// makes remaining huge so the second chunk is never truncated, leaking +// post-cap bytes into the sample and shifting detection from UTF-8 to KOI8-R. +// Only observable with TWO chunks (when sampleLength === 0 both expressions +// give MAX, so the first chunk is handled identically). *** // +test(`${variant}: charsetDetectStream should correctly cap the sample across two chunks`, async (_t) => { + const MAX = 64 * 1024; + const koi8rPattern = Buffer.from([ + 0xf0, 0xd2, 0xc9, 0xd7, 0xc5, 0xd4, 0x2c, 0x20, 0xcb, 0xc1, 0xcb, 0x20, + 0xc4, 0xc5, 0xcc, 0xc1, 0x3f, 0x20, 0xfa, 0xd4, 0xcf, 0x20, 0xd4, 0xc5, + 0xd3, 0xd4, 0xcf, 0xd7, 0xd9, 0xca, 0x20, 0xd4, 0xc5, 0xcb, 0xd3, 0xd4, + 0x20, 0xce, 0xc1, 0x20, 0xd2, 0xd5, 0xd3, 0xd3, 0xcb, 0xcf, 0xcd, 0x20, + 0xd1, 0xda, 0xd9, 0xcb, 0xc5, 0x2e, + ]); + const koi8r = Buffer.alloc(MAX / 2); + for (let i = 0; i < koi8r.length; i++) + koi8r[i] = koi8rPattern[i % koi8rPattern.length]; + + // Chunk 1 fills MAX/2 bytes (sampleLength = MAX/2 after it). + // Chunk 2 has MAX/2 bytes ASCII followed by MAX/2 bytes KOI8-R. + // Real: remaining = MAX - MAX/2 = MAX/2, so only first MAX/2 of chunk2 kept. + // Mutant: remaining = MAX + MAX/2 (huge), full chunk2 kept, KOI8-R leaks in. + const chunk1 = Buffer.alloc(MAX / 2, 0x41); + const chunk2 = Buffer.concat([Buffer.alloc(MAX / 2, 0x41), koi8r]); + const streams = [ + createReadableStream([chunk1, chunk2]), + charsetDetectStream(), + ]; + await pipeline(streams); + const { value } = streams[1].result(); + strictEqual( + value.charset, + "UTF-8", + `two-chunk cap: expected UTF-8 but got ${value.charset}@${value.confidence}`, + ); + strictEqual(value.confidence, 100); +}); diff --git a/packages/charset/package.json b/packages/charset/package.json index eb86556..d3c2b48 100644 --- a/packages/charset/package.json +++ b/packages/charset/package.json @@ -87,6 +87,7 @@ "scripts": { "test": "npm run test:unit", "test:unit": "node --test", + "test:mutation": "cd ../.. && MUTATE_PACKAGE=\"$(basename \"$OLDPWD\")\" stryker run", "test:benchmark": "node __benchmarks__/index.js" }, "license": "MIT", diff --git a/packages/compress/README.md b/packages/compress/README.md index 69d3f05..09433ff 100644 --- a/packages/compress/README.md +++ b/packages/compress/README.md @@ -1,6 +1,6 @@Compression streams for gzip, brotli, zstd, and deflate.
@@ -18,10 +18,10 @@
-
+
-
+
You can read the documentation at: https://datastream.js.org
diff --git a/packages/compress/brotli.node.js b/packages/compress/brotli.node.js index 1f75985..9a3b3fa 100644 --- a/packages/compress/brotli.node.js +++ b/packages/compress/brotli.node.js @@ -6,43 +6,61 @@ import { createBrotliDecompress, } from "node:zlib"; +// Default decompression output ceiling (256MiB) so that untrusted compressed +// input is bounded by default (zip-bomb protection). Pass `maxOutputSize: null` +// to opt out of the limit entirely. +const DEFAULT_DECOMPRESS_MAX_OUTPUT_SIZE = 256 * 1024 * 1024; + +const guardOutput = (stream, maxOutputSize, label) => { + let outputSize = 0; + const originalPush = stream.push.bind(stream); + stream.push = (chunk, encoding) => { + if (chunk !== null) { + outputSize += chunk.byteLength ?? Buffer.byteLength(chunk); + if (outputSize > maxOutputSize) { + stream.push = originalPush; + stream.destroy( + new Error( + `${label} output exceeds maxOutputSize (${maxOutputSize} bytes)`, + ), + ); + return false; + } + } + return originalPush(chunk, encoding); + }; + const restore = () => { + stream.push = originalPush; + }; + stream.on("close", restore); + stream.on("error", restore); +}; + // quality: 0 - 11 -export const brotliCompressStream = ({ quality } = {}, streamOptions = {}) => { - return createBrotliCompress({ +export const brotliCompressStream = (options = {}, streamOptions = {}) => { + const { quality, maxOutputSize } = options; + const stream = createBrotliCompress({ ...streamOptions, params: { [constants.BROTLI_PARAM_QUALITY]: quality ?? constants.BROTLI_DEFAULT_QUALITY, }, }); + if (maxOutputSize !== null && maxOutputSize !== undefined) { + guardOutput(stream, maxOutputSize, "Compression"); + } + return stream; }; export const brotliDecompressStream = (options = {}, streamOptions = {}) => { - const { maxOutputSize, ...params } = options; - const zlibOptions = Object.keys(params).length - ? { ...streamOptions, params } - : streamOptions; + const { maxOutputSize, params } = options; + const zlibOptions = params ? { ...streamOptions, params } : streamOptions; const stream = createBrotliDecompress(zlibOptions); - if (maxOutputSize != null) { - let outputSize = 0; - const originalPush = stream.push.bind(stream); - stream.push = (chunk) => { - if (chunk !== null) { - outputSize += chunk.length; - if (outputSize > maxOutputSize) { - stream.push = originalPush; - stream.destroy( - new Error( - `Decompression output exceeds maxOutputSize (${maxOutputSize} bytes)`, - ), - ); - return false; - } - } - return originalPush(chunk); - }; - stream.on("close", () => { - stream.push = originalPush; - }); + const limit = + maxOutputSize === null + ? undefined + : (maxOutputSize ?? DEFAULT_DECOMPRESS_MAX_OUTPUT_SIZE); + if (limit !== undefined) { + guardOutput(stream, limit, "Decompression"); } return stream; }; diff --git a/packages/compress/brotli.web.js b/packages/compress/brotli.web.js index 16f17c5..54e917a 100644 --- a/packages/compress/brotli.web.js +++ b/packages/compress/brotli.web.js @@ -8,54 +8,98 @@ import { createTransformStream } from "@datastream/core"; import brotliPromise from "brotli-wasm"; // Import the default export -const { CompressStream, DecompressStream, BrotliStreamResult } = +const { CompressStream, DecompressStream, BrotliStreamResultCode } = await brotliPromise; // Import is async in browsers due to wasm requirements! +// Fixed-size output buffer; the streaming loop drains NeedsMoreOutput so any +// chunk/output size is handled correctly. +const OUTPUT_SIZE = 16_384; // 16KB + +// Default decompression output ceiling (256MiB) so that untrusted compressed +// input is bounded by default (zip-bomb protection). Pass `maxOutputSize: null` +// to opt out of the limit entirely. +const DEFAULT_DECOMPRESS_MAX_OUTPUT_SIZE = 256 * 1024 * 1024; + +const textEncoder = new TextEncoder(); +const toBytes = (chunk) => + typeof chunk === "string" ? textEncoder.encode(chunk) : chunk; + // https://github.com/httptoolkit/brotli-wasm/issues/14 export const brotliCompressStream = (options = {}, streamOptions = {}) => { - const { quality } = options; + const { quality, maxOutputSize } = options; const engine = new CompressStream(quality ?? 11); + let outputSize = 0; + const guard = (buf, enqueue) => { + if (maxOutputSize != null) { + outputSize += buf.byteLength; + if (outputSize > maxOutputSize) { + throw new Error( + `Compression output exceeds maxOutputSize (${maxOutputSize} bytes)`, + ); + } + } + enqueue(buf); + }; const transform = (chunk, enqueue) => { - enqueue(engine.compress(chunk)); + const input = toBytes(chunk); + let inputOffset = 0; + let code; + do { + const result = engine.compress(input.slice(inputOffset), OUTPUT_SIZE); + guard(result.buf, enqueue); + inputOffset += result.input_offset; + code = result.code; + } while (code === BrotliStreamResultCode.NeedsMoreOutput); }; const flush = (enqueue) => { - if (engine.result() === BrotliStreamResult.NeedsMoreInput) { - enqueue(engine.compress(undefined, 100)); - } + let code; + do { + const result = engine.compress(undefined, OUTPUT_SIZE); + guard(result.buf, enqueue); + code = result.code; + } while (code === BrotliStreamResultCode.NeedsMoreOutput); }; return createTransformStream(transform, flush, streamOptions); }; export const brotliDecompressStream = (options = {}, streamOptions = {}) => { const { maxOutputSize } = options; + const limit = + maxOutputSize === null + ? undefined + : (maxOutputSize ?? DEFAULT_DECOMPRESS_MAX_OUTPUT_SIZE); const engine = new DecompressStream(); let outputSize = 0; const transform = (chunk, enqueue) => { - const result = engine.decompress(chunk); - if (maxOutputSize != null) { - outputSize += result.byteLength; - if (outputSize > maxOutputSize) { - throw new Error( - `Decompression output exceeds maxOutputSize (${maxOutputSize} bytes)`, - ); - } - } - enqueue(result); - }; - const flush = (enqueue) => { - if (engine.result() === BrotliStreamResult.NeedsMoreInput) { - const result = engine.decompress(undefined, 100); - if (maxOutputSize != null) { - outputSize += result.byteLength; - if (outputSize > maxOutputSize) { + const input = toBytes(chunk); + let inputOffset = 0; + let code; + do { + const result = engine.decompress(input.slice(inputOffset), OUTPUT_SIZE); + if (limit !== undefined) { + outputSize += result.buf.byteLength; + if (outputSize > limit) { throw new Error( - `Decompression output exceeds maxOutputSize (${maxOutputSize} bytes)`, + `Decompression output exceeds maxOutputSize (${limit} bytes)`, ); } } - enqueue(result); + enqueue(result.buf); + inputOffset += result.input_offset; + code = result.code; + } while (code === BrotliStreamResultCode.NeedsMoreOutput); + // A complete brotli stream (ResultSuccess) followed by leftover bytes in + // the same chunk means trailing/garbage data; strict decoders reject it + // rather than silently dropping it. + if ( + code === BrotliStreamResultCode.ResultSuccess && + inputOffset < input.byteLength + ) { + throw new Error( + "Decompression has trailing bytes after end of brotli stream", + ); } }; - return createTransformStream(transform, flush, streamOptions); + return createTransformStream(transform, undefined, streamOptions); }; export default { diff --git a/packages/compress/deflate.node.js b/packages/compress/deflate.node.js index ff80036..9112b4f 100644 --- a/packages/compress/deflate.node.js +++ b/packages/compress/deflate.node.js @@ -2,58 +2,54 @@ // SPDX-License-Identifier: MIT import { createDeflate, createInflate } from "node:zlib"; +// Default decompression output ceiling (256MiB) so that untrusted compressed +// input is bounded by default (zip-bomb protection). Pass `maxOutputSize: null` +// to opt out of the limit entirely. +const DEFAULT_DECOMPRESS_MAX_OUTPUT_SIZE = 256 * 1024 * 1024; + +const guardOutput = (stream, maxOutputSize, label) => { + let outputSize = 0; + const originalPush = stream.push.bind(stream); + stream.push = (chunk, encoding) => { + if (chunk !== null) { + outputSize += chunk.byteLength ?? Buffer.byteLength(chunk); + if (outputSize > maxOutputSize) { + stream.push = originalPush; + stream.destroy( + new Error( + `${label} output exceeds maxOutputSize (${maxOutputSize} bytes)`, + ), + ); + return false; + } + } + return originalPush(chunk, encoding); + }; + const restore = () => { + stream.push = originalPush; + }; + stream.on("close", restore); + stream.on("error", restore); +}; + // quality -1 - 9 -export const deflateCompressStream = (options = {}, _streamOptions = {}) => { - const { quality, maxOutputSize, ...rest } = options; - const stream = createDeflate({ ...rest, level: rest.level ?? quality }); +export const deflateCompressStream = (options = {}, streamOptions = {}) => { + const { quality, maxOutputSize, level } = options; + const stream = createDeflate({ ...streamOptions, level: level ?? quality }); if (maxOutputSize !== null && maxOutputSize !== undefined) { - let outputSize = 0; - const originalPush = stream.push.bind(stream); - stream.push = (chunk) => { - if (chunk !== null) { - outputSize += chunk.length; - if (outputSize > maxOutputSize) { - stream.push = originalPush; - stream.destroy( - new Error( - `Compression output exceeds maxOutputSize (${maxOutputSize} bytes)`, - ), - ); - return false; - } - } - return originalPush(chunk); - }; - stream.on("close", () => { - stream.push = originalPush; - }); + guardOutput(stream, maxOutputSize, "Compression"); } return stream; }; export const deflateDecompressStream = (options = {}, streamOptions = {}) => { const { maxOutputSize } = options; const stream = createInflate(streamOptions); - if (maxOutputSize != null) { - let outputSize = 0; - const originalPush = stream.push.bind(stream); - stream.push = (chunk) => { - if (chunk !== null) { - outputSize += chunk.length; - if (outputSize > maxOutputSize) { - stream.push = originalPush; - stream.destroy( - new Error( - `Decompression output exceeds maxOutputSize (${maxOutputSize} bytes)`, - ), - ); - return false; - } - } - return originalPush(chunk); - }; - stream.on("close", () => { - stream.push = originalPush; - }); + const limit = + maxOutputSize === null + ? undefined + : (maxOutputSize ?? DEFAULT_DECOMPRESS_MAX_OUTPUT_SIZE); + if (limit !== undefined) { + guardOutput(stream, limit, "Decompression"); } return stream; }; diff --git a/packages/compress/deflate.web.js b/packages/compress/deflate.web.js index fdc9a80..c5d0eff 100644 --- a/packages/compress/deflate.web.js +++ b/packages/compress/deflate.web.js @@ -5,60 +5,119 @@ // - https://caniuse.com/?search=CompressionStream // - not supported on firefox - https://bugzilla.mozilla.org/show_bug.cgi?id=1586639 // - not supported in safari +import { makeOptions } from "@datastream/core"; -export const deflateCompressStream = (options = {}, _streamOptions = {}) => { - const { maxOutputSize } = options; - const compressor = new CompressionStream("deflate"); - if (maxOutputSize != null) { - let outputSize = 0; - const transformer = { +// Default decompression output ceiling (256MiB) so that untrusted compressed +// input is bounded by default (zip-bomb protection). Pass `maxOutputSize: null` +// to opt out of the limit entirely. +const DEFAULT_DECOMPRESS_MAX_OUTPUT_SIZE = 256 * 1024 * 1024; + +const textEncoder = new TextEncoder(); +// The WHATWG CompressionStream/DecompressionStream require each chunk to be a +// BufferSource; strings throw a TypeError in spec-compliant browsers. Node's +// implementation is lenient, so convert here to match Node + web brotli. +const toBytes = (chunk) => + typeof chunk === "string" ? textEncoder.encode(chunk) : chunk; + +// Input stage: convert string chunks to bytes (BufferSource) and honor an +// AbortSignal. The native CompressionStream/DecompressionStream accept neither a +// signal nor string chunks, so this stage provides both (parity with the Node +// build and web brotli). highWaterMark/chunkSize are threaded via makeOptions. +const inputStage = (streamOptions) => { + const { signal } = streamOptions ?? {}; + const { writableStrategy, readableStrategy } = makeOptions(streamOptions); + let onAbort; + const abortError = () => + signal.reason ?? new DOMException("Aborted", "AbortError"); + return new TransformStream( + { + start(controller) { + if (signal) { + if (signal.aborted) { + controller.error(abortError()); + return; + } + onAbort = () => controller.error(abortError()); + signal.addEventListener("abort", onAbort, { once: true }); + } + }, transform(chunk, controller) { - outputSize += chunk.byteLength; - if (outputSize > maxOutputSize) { - controller.error( - new Error( - `Compression output exceeds maxOutputSize (${maxOutputSize} bytes)`, - ), - ); - return; + controller.enqueue(toBytes(chunk)); + }, + flush() { + if (onAbort) { + signal.removeEventListener("abort", onAbort); + onAbort = undefined; } - controller.enqueue(chunk); }, - }; - const limiter = new TransformStream(transformer); - return { - readable: compressor.readable.pipeThrough(limiter), - writable: compressor.writable, - }; - } - return compressor; + }, + writableStrategy, + readableStrategy, + ); }; -export const deflateDecompressStream = (options = {}, _streamOptions = {}) => { - const { maxOutputSize } = options; - const decompressor = new DecompressionStream("deflate"); - if (maxOutputSize != null) { - let outputSize = 0; - const transformer = { - transform(chunk, controller) { + +// Output stage: enforce maxOutputSize and keep honoring the AbortSignal for the +// whole stream lifetime (a mid-flight abort errors this terminal readable). +const outputStage = (maxOutputSize, label, streamOptions) => { + const { signal } = streamOptions ?? {}; + let onAbort; + let outputSize = 0; + const abortError = () => + signal.reason ?? new DOMException("Aborted", "AbortError"); + return new TransformStream({ + start(controller) { + if (signal) { + if (signal.aborted) { + controller.error(abortError()); + return; + } + onAbort = () => controller.error(abortError()); + signal.addEventListener("abort", onAbort, { once: true }); + } + }, + transform(chunk, controller) { + if (maxOutputSize !== null && maxOutputSize !== undefined) { outputSize += chunk.byteLength; if (outputSize > maxOutputSize) { controller.error( new Error( - `Decompression output exceeds maxOutputSize (${maxOutputSize} bytes)`, + `${label} output exceeds maxOutputSize (${maxOutputSize} bytes)`, ), ); return; } - controller.enqueue(chunk); - }, - }; - const limiter = new TransformStream(transformer); - return { - readable: decompressor.readable.pipeThrough(limiter), - writable: decompressor.writable, - }; - } - return decompressor; + } + controller.enqueue(chunk); + }, + flush() { + if (onAbort) { + signal.removeEventListener("abort", onAbort); + onAbort = undefined; + } + }, + }); +}; + +const wrap = (compressor, maxOutputSize, streamOptions, label) => { + const input = inputStage(streamOptions); + const output = outputStage(maxOutputSize, label, streamOptions); + const readable = input.readable.pipeThrough(compressor).pipeThrough(output); + return { readable, writable: input.writable }; +}; + +export const deflateCompressStream = (options = {}, streamOptions = {}) => { + const { maxOutputSize } = options; + const compressor = new CompressionStream("deflate"); + return wrap(compressor, maxOutputSize, streamOptions, "Compression"); +}; +export const deflateDecompressStream = (options = {}, streamOptions = {}) => { + const { maxOutputSize } = options; + const decompressor = new DecompressionStream("deflate"); + const limit = + maxOutputSize === null + ? undefined + : (maxOutputSize ?? DEFAULT_DECOMPRESS_MAX_OUTPUT_SIZE); + return wrap(decompressor, limit, streamOptions, "Decompression"); }; export default { diff --git a/packages/compress/gzip.node.js b/packages/compress/gzip.node.js index c0a9255..68a8892 100644 --- a/packages/compress/gzip.node.js +++ b/packages/compress/gzip.node.js @@ -2,58 +2,54 @@ // SPDX-License-Identifier: MIT import { createGunzip, createGzip } from "node:zlib"; +// Default decompression output ceiling (256MiB) so that untrusted compressed +// input is bounded by default (zip-bomb protection). Pass `maxOutputSize: null` +// to opt out of the limit entirely. +const DEFAULT_DECOMPRESS_MAX_OUTPUT_SIZE = 256 * 1024 * 1024; + +const guardOutput = (stream, maxOutputSize, label) => { + let outputSize = 0; + const originalPush = stream.push.bind(stream); + stream.push = (chunk, encoding) => { + if (chunk !== null) { + outputSize += chunk.byteLength ?? Buffer.byteLength(chunk); + if (outputSize > maxOutputSize) { + stream.push = originalPush; + stream.destroy( + new Error( + `${label} output exceeds maxOutputSize (${maxOutputSize} bytes)`, + ), + ); + return false; + } + } + return originalPush(chunk, encoding); + }; + const restore = () => { + stream.push = originalPush; + }; + stream.on("close", restore); + stream.on("error", restore); +}; + // quality -1 - 9 export const gzipCompressStream = (options = {}, streamOptions = {}) => { const { quality, maxOutputSize } = options; const stream = createGzip({ ...streamOptions, level: quality }); if (maxOutputSize !== null && maxOutputSize !== undefined) { - let outputSize = 0; - const originalPush = stream.push.bind(stream); - stream.push = (chunk) => { - if (chunk !== null) { - outputSize += chunk.length; - if (outputSize > maxOutputSize) { - stream.push = originalPush; - stream.destroy( - new Error( - `Compression output exceeds maxOutputSize (${maxOutputSize} bytes)`, - ), - ); - return false; - } - } - return originalPush(chunk); - }; - stream.on("close", () => { - stream.push = originalPush; - }); + guardOutput(stream, maxOutputSize, "Compression"); } return stream; }; export const gzipDecompressStream = (options = {}, streamOptions = {}) => { const { maxOutputSize } = options; const stream = createGunzip(streamOptions); - if (maxOutputSize != null) { - let outputSize = 0; - const originalPush = stream.push.bind(stream); - stream.push = (chunk) => { - if (chunk !== null) { - outputSize += chunk.length; - if (outputSize > maxOutputSize) { - stream.push = originalPush; - stream.destroy( - new Error( - `Decompression output exceeds maxOutputSize (${maxOutputSize} bytes)`, - ), - ); - return false; - } - } - return originalPush(chunk); - }; - stream.on("close", () => { - stream.push = originalPush; - }); + const limit = + maxOutputSize === null + ? undefined + : (maxOutputSize ?? DEFAULT_DECOMPRESS_MAX_OUTPUT_SIZE); + if (limit !== undefined) { + guardOutput(stream, limit, "Decompression"); } return stream; }; diff --git a/packages/compress/gzip.web.js b/packages/compress/gzip.web.js index 7776ee1..465688a 100644 --- a/packages/compress/gzip.web.js +++ b/packages/compress/gzip.web.js @@ -5,60 +5,119 @@ // - https://caniuse.com/?search=CompressionStream // - not supported on firefox - https://bugzilla.mozilla.org/show_bug.cgi?id=1586639 // - not supported in safari +import { makeOptions } from "@datastream/core"; -export const gzipCompressStream = (options = {}, _streamOptions = {}) => { - const { maxOutputSize } = options; - const compressor = new CompressionStream("gzip"); - if (maxOutputSize != null) { - let outputSize = 0; - const transformer = { +// Default decompression output ceiling (256MiB) so that untrusted compressed +// input is bounded by default (zip-bomb protection). Pass `maxOutputSize: null` +// to opt out of the limit entirely. +const DEFAULT_DECOMPRESS_MAX_OUTPUT_SIZE = 256 * 1024 * 1024; + +const textEncoder = new TextEncoder(); +// The WHATWG CompressionStream/DecompressionStream require each chunk to be a +// BufferSource; strings throw a TypeError in spec-compliant browsers. Node's +// implementation is lenient, so convert here to match Node + web brotli. +const toBytes = (chunk) => + typeof chunk === "string" ? textEncoder.encode(chunk) : chunk; + +// Input stage: convert string chunks to bytes (BufferSource) and honor an +// AbortSignal. The native CompressionStream/DecompressionStream accept neither a +// signal nor string chunks, so this stage provides both (parity with the Node +// build and web brotli). highWaterMark/chunkSize are threaded via makeOptions. +const inputStage = (streamOptions) => { + const { signal } = streamOptions ?? {}; + const { writableStrategy, readableStrategy } = makeOptions(streamOptions); + let onAbort; + const abortError = () => + signal.reason ?? new DOMException("Aborted", "AbortError"); + return new TransformStream( + { + start(controller) { + if (signal) { + if (signal.aborted) { + controller.error(abortError()); + return; + } + onAbort = () => controller.error(abortError()); + signal.addEventListener("abort", onAbort, { once: true }); + } + }, transform(chunk, controller) { - outputSize += chunk.byteLength; - if (outputSize > maxOutputSize) { - controller.error( - new Error( - `Compression output exceeds maxOutputSize (${maxOutputSize} bytes)`, - ), - ); - return; + controller.enqueue(toBytes(chunk)); + }, + flush() { + if (onAbort) { + signal.removeEventListener("abort", onAbort); + onAbort = undefined; } - controller.enqueue(chunk); }, - }; - const limiter = new TransformStream(transformer); - return { - readable: compressor.readable.pipeThrough(limiter), - writable: compressor.writable, - }; - } - return compressor; + }, + writableStrategy, + readableStrategy, + ); }; -export const gzipDecompressStream = (options = {}, _streamOptions = {}) => { - const { maxOutputSize } = options; - const decompressor = new DecompressionStream("gzip"); - if (maxOutputSize != null) { - let outputSize = 0; - const transformer = { - transform(chunk, controller) { + +// Output stage: enforce maxOutputSize and keep honoring the AbortSignal for the +// whole stream lifetime (a mid-flight abort errors this terminal readable). +const outputStage = (maxOutputSize, label, streamOptions) => { + const { signal } = streamOptions ?? {}; + let onAbort; + let outputSize = 0; + const abortError = () => + signal.reason ?? new DOMException("Aborted", "AbortError"); + return new TransformStream({ + start(controller) { + if (signal) { + if (signal.aborted) { + controller.error(abortError()); + return; + } + onAbort = () => controller.error(abortError()); + signal.addEventListener("abort", onAbort, { once: true }); + } + }, + transform(chunk, controller) { + if (maxOutputSize !== null && maxOutputSize !== undefined) { outputSize += chunk.byteLength; if (outputSize > maxOutputSize) { controller.error( new Error( - `Decompression output exceeds maxOutputSize (${maxOutputSize} bytes)`, + `${label} output exceeds maxOutputSize (${maxOutputSize} bytes)`, ), ); return; } - controller.enqueue(chunk); - }, - }; - const limiter = new TransformStream(transformer); - return { - readable: decompressor.readable.pipeThrough(limiter), - writable: decompressor.writable, - }; - } - return decompressor; + } + controller.enqueue(chunk); + }, + flush() { + if (onAbort) { + signal.removeEventListener("abort", onAbort); + onAbort = undefined; + } + }, + }); +}; + +const wrap = (compressor, maxOutputSize, streamOptions, label) => { + const input = inputStage(streamOptions); + const output = outputStage(maxOutputSize, label, streamOptions); + const readable = input.readable.pipeThrough(compressor).pipeThrough(output); + return { readable, writable: input.writable }; +}; + +export const gzipCompressStream = (options = {}, streamOptions = {}) => { + const { maxOutputSize } = options; + const compressor = new CompressionStream("gzip"); + return wrap(compressor, maxOutputSize, streamOptions, "Compression"); +}; +export const gzipDecompressStream = (options = {}, streamOptions = {}) => { + const { maxOutputSize } = options; + const decompressor = new DecompressionStream("gzip"); + const limit = + maxOutputSize === null + ? undefined + : (maxOutputSize ?? DEFAULT_DECOMPRESS_MAX_OUTPUT_SIZE); + return wrap(decompressor, limit, streamOptions, "Decompression"); }; export default { diff --git a/packages/compress/index.d.ts b/packages/compress/index.d.ts index ebe4c82..d0aa8d2 100644 --- a/packages/compress/index.d.ts +++ b/packages/compress/index.d.ts @@ -13,10 +13,6 @@ export { gzipCompressStream, gzipDecompressStream, } from "@datastream/compress/gzip"; -export { - protobufDeserializeStream, - protobufSerializeStream, -} from "@datastream/compress/protobuf"; export { zstdCompressStream, zstdDecompressStream, diff --git a/packages/compress/index.js b/packages/compress/index.js index 9712e8b..c7b767e 100644 --- a/packages/compress/index.js +++ b/packages/compress/index.js @@ -3,5 +3,4 @@ export * from "@datastream/compress/brotli"; export * from "@datastream/compress/deflate"; export * from "@datastream/compress/gzip"; -export * from "@datastream/compress/protobuf"; export * from "@datastream/compress/zstd"; diff --git a/packages/compress/index.test.js b/packages/compress/index.test.js index 94fa665..d5f5d2f 100644 --- a/packages/compress/index.test.js +++ b/packages/compress/index.test.js @@ -1,7 +1,10 @@ import { ok, strictEqual } from "node:assert"; +import { register } from "node:module"; import test from "node:test"; +import { pathToFileURL } from "node:url"; import { brotliCompressSync, + brotliDecompressSync, deflateSync, gzipSync, zstdCompressSync, @@ -23,7 +26,6 @@ import { createReadableStream, pipejoin, pipeline, - streamToArray, streamToBuffer, streamToString, } from "@datastream/core"; @@ -158,6 +160,18 @@ if (variant === "node") { strictEqual(output, compressibleBody); }); + // A default decompression ceiling now applies; `maxOutputSize: null` opts + // out of any limit (unbounded), so normal payloads still round-trip. + test(`${variant}: gzipDecompressStream maxOutputSize:null disables the limit`, async (_t) => { + const input = gzipSync(compressibleBody); + const streams = [ + createReadableStream(input), + gzipDecompressStream({ maxOutputSize: null }), + ]; + const output = await streamToString(pipejoin(streams)); + strictEqual(output, compressibleBody); + }); + // *** maxOutputSize within limit (covers normal-path push) *** // test(`${variant}: gzipDecompressStream should pass through within maxOutputSize`, async (_t) => { const input = gzipSync(compressibleBody); @@ -189,6 +203,20 @@ if (variant === "node") { strictEqual(output, compressibleBody); }); + // Arbitrary keys on the first (options) argument must NOT be promoted into + // zlib Brotli `params` (the old behavior threw "chunkSize is not a valid + // Brotli parameter"). Only an explicit `params` field is forwarded; real + // stream options go on the second argument. + test(`${variant}: brotliDecompressStream should not promote first-arg keys to Brotli params`, async (_t) => { + const input = brotliCompressSync(compressibleBody); + const streams = [ + createReadableStream(input), + brotliDecompressStream({ chunkSize: 1024 }), + ]; + const output = await streamToString(pipejoin(streams)); + strictEqual(output, compressibleBody); + }); + // *** zstd decompress maxOutputSize *** // test(`${variant}: zstdDecompressStream should enforce maxOutputSize`, async (_t) => { const input = zstdCompressSync(compressibleBody); @@ -262,48 +290,47 @@ if (variant === "node") { const output = await streamToString(pipejoin(streams)); strictEqual(output, deflateSync(compressibleBody).toString()); }); -} -// *** protobuf *** // -let protobuf; -try { - protobuf = (await import("protobufjs")).default; -} catch { - // protobufjs not installed -} + // deflateCompressStream reads quality/level/maxOutputSize from the first + // argument and forwards real stream options from the second argument + // (matching gzipCompressStream), rather than spreading the first arg. + test(`${variant}: deflateCompressStream should honor quality and second-arg stream options`, async (_t) => { + const streams = [ + createReadableStream(compressibleBody), + deflateCompressStream({ quality: 9 }, { chunkSize: 1024 }), + deflateDecompressStream(), + ]; + const output = await streamToString(pipejoin(streams)); + strictEqual(output, compressibleBody); + }); -if (protobuf) { - const { protobufSerializeStream, protobufDeserializeStream } = await import( - "@datastream/compress/protobuf" - ); + test(`${variant}: brotliCompressStream should enforce maxOutputSize`, async (_t) => { + const streams = [ + createReadableStream(compressibleBody), + brotliCompressStream({ maxOutputSize: 5 }), + ]; + try { + await pipeline(streams); + throw new Error("Should have thrown"); + } catch (e) { + ok(e.message.includes("maxOutputSize")); + } + }); + + test(`${variant}: brotliCompressStream should pass through within maxOutputSize`, async (_t) => { + const streams = [ + createReadableStream(compressibleBody), + brotliCompressStream({ maxOutputSize: 1024 * 1024 }), + ]; + const output = await streamToBuffer(pipejoin(streams)); + strictEqual(brotliDecompressSync(output).toString(), compressibleBody); + }); - const TestType = new protobuf.Type("TestMessage") - .add(new protobuf.Field("name", 1, "string")) - .add(new protobuf.Field("value", 2, "int32")); - new protobuf.Root().define("test").add(TestType); - - test(`${variant}: protobuf roundtrip serialize/deserialize`, async (_t) => { - const input = [ - { name: "a", value: 1 }, - { name: "b", value: 2 }, - ]; - const serialize = protobufSerializeStream({ Type: TestType }); - const deserialize = protobufDeserializeStream({ Type: TestType }); - const streams = [createReadableStream(input), serialize, deserialize]; - const output = await streamToArray(pipejoin(streams)); - strictEqual(output.length, 2); - strictEqual(output[0].name, "a"); - strictEqual(output[1].name, "b"); - }); - - test(`${variant}: protobufDeserializeStream should enforce maxOutputSize`, async (_t) => { - const input = [{ name: "long-name-here", value: 12345 }]; - const serialize = protobufSerializeStream({ Type: TestType }); - const deserialize = protobufDeserializeStream({ - Type: TestType, - maxOutputSize: 5, - }); - const streams = [createReadableStream(input), serialize, deserialize]; + test(`${variant}: zstdCompressStream should enforce maxOutputSize`, async (_t) => { + const streams = [ + createReadableStream(compressibleBody), + zstdCompressStream({ maxOutputSize: 5 }), + ]; try { await pipeline(streams); throw new Error("Should have thrown"); @@ -312,16 +339,586 @@ if (protobuf) { } }); - test(`${variant}: protobufDeserializeStream should pass through within maxOutputSize`, async (_t) => { - const input = [{ name: "a", value: 1 }]; - const serialize = protobufSerializeStream({ Type: TestType }); - const deserialize = protobufDeserializeStream({ - Type: TestType, - maxOutputSize: 1024, - }); - const streams = [createReadableStream(input), serialize, deserialize]; - const output = await streamToArray(pipejoin(streams)); - strictEqual(output[0].name, "a"); + test(`${variant}: zstdCompressStream should pass through within maxOutputSize`, async (_t) => { + const streams = [ + createReadableStream(compressibleBody), + zstdCompressStream({ maxOutputSize: 1024 * 1024 }), + ]; + const output = await streamToBuffer(pipejoin(streams)); + strictEqual(zstdDecompressSync(output).toString(), compressibleBody); + }); +} + +// *** quality / level parameter routing *** // +if (variant === "node") { + // brotliCompressStream: quality=0 vs quality=11 produce different sizes; + // ensures params object is forwarded (ObjectLiteral survivor). + test(`${variant}: brotliCompressStream quality:0 differs from quality:11`, async (_t) => { + const out0 = await streamToBuffer( + pipejoin([ + createReadableStream(compressibleBody), + brotliCompressStream({ quality: 0 }), + ]), + ); + const out11 = await streamToBuffer( + pipejoin([ + createReadableStream(compressibleBody), + brotliCompressStream({ quality: 11 }), + ]), + ); + ok( + out0.byteLength !== out11.byteLength, + "different quality => different size", + ); + strictEqual(brotliDecompressSync(out0).toString(), compressibleBody); + strictEqual(brotliDecompressSync(out11).toString(), compressibleBody); + }); + + // default quality matches BROTLI_DEFAULT_QUALITY constant + // (covers quality ?? BROTLI_DEFAULT_QUALITY LogicalOperator survivor). + test(`${variant}: brotliCompressStream default quality equals explicit BROTLI_DEFAULT_QUALITY`, async (_t) => { + const { constants: zlibConst } = await import("node:zlib"); + const outDef = await streamToBuffer( + pipejoin([ + createReadableStream(compressibleBody), + brotliCompressStream(), + ]), + ); + const outExp = await streamToBuffer( + pipejoin([ + createReadableStream(compressibleBody), + brotliCompressStream({ quality: zlibConst.BROTLI_DEFAULT_QUALITY }), + ]), + ); + strictEqual(outDef.toString("hex"), outExp.toString("hex")); + }); + + // gzipCompressStream: quality maps to zlib level; levels 1 and 9 differ. + test(`${variant}: gzipCompressStream quality:1 and quality:9 both round-trip`, async (_t) => { + const out1 = await streamToBuffer( + pipejoin([ + createReadableStream(compressibleBody), + gzipCompressStream({ quality: 1 }), + ]), + ); + const out9 = await streamToBuffer( + pipejoin([ + createReadableStream(compressibleBody), + gzipCompressStream({ quality: 9 }), + ]), + ); + ok(out1.byteLength !== out9.byteLength, "quality 1 vs 9 => different size"); + strictEqual( + await streamToString( + pipejoin([createReadableStream(out1), gzipDecompressStream()]), + ), + compressibleBody, + ); + strictEqual( + await streamToString( + pipejoin([createReadableStream(out9), gzipDecompressStream()]), + ), + compressibleBody, + ); + }); + + // deflateCompressStream: `level` takes precedence over `quality` + // (covers `level ?? quality` LogicalOperator survivor). + test(`${variant}: deflateCompressStream level overrides quality`, async (_t) => { + const compressed = await streamToBuffer( + pipejoin([ + createReadableStream(compressibleBody), + deflateCompressStream({ level: 9, quality: 1 }), + ]), + ); + const output = await streamToString( + pipejoin([createReadableStream(compressed), deflateDecompressStream()]), + ); + strictEqual(output, compressibleBody); + }); + + // deflateCompressStream with quality:9 must match deflateSync at level:9. + // `level && quality` mutation: when level is undefined, `undefined && quality` + // = `undefined` → quality ignored → output would match default level, not 9. + // Also catches `createDeflate({})` mutation (drops level entirely). + test(`${variant}: deflateCompressStream quality:9 output matches deflateSync level:9`, async (_t) => { + const { deflateSync: defSync } = await import("node:zlib"); + const output = await streamToBuffer( + pipejoin([ + createReadableStream(compressibleBody), + deflateCompressStream({ quality: 9 }), + ]), + ); + strictEqual( + output.toString("hex"), + defSync(compressibleBody, { level: 9 }).toString("hex"), + ); + }); + + // deflateCompressStream with level:1 must match deflateSync at level:1. + test(`${variant}: deflateCompressStream level:1 output matches deflateSync level:1`, async (_t) => { + const { deflateSync: defSync } = await import("node:zlib"); + const output = await streamToBuffer( + pipejoin([ + createReadableStream(compressibleBody), + deflateCompressStream({ level: 1 }), + ]), + ); + strictEqual( + output.toString("hex"), + defSync(compressibleBody, { level: 1 }).toString("hex"), + ); + }); + + // zstdCompressStream: different quality levels both round-trip. + test(`${variant}: zstdCompressStream quality:1 and quality:19 both round-trip`, async (_t) => { + const out1 = await streamToBuffer( + pipejoin([ + createReadableStream(compressibleBody), + zstdCompressStream({ quality: 1 }), + ]), + ); + const out19 = await streamToBuffer( + pipejoin([ + createReadableStream(compressibleBody), + zstdCompressStream({ quality: 19 }), + ]), + ); + strictEqual(zstdDecompressSync(out1).toString(), compressibleBody); + strictEqual(zstdDecompressSync(out19).toString(), compressibleBody); + }); + + // zstdCompressStream with explicit params (covers `params ?? { ... }` ObjectLiteral survivor). + test(`${variant}: zstdCompressStream with explicit params round-trips`, async (_t) => { + const { constants: zlibConst } = await import("node:zlib"); + const out = await streamToBuffer( + pipejoin([ + createReadableStream(compressibleBody), + zstdCompressStream({ + params: { [zlibConst.ZSTD_c_compressionLevel]: 3 }, + }), + ]), + ); + strictEqual(zstdDecompressSync(out).toString(), compressibleBody); + }); + + // zstdDecompressStream with explicit params + // (covers `params ? {..., params} : streamOptions` ConditionalExpression survivor). + test(`${variant}: zstdDecompressStream with explicit params round-trips`, async (_t) => { + const { constants: zlibConst } = await import("node:zlib"); + const input = zstdCompressSync(compressibleBody); + const output = await streamToString( + pipejoin([ + createReadableStream(input), + zstdDecompressStream({ + params: { [zlibConst.ZSTD_d_windowLogMax]: 27 }, + }), + ]), + ); + strictEqual(output, compressibleBody); + }); + + // brotliDecompressStream with params option + // (covers `params ? {..., params} : streamOptions` ConditionalExpression survivor). + test(`${variant}: brotliDecompressStream with params option round-trips`, async (_t) => { + const { constants: zlibConst } = await import("node:zlib"); + const input = brotliCompressSync(compressibleBody); + // BROTLI_PARAM_MODE is a valid decompress-time param (mode 0 = generic) + const output = await streamToString( + pipejoin([ + createReadableStream(input), + brotliDecompressStream({ + params: { [zlibConst.BROTLI_PARAM_MODE]: 0 }, + }), + ]), + ); + strictEqual(output, compressibleBody); + }); +} + +// *** maxOutputSize exact boundary (> vs >=) *** // +// Payload whose decompressed size exactly equals maxOutputSize must PASS. +// `outputSize > maxOutputSize` allows equal; `>=` would reject it. +if (variant === "node") { + test(`${variant}: gzipDecompressStream exact-boundary maxOutputSize should NOT throw`, async (_t) => { + const input = gzipSync(compressibleBody); + const exactSize = Buffer.byteLength(compressibleBody); + const output = await streamToString( + pipejoin([ + createReadableStream(input), + gzipDecompressStream({ maxOutputSize: exactSize }), + ]), + ); + strictEqual(output, compressibleBody); + }); + + test(`${variant}: deflateDecompressStream exact-boundary maxOutputSize should NOT throw`, async (_t) => { + const input = deflateSync(compressibleBody); + const exactSize = Buffer.byteLength(compressibleBody); + const output = await streamToString( + pipejoin([ + createReadableStream(input), + deflateDecompressStream({ maxOutputSize: exactSize }), + ]), + ); + strictEqual(output, compressibleBody); + }); + + test(`${variant}: brotliDecompressStream exact-boundary maxOutputSize should NOT throw`, async (_t) => { + const input = brotliCompressSync(compressibleBody); + const exactSize = Buffer.byteLength(compressibleBody); + const output = await streamToString( + pipejoin([ + createReadableStream(input), + brotliDecompressStream({ maxOutputSize: exactSize }), + ]), + ); + strictEqual(output, compressibleBody); + }); + + test(`${variant}: zstdDecompressStream exact-boundary maxOutputSize should NOT throw`, async (_t) => { + const input = zstdCompressSync(compressibleBody); + const exactSize = Buffer.byteLength(compressibleBody); + const output = await streamToString( + pipejoin([ + createReadableStream(input), + zstdDecompressStream({ maxOutputSize: exactSize }), + ]), + ); + strictEqual(output, compressibleBody); + }); + + // One byte under the limit MUST throw. + test(`${variant}: gzipDecompressStream one-byte-under maxOutputSize should throw`, async (_t) => { + const input = gzipSync(compressibleBody); + const exactSize = Buffer.byteLength(compressibleBody); + try { + await pipeline([ + createReadableStream(input), + gzipDecompressStream({ maxOutputSize: exactSize - 1 }), + ]); + throw new Error("Should have thrown"); + } catch (e) { + ok(e.message.includes("maxOutputSize"), e.message); + } + }); +} + +// *** error message label strings (StringLiteral survivors) *** // +// Error message must contain "Compression"/"Decompression" (not ""). +if (variant === "node") { + test(`${variant}: gzipDecompressStream error message contains "Decompression"`, async (_t) => { + const input = gzipSync(compressibleBody); + try { + await pipeline([ + createReadableStream(input), + gzipDecompressStream({ maxOutputSize: 10 }), + ]); + throw new Error("Should have thrown"); + } catch (e) { + ok(e.message.includes("Decompression"), `msg: ${e.message}`); + } + }); + + test(`${variant}: gzipCompressStream error message contains "Compression"`, async (_t) => { + try { + await pipeline([ + createReadableStream(compressibleBody), + gzipCompressStream({ maxOutputSize: 5 }), + ]); + throw new Error("Should have thrown"); + } catch (e) { + ok(e.message.includes("Compression"), `msg: ${e.message}`); + } + }); + + test(`${variant}: deflateDecompressStream error message contains "Decompression"`, async (_t) => { + const input = deflateSync(compressibleBody); + try { + await pipeline([ + createReadableStream(input), + deflateDecompressStream({ maxOutputSize: 10 }), + ]); + throw new Error("Should have thrown"); + } catch (e) { + ok(e.message.includes("Decompression"), `msg: ${e.message}`); + } + }); + + test(`${variant}: deflateCompressStream error message contains "Compression"`, async (_t) => { + try { + await pipeline([ + createReadableStream(compressibleBody), + deflateCompressStream({ maxOutputSize: 5 }), + ]); + throw new Error("Should have thrown"); + } catch (e) { + ok(e.message.includes("Compression"), `msg: ${e.message}`); + } + }); + + test(`${variant}: brotliDecompressStream error message contains "Decompression"`, async (_t) => { + const input = brotliCompressSync(compressibleBody); + try { + await pipeline([ + createReadableStream(input), + brotliDecompressStream({ maxOutputSize: 10 }), + ]); + throw new Error("Should have thrown"); + } catch (e) { + ok(e.message.includes("Decompression"), `msg: ${e.message}`); + } + }); + + test(`${variant}: brotliCompressStream error message contains "Compression"`, async (_t) => { + try { + await pipeline([ + createReadableStream(compressibleBody), + brotliCompressStream({ maxOutputSize: 5 }), + ]); + throw new Error("Should have thrown"); + } catch (e) { + ok(e.message.includes("Compression"), `msg: ${e.message}`); + } + }); + + test(`${variant}: zstdDecompressStream error message contains "Decompression"`, async (_t) => { + const input = zstdCompressSync(compressibleBody); + try { + await pipeline([ + createReadableStream(input), + zstdDecompressStream({ maxOutputSize: 10 }), + ]); + throw new Error("Should have thrown"); + } catch (e) { + ok(e.message.includes("Decompression"), `msg: ${e.message}`); + } + }); + + test(`${variant}: zstdCompressStream error message contains "Compression"`, async (_t) => { + try { + await pipeline([ + createReadableStream(compressibleBody), + zstdCompressStream({ maxOutputSize: 5 }), + ]); + throw new Error("Should have thrown"); + } catch (e) { + ok(e.message.includes("Compression"), `msg: ${e.message}`); + } + }); + + // Error message includes the maxOutputSize number (covers StringLiteral survivor). + test(`${variant}: gzipDecompressStream error message includes the byte limit value`, async (_t) => { + const input = gzipSync(compressibleBody); + try { + await pipeline([ + createReadableStream(input), + gzipDecompressStream({ maxOutputSize: 42 }), + ]); + throw new Error("Should have thrown"); + } catch (e) { + ok(e.message.includes("42"), `msg: ${e.message}`); + } + }); +} + +// *** restore after "close" event (StringLiteral "close" → "") *** // +// After a stream closes normally, a second independent stream must still work. +if (variant === "node") { + test(`${variant}: gzipDecompressStream second invocation works after first closes`, async (_t) => { + const input = gzipSync(compressibleBody); + const out1 = await streamToString( + pipejoin([createReadableStream(input), gzipDecompressStream()]), + ); + strictEqual(out1, compressibleBody); + const out2 = await streamToString( + pipejoin([createReadableStream(input), gzipDecompressStream()]), + ); + strictEqual(out2, compressibleBody); + }); + + // After an error event fires the push override must be restored + // (StringLiteral "error" → ""). + test(`${variant}: gzipDecompressStream works correctly after previous maxOutputSize error`, async (_t) => { + const input = gzipSync(compressibleBody); + try { + await pipeline([ + createReadableStream(input), + gzipDecompressStream({ maxOutputSize: 10 }), + ]); + } catch (_e) { + // expected + } + const out = await streamToString( + pipejoin([createReadableStream(input), gzipDecompressStream()]), + ); + strictEqual(out, compressibleBody); + }); +} + +// *** maxOutputSize: null on compress streams (LogicalOperator || survivor) *** // +// `||` mutation: `null !== null || null !== void 0` = true → guardOutput(null) → throws. +// These tests verify null disables the guard on compress streams. +if (variant === "node") { + test(`${variant}: gzipCompressStream maxOutputSize:null should NOT throw`, async (_t) => { + const output = await streamToString( + pipejoin([ + createReadableStream(compressibleBody), + gzipCompressStream({ maxOutputSize: null }), + ]), + ); + strictEqual(output, gzipSync(compressibleBody).toString()); + }); + + test(`${variant}: deflateCompressStream maxOutputSize:null should NOT throw`, async (_t) => { + const output = await streamToString( + pipejoin([ + createReadableStream(compressibleBody), + deflateCompressStream({ maxOutputSize: null }), + ]), + ); + strictEqual(output, deflateSync(compressibleBody).toString()); + }); + + test(`${variant}: brotliCompressStream maxOutputSize:null should NOT throw`, async (_t) => { + const out = await streamToBuffer( + pipejoin([ + createReadableStream(compressibleBody), + brotliCompressStream({ maxOutputSize: null }), + ]), + ); + strictEqual(brotliDecompressSync(out).toString(), compressibleBody); + }); + + test(`${variant}: zstdCompressStream maxOutputSize:null should NOT throw`, async (_t) => { + const out = await streamToBuffer( + pipejoin([ + createReadableStream(compressibleBody), + zstdCompressStream({ maxOutputSize: null }), + ]), + ); + strictEqual(zstdDecompressSync(out).toString(), compressibleBody); + }); +} + +// *** zstd quality output size differs (kills ObjectLiteral `params ?? {}`) *** // +// With a 100KB repetitive body, quality:1 and quality:19 DO produce different sizes. +// `params ?? {}` loses the quality → both use default level → same output size. +if (variant === "node") { + const bigRepeat = "x".repeat(100_000); + test(`${variant}: zstdCompressStream quality:1 differs from quality:19 on large body`, async (_t) => { + const out1 = await streamToBuffer( + pipejoin([ + createReadableStream(bigRepeat), + zstdCompressStream({ quality: 1 }), + ]), + ); + const out19 = await streamToBuffer( + pipejoin([ + createReadableStream(bigRepeat), + zstdCompressStream({ quality: 19 }), + ]), + ); + ok( + out1.byteLength !== out19.byteLength, + `quality 1 (${out1.byteLength}B) must differ from quality 19 (${out19.byteLength}B)`, + ); + }); +} + +// *** default export usability (ObjectLiteral `default = {}` survivor) *** // +// The default export must expose compressStream/decompressStream functions; +// if the object is `{}` those calls would throw TypeError. +if (variant === "node") { + test(`${variant}: gzip default export compressStream/decompressStream round-trips`, async (_t) => { + const gzipMod = await import("@datastream/compress/gzip"); + const out = await streamToString( + pipejoin([ + createReadableStream(compressibleBody), + gzipMod.default.compressStream(), + gzipMod.default.decompressStream(), + ]), + ); + strictEqual(out, compressibleBody); + }); + + test(`${variant}: deflate default export compressStream/decompressStream round-trips`, async (_t) => { + const defMod = await import("@datastream/compress/deflate"); + const out = await streamToString( + pipejoin([ + createReadableStream(compressibleBody), + defMod.default.compressStream(), + defMod.default.decompressStream(), + ]), + ); + strictEqual(out, compressibleBody); + }); + + test(`${variant}: brotli default export compressStream/decompressStream round-trips`, async (_t) => { + const brotliMod = await import("@datastream/compress/brotli"); + const out = await streamToString( + pipejoin([ + createReadableStream(compressibleBody), + brotliMod.default.compressStream(), + brotliMod.default.decompressStream(), + ]), + ); + strictEqual(out, compressibleBody); + }); + + test(`${variant}: zstd default export compressStream/decompressStream round-trips`, async (_t) => { + const zstdMod = await import("@datastream/compress/zstd"); + const out = await streamToString( + pipejoin([ + createReadableStream(compressibleBody), + zstdMod.default.compressStream(), + zstdMod.default.decompressStream(), + ]), + ); + strictEqual(out, compressibleBody); + }); +} + +// *** AbortSignal honored on node compress/decompress streams *** // +// Aborting mid-flight must cause the pipeline to reject with an AbortError (the +// signal is forwarded into the underlying zlib stream); without signal support +// the pipeline would resolve successfully. A large payload + small chunkSize +// guarantees the stream is still in-flight when the signal fires. +const signalHonored = (e) => + e.name === "AbortError" || e.code === "ABORT_ERR" || /abort/i.test(e.message); +const bigBody = "x".repeat(2_000_000); +if (variant === "node") { + test(`${variant}: gzipCompressStream should reject when signal aborts`, async (_t) => { + const controller = new AbortController(); + const streams = [ + createReadableStream(bigBody, { chunkSize: 1024 }), + gzipCompressStream({}, { signal: controller.signal }), + ]; + const promise = pipeline(streams); + queueMicrotask(() => controller.abort()); + try { + await promise; + throw new Error("Should have thrown"); + } catch (e) { + ok(signalHonored(e), `${e.name}: ${e.message}`); + } + }); + + test(`${variant}: deflateDecompressStream should reject when signal aborts`, async (_t) => { + const controller = new AbortController(); + const input = deflateSync(bigBody); + const streams = [ + createReadableStream(input, { chunkSize: 1024 }), + deflateDecompressStream({}, { signal: controller.signal }), + ]; + const promise = pipeline(streams); + queueMicrotask(() => controller.abort()); + try { + await promise; + throw new Error("Should have thrown"); + } catch (e) { + ok(signalHonored(e), `${e.name}: ${e.message}`); + } }); } @@ -380,3 +977,400 @@ if (variant === "webstream") { } }); } + +// *** web (*.web.js) sources, exercised directly *** // +// Node's package export resolution always matches the built-in `node` +// condition first, so `@datastream/compress/Core component of the datastream framework, the robust JavaScript streaming utility.
@@ -18,10 +18,10 @@
-
+
-
+
You can read the documentation at: https://datastream.js.org
diff --git a/packages/core/index.node.js b/packages/core/index.node.js index f50d0bd..b329293 100644 --- a/packages/core/index.node.js +++ b/packages/core/index.node.js @@ -9,16 +9,37 @@ const NULL_SENTINEL = Symbol.for("@datastream/null"); const toSafe = (v) => (v === null ? NULL_SENTINEL : v); const fromSafe = (v) => (v === NULL_SENTINEL ? null : v); +// streamToObject accumulates onto an Object.create(null) and previously +// returned `{ ...value }`. If any chunk carried an own `__proto__` key (e.g. +// from JSON.parse of untrusted input), the spread copied it as an own +// enumerable `__proto__` data property on the returned plain object — a +// surprising contract that confuses prototype-based checks. Strip any own +// `__proto__` key and return a plain object with a normal prototype. +const sanitizeObject = (value) => { + const out = {}; + for (const key of Object.keys(value)) { + if (key === "__proto__") continue; + out[key] = value[key]; + } + return out; +}; + export const pipeline = async (streams, streamOptions = {}) => { for (let idx = 0, l = streams.length; idx < l; idx++) { if (typeof streams[idx].then === "function") { throw new Error(`Promise instead of stream passed in at index ${idx}`); } } + // Work on copies so appending the terminal writable (and deriving its + // objectMode) doesn't mutate the caller's array or options object. + streams = [...streams]; // Ensure stream ends with only writable const lastStream = streams[streams.length - 1]; if (isReadable(lastStream)) { - streamOptions.objectMode = lastStream._readableState.objectMode; + streamOptions = { + ...streamOptions, + objectMode: lastStream._readableState.objectMode, + }; streams.push(createWritableStream(() => {}, streamOptions)); } await pipelinePromise(streams, streamOptions); @@ -73,12 +94,23 @@ export const backpressureGauge = (streams) => { // Number.parseInt( (process.hrtime.bigint() - pauseTimestamp).toString() , 10 ) / 1_000_000 // ms const duration = Date.now() - timestamp; metrics[keys[i]].timeline.push({ timestamp, duration }); + // Clear so a second resume without an intervening pause can't + // record a phantom interval from the stale pause timestamp. + timestamp = undefined; } }); - value.on("end", () => { + // Readable streams emit 'end'; writable (sink) streams emit 'finish' + // and never 'end', so listen for both (plus 'close' as a backstop) to + // record total duration for writable/duplex nodes too. Guard against + // double-recording when more than one terminal event fires. + const recordTotal = () => { + if (metrics[keys[i]].total.timestamp != null) return; const duration = Date.now() - startTimestamp; metrics[keys[i]].total = { timestamp: startTimestamp, duration }; - }); + }; + value.on("end", recordTotal); + value.on("finish", recordTotal); + value.on("close", recordTotal); } return metrics; }; @@ -120,7 +152,8 @@ export const streamToArray = (stream, { maxBufferSize } = {}) => { ); } } - value.push(chunk); + // Decode the null sentinel here too so both consumption paths agree. + value.push(fromSafe(chunk)); } return value; })(); @@ -143,10 +176,12 @@ export const streamToObject = (stream, { maxBufferSize } = {}) => { return; } } - Object.assign(value, chunk); + // Unwrap the null sentinel so a null-bearing object stream doesn't + // leak the Symbol; Object.assign(value, null) is a safe no-op. + Object.assign(value, fromSafe(chunk)); }); stream.on("end", () => { - resolve({ ...value }); + resolve(sanitizeObject(value)); }); stream.on("error", reject); }); @@ -163,9 +198,9 @@ export const streamToObject = (stream, { maxBufferSize } = {}) => { ); } } - Object.assign(value, chunk); + Object.assign(value, fromSafe(chunk)); } - return { ...value }; + return sanitizeObject(value); })(); }; @@ -186,7 +221,9 @@ export const streamToString = (stream, { maxBufferSize } = {}) => { return; } } - chunks.push(chunk); + // Unwrap the null sentinel; otherwise join("") throws + // "Cannot convert a Symbol value to a string". + chunks.push(fromSafe(chunk)); }); stream.on("end", () => { resolve(chunks.join("")); @@ -206,7 +243,7 @@ export const streamToString = (stream, { maxBufferSize } = {}) => { ); } } - chunks.push(chunk); + chunks.push(fromSafe(chunk)); } return chunks.join(""); })(); @@ -218,7 +255,9 @@ export const streamToBuffer = (stream, { maxBufferSize } = {}) => { const value = []; let size = 0; stream.on("data", (chunk) => { - const buf = Buffer.from(chunk); + // Unwrap the null sentinel; Buffer.from(symbol) throws + // ERR_INVALID_ARG_TYPE. fromSafe(null) -> null -> empty buffer. + const buf = Buffer.from(fromSafe(chunk) ?? []); if (maxBufferSize != null) { size += buf.length; if (size > maxBufferSize) { @@ -242,7 +281,7 @@ export const streamToBuffer = (stream, { maxBufferSize } = {}) => { const value = []; let size = 0; for await (const chunk of stream) { - const buf = Buffer.from(chunk); + const buf = Buffer.from(fromSafe(chunk) ?? []); if (maxBufferSize != null) { size += buf.length; if (size > maxBufferSize) { diff --git a/packages/core/index.test.js b/packages/core/index.test.js index f1a3c8f..27752d1 100644 --- a/packages/core/index.test.js +++ b/packages/core/index.test.js @@ -1,4 +1,5 @@ import { deepStrictEqual, ok, strictEqual } from "node:assert"; +import { EventEmitter } from "node:events"; import test, { mock } from "node:test"; import { backpressureGauge, @@ -165,6 +166,22 @@ test(`${variant}: streamToBuffer should work with Uint8Array`, async (_t) => { deepStrictEqual(output.toString(), "hello"); }); +// The bare `@datastream/core` import resolves to the node build under both +// --conditions (Node always injects the `node` condition first), so the web +// build is only actually exercised by importing it directly. streamToBuffer +// was missing from the web build entirely; assert parity here. +test(`${variant}: web build exports a working streamToBuffer`, async (_t) => { + const web = await import( + `file://${new URL("./index.web.js", import.meta.url).pathname}` + ); + strictEqual(typeof web.streamToBuffer, "function"); + const out = await web.streamToBuffer( + web.createReadableStream(["hello", " ", "world"]), + ); + ok(out instanceof Uint8Array); + strictEqual(new TextDecoder().decode(out), "hello world"); +}); + // *** backpressureGauge *** // test(`${variant}: backpressureGauge should measure stream metrics`, async (_t) => { const input = ["a", "b", "c"]; @@ -219,6 +236,19 @@ test(`${variant}: backpressureGauge should track resume without prior pause`, as strictEqual(typeof metrics.transform.total.duration, "number"); }); +test(`${variant}: backpressureGauge records one interval per pause/resume pair`, async (_t) => { + const transform = createTransformStream(); + const metrics = backpressureGauge({ transform }); + + // One real pause/resume pair, then a stray resume with no intervening pause. + transform.emit("pause"); + transform.emit("resume"); + transform.emit("resume"); + + // The stray resume must not record a phantom interval from the stale pause. + strictEqual(metrics.transform.timeline.length, 1); +}); + // *** createReadableStream *** // test(`${variant}: createReadableStream should create a readable stream from string`, async (_t) => { const input = "abc"; @@ -884,3 +914,1149 @@ test(`${variant}: deepEqual via JSON serialization`, () => { strictEqual(deepEqual({ a: { b: 1 } }, { a: { b: 1 } }), true); strictEqual(deepEqual({ a: { b: 1 } }, { a: { b: 2 } }), false); }); + +// *** Node NULL_SENTINEL collector regression *** // +// The documented way to flow a null through a node object-mode stream is +// enqueue(null), which createTransformStream wraps as NULL_SENTINEL. Every +// collector must unwrap it via fromSafe, not just streamToArray. +test(`${variant}: streamToArray unwraps NULL_SENTINEL from object stream`, async (_t) => { + const streams = [ + createReadableStream(["a"]), + createTransformStream((_chunk, enqueue) => enqueue(null)), + ]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [null]); +}); + +test(`${variant}: streamToString unwraps NULL_SENTINEL from object stream`, async (_t) => { + const streams = [ + createReadableStream(["a"]), + createTransformStream((_chunk, enqueue) => enqueue(null)), + ]; + const output = await streamToString(pipejoin(streams)); + // fromSafe(null) -> null; "".join semantics turn null into an empty string. + strictEqual(output, ""); +}); + +test(`${variant}: streamToObject unwraps NULL_SENTINEL from object stream`, async (_t) => { + const streams = [ + createReadableStream(["a"]), + createTransformStream((_chunk, enqueue) => { + enqueue({ x: 1 }); + enqueue(null); + }), + ]; + // Object.assign(value, null) is a no-op, so the null chunk must not throw. + const output = await streamToObject(pipejoin(streams)); + deepStrictEqual(output, { x: 1 }); +}); + +test(`${variant}: streamToBuffer unwraps NULL_SENTINEL from object stream`, async (_t) => { + const streams = [ + createReadableStream(["a"]), + createTransformStream((_chunk, enqueue) => { + enqueue("hi"); + enqueue(null); + }), + ]; + // Buffer.from(null) throws; fromSafe(null) must yield an empty buffer. + const output = await streamToBuffer(pipejoin(streams)); + strictEqual(output.toString(), "hi"); +}); + +// *** Node backpressureGauge writable total regression *** // +if (variant === "node") { + test(`${variant}: backpressureGauge records total for writable sinks`, async (_t) => { + const writable = createWritableStream(); + const streams = { + readable: createReadableStream(["a", "b", "c"]), + writable, + }; + const metrics = backpressureGauge(streams); + await pipeline(Object.values(streams)); + // Writable streams emit 'finish'/'close', not 'end', so total must be + // recorded from those lifecycle events too. + strictEqual(typeof metrics.writable.total.timestamp, "number"); + strictEqual(typeof metrics.writable.total.duration, "number"); + }); +} + +// *** Node streamToObject __proto__ contract regression *** // +test(`${variant}: streamToObject does not expose own __proto__ data key`, async (_t) => { + // JSON.parse produces an own __proto__ key; the accumulator must not surface + // it as an own enumerable property on the returned object. + const evil = JSON.parse('{"__proto__":{"polluted":true},"safe":1}'); + const streams = [ + createReadableStream(["a"]), + createTransformStream((_chunk, enqueue) => enqueue(evil)), + ]; + const output = await streamToObject(pipejoin(streams)); + strictEqual(Object.hasOwn(output, "__proto__"), false); + strictEqual(output.safe, 1); + // And no global prototype pollution occurred. + strictEqual({}.polluted, undefined); +}); + +// *** Web build direct-import regressions *** // +// The bare `@datastream/core` import always resolves to the node build, so the +// web source is exercised only by importing it directly here. +const loadWeb = () => + import(`file://${new URL("./index.web.js", import.meta.url).pathname}`); + +test(`${variant}: web streamToString decodes byte chunks instead of comma-joining`, async (_t) => { + const web = await loadWeb(); + async function* gen() { + yield new TextEncoder().encode("hi"); + yield new TextEncoder().encode("!"); + } + const output = await web.streamToString(gen()); + strictEqual(output, "hi!"); +}); + +test(`${variant}: web streamToString decodes multibyte split across chunks`, async (_t) => { + const web = await loadWeb(); + const bytes = new TextEncoder().encode("é"); // 2 bytes: 0xC3 0xA9 + async function* gen() { + yield bytes.subarray(0, 1); + yield bytes.subarray(1); + } + const output = await web.streamToString(gen()); + strictEqual(output, "é"); +}); + +test(`${variant}: web streamToString still joins string chunks`, async (_t) => { + const web = await loadWeb(); + async function* gen() { + yield "hello"; + yield " world"; + } + const output = await web.streamToString(gen()); + strictEqual(output, "hello world"); +}); + +test(`${variant}: web createReadableStream honors typed-array byteOffset/byteLength`, async (_t) => { + const web = await loadWeb(); + // A subarray view over a larger buffer must stream only its own window, + // not the whole backing ArrayBuffer (adjacent-heap leak otherwise). + const full = new Uint8Array([0, 0, 1, 2, 3, 0, 0]); + const view = full.subarray(2, 5); // [1,2,3] + const out = await web.streamToBuffer(web.createReadableStream(view)); + deepStrictEqual(Array.from(out), [1, 2, 3]); +}); + +test(`${variant}: web createReadableStream honors Buffer byteOffset/byteLength`, async (_t) => { + const web = await loadWeb(); + // Node Buffers share a pooled allocation; reading the whole backing buffer + // would leak pooled bytes and yield far more than 5 bytes. + const buf = Buffer.from([1, 2, 3, 4, 5]); + const out = await web.streamToBuffer(web.createReadableStream(buf)); + deepStrictEqual(Array.from(out), [1, 2, 3, 4, 5]); +}); + +test(`${variant}: web create*Stream remove the abort listener on error`, async (_t) => { + const web = await loadWeb(); + const controller = new AbortController(); + const { signal } = controller; + const before = signal.removeEventListener; + let removed = 0; + // Count removeEventListener calls for 'abort' to detect listener cleanup. + signal.removeEventListener = function (type, ...rest) { + if (type === "abort") removed += 1; + return before.call(this, type, ...rest); + }; + const streams = [ + web.createReadableStream(["a", "b", "c"]), + web.createTransformStream( + () => { + throw new Error("boom"); + }, + { signal }, + ), + web.createWritableStream(() => {}, { signal }), + ]; + try { + await web.pipeline(streams); + throw new Error("Should have thrown"); + } catch (e) { + strictEqual(e.message, "boom"); + } + // Both the transform and the writable registered an abort listener; both + // must be removed on the error path. + ok(removed >= 2, `expected >=2 abort listener removals, got ${removed}`); +}); + +// Race against a short timeout: an unsupported input must error promptly, not +// hang the stream forever (which would otherwise stall the whole test run). +const withTimeout = (promise, ms = 1000) => + Promise.race([ + promise, + new Promise((_resolve, reject) => + setTimeout(() => reject(new Error("hung: stream never settled")), ms), + ), + ]); + +test(`${variant}: web createReadableStream errors on unsupported scalar input`, async (_t) => { + const web = await loadWeb(); + try { + await withTimeout(web.streamToArray(web.createReadableStream(42))); + throw new Error("Should have thrown"); + } catch (e) { + ok(e instanceof TypeError, `expected TypeError, got ${e}`); + ok(e.message.includes("unsupported input")); + } +}); + +test(`${variant}: web createReadableStream errors clearly on null input`, async (_t) => { + const web = await loadWeb(); + try { + await withTimeout(web.streamToArray(web.createReadableStream(null))); + throw new Error("Should have thrown"); + } catch (e) { + ok(e instanceof TypeError, `expected TypeError, got ${e}`); + ok(e.message.includes("unsupported input")); + } +}); + +test(`${variant}: web isReadable/isWritable return false for null/undefined`, async (_t) => { + const web = await loadWeb(); + strictEqual(web.isReadable(null), false); + strictEqual(web.isReadable(undefined), false); + strictEqual(web.isWritable(null), false); + strictEqual(web.isWritable(undefined), false); + // And primitives must not throw either. + strictEqual(web.isReadable(42), false); + strictEqual(web.isWritable("x"), false); +}); + +// =========================================================================== +// *** Mutation-killing tests (node build) *** +// Each test below pins a specific behavior so a one-line mutation of the +// source would flip an assertion. Grouped by the source construct targeted. +// =========================================================================== + +// --- EventEmitter-only collector path (the `typeof stream.on === "function"` +// branch). A Node Readable is also async-iterable, so deleting the .on branch +// still works via the async path. A bare EventEmitter is NOT async-iterable, so +// only the .on path can drain it; this distinguishes the two code paths. --- +const emitterStream = (chunks) => { + const ee = new EventEmitter(); + // Not async-iterable on purpose: no Symbol.asyncIterator, no .pipe. + process.nextTick(() => { + for (const c of chunks) ee.emit("data", c); + ee.emit("end"); + }); + return ee; +}; + +if (variant === "node") { + test(`${variant}: streamToArray uses the .on path for plain EventEmitters`, async (_t) => { + const out = await streamToArray(emitterStream(["a", "b", "c"])); + deepStrictEqual(out, ["a", "b", "c"]); + }); + + test(`${variant}: streamToString uses the .on path for plain EventEmitters`, async (_t) => { + const out = await streamToString(emitterStream(["a", "b", "c"])); + strictEqual(out, "abc"); + }); + + test(`${variant}: streamToObject uses the .on path for plain EventEmitters`, async (_t) => { + const out = await streamToObject(emitterStream([{ a: 1 }, { b: 2 }])); + deepStrictEqual(out, { a: 1, b: 2 }); + }); + + test(`${variant}: streamToBuffer uses the .on path for plain EventEmitters`, async (_t) => { + const out = await streamToBuffer( + emitterStream([Buffer.from("ab"), Buffer.from("c")]), + ); + strictEqual(out.toString(), "abc"); + }); + + // The .on path must reject on 'error' (kills deletion of stream.on("error")). + test(`${variant}: streamToArray .on path rejects on error event`, async (_t) => { + const ee = new EventEmitter(); + ee.destroy = () => {}; + process.nextTick(() => ee.emit("error", new Error("boom"))); + try { + await withTimeout(streamToArray(ee)); + throw new Error("Should have thrown"); + } catch (e) { + strictEqual(e.message, "boom"); + } + }); +} + +// --- maxBufferSize boundary precision for every collector. The threshold is a +// strict `>` and the running total is an ADDITION. These pin `>` (not >=, <=), +// the `+=` (not -=), and that the boundary value itself does NOT throw. --- + +// streamToArray: object-mode length fallback is `?? 1` per chunk. +test(`${variant}: streamToArray counts each non-sized chunk as 1 (?? 1 fallback)`, async (_t) => { + // 3 plain objects -> size 3. maxBufferSize 3 must pass (boundary, not > ). + const ok3 = await streamToArray(createReadableStream([{}, {}, {}]), { + maxBufferSize: 3, + }); + strictEqual(ok3.length, 3); + // A 4th identical chunk -> size 4 > 3 must throw (kills `?? 0`, `-=`, `>=`). + try { + await streamToArray(createReadableStream([{}, {}, {}, {}]), { + maxBufferSize: 3, + }); + throw new Error("Should have thrown"); + } catch (e) { + ok(e.message.includes("maxBufferSize")); + } +}); + +test(`${variant}: streamToArray at exact maxBufferSize boundary does not throw`, async (_t) => { + // "aaa"+"bbb" = 6 chars; maxBufferSize 6 is the boundary and must pass. + const out = await streamToArray(createReadableStream(["aaa", "bbb"]), { + maxBufferSize: 6, + }); + deepStrictEqual(out, ["aaa", "bbb"]); +}); + +test(`${variant}: streamToArray uses byteLength when length is absent`, async (_t) => { + // Uint8Array has byteLength but no string length; size must accrue 5. + const chunk = Uint8Array.from([1, 2, 3, 4, 5]); + try { + await streamToArray(createReadableStream([chunk]), { maxBufferSize: 4 }); + throw new Error("Should have thrown"); + } catch (e) { + ok(e.message.includes("maxBufferSize")); + } + // And 5 (exact) passes. + const out = await streamToArray(createReadableStream([chunk]), { + maxBufferSize: 5, + }); + strictEqual(out.length, 1); +}); + +test(`${variant}: streamToString at exact boundary passes, one over throws`, async (_t) => { + const ok6 = await streamToString(createReadableStream(["aaa", "bbb"]), { + maxBufferSize: 6, + }); + strictEqual(ok6, "aaabbb"); + try { + await streamToString(createReadableStream(["aaa", "bbbc"]), { + maxBufferSize: 6, + }); + throw new Error("Should have thrown"); + } catch (e) { + ok(e.message.includes("maxBufferSize")); + } +}); + +test(`${variant}: streamToString non-sized chunk fallback is 0, not 1`, async (_t) => { + // streamToString uses `?? 0`: an object with no length contributes 0, so a + // tiny maxBufferSize must NOT trip on object-mode chunks. (Kills `?? 1`.) + const out = await streamToString(createReadableStream([{}, {}, {}]), { + maxBufferSize: 0, + }); + // String(...) of objects joined; just assert it did not throw. + strictEqual(typeof out, "string"); +}); + +test(`${variant}: streamToObject at exact boundary passes, one over throws`, async (_t) => { + // Each object counts as 1 (?? 1). 3 objects, boundary 3 passes. + const ok3 = await streamToObject( + createReadableStream([{ a: 1 }, { b: 2 }, { c: 3 }]), + { maxBufferSize: 3 }, + ); + deepStrictEqual(ok3, { a: 1, b: 2, c: 3 }); + try { + await streamToObject( + createReadableStream([{ a: 1 }, { b: 2 }, { c: 3 }, { d: 4 }]), + { maxBufferSize: 3 }, + ); + throw new Error("Should have thrown"); + } catch (e) { + ok(e.message.includes("maxBufferSize")); + } +}); + +test(`${variant}: streamToBuffer at exact boundary passes, one over throws`, async (_t) => { + const ok6 = await streamToBuffer( + createReadableStream([Buffer.from("aaa"), Buffer.from("bbb")]), + { maxBufferSize: 6 }, + ); + strictEqual(ok6.toString(), "aaabbb"); + try { + await streamToBuffer( + createReadableStream([Buffer.from("aaa"), Buffer.from("bbbc")]), + { maxBufferSize: 6 }, + ); + throw new Error("Should have thrown"); + } catch (e) { + ok(e.message.includes("maxBufferSize")); + } +}); + +// The maxBufferSize error messages must name the collector and the limit value +// (kills StringLiteral -> "" on each `buffer exceeds maxBufferSize (...)`). +test(`${variant}: maxBufferSize errors carry collector name and limit`, async (_t) => { + const cases = [ + [streamToArray, ["aaa", "bbb", "ccc"], "streamToArray"], + [streamToString, ["aaa", "bbb", "ccc"], "streamToString"], + [streamToBuffer, [Buffer.from("aaaaaaa")], "streamToBuffer"], + ]; + for (const [fn, input, name] of cases) { + try { + await fn(createReadableStream(input), { maxBufferSize: 6 }); + throw new Error("Should have thrown"); + } catch (e) { + ok(e.message.includes(name), `expected ${name} in: ${e.message}`); + ok(e.message.includes("6"), `expected limit 6 in: ${e.message}`); + } + } + try { + await streamToObject(createReadableStream([{ a: 1 }, { b: 2 }, { c: 3 }]), { + maxBufferSize: 2, + }); + throw new Error("Should have thrown"); + } catch (e) { + ok(e.message.includes("streamToObject")); + ok(e.message.includes("2")); + } +}); + +// --- async-iterable path also enforces maxBufferSize boundary (covers the +// second copy of each guard in the for-await branch). --- +const asyncGen = (chunks) => + (async function* () { + for (const c of chunks) yield c; + })(); + +test(`${variant}: streamToArray async path enforces boundary precisely`, async (_t) => { + const out = await streamToArray(asyncGen(["aaa", "bbb"]), { + maxBufferSize: 6, + }); + deepStrictEqual(out, ["aaa", "bbb"]); + try { + await streamToArray(asyncGen(["aaa", "bbbc"]), { maxBufferSize: 6 }); + throw new Error("Should have thrown"); + } catch (e) { + ok(e.message.includes("maxBufferSize")); + } +}); + +test(`${variant}: streamToString async path enforces boundary precisely`, async (_t) => { + const out = await streamToString(asyncGen(["aaa", "bbb"]), { + maxBufferSize: 6, + }); + strictEqual(out, "aaabbb"); + try { + await streamToString(asyncGen(["aaa", "bbbc"]), { maxBufferSize: 6 }); + throw new Error("Should have thrown"); + } catch (e) { + ok(e.message.includes("maxBufferSize")); + } +}); + +test(`${variant}: streamToObject async path enforces boundary precisely`, async (_t) => { + const out = await streamToObject(asyncGen([{ a: 1 }, { b: 2 }, { c: 3 }]), { + maxBufferSize: 3, + }); + deepStrictEqual(out, { a: 1, b: 2, c: 3 }); + try { + await streamToObject(asyncGen([{ a: 1 }, { b: 2 }, { c: 3 }, { d: 4 }]), { + maxBufferSize: 3, + }); + throw new Error("Should have thrown"); + } catch (e) { + ok(e.message.includes("maxBufferSize")); + } +}); + +test(`${variant}: streamToBuffer async path enforces boundary precisely`, async (_t) => { + const out = await streamToBuffer( + asyncGen([Buffer.from("aaa"), Buffer.from("bbb")]), + { maxBufferSize: 6 }, + ); + strictEqual(out.toString(), "aaabbb"); + try { + await streamToBuffer(asyncGen([Buffer.from("aaa"), Buffer.from("bbbc")]), { + maxBufferSize: 6, + }); + throw new Error("Should have thrown"); + } catch (e) { + ok(e.message.includes("maxBufferSize")); + } +}); + +// streamToObject async byteLength fallback (Uint8Array chunks count by bytes). +test(`${variant}: streamToObject byteLength fallback counts bytes`, async (_t) => { + // A typed array of 5 bytes -> size 5 > 4 must throw even in object mode. + const chunk = Uint8Array.from([1, 2, 3, 4, 5]); + try { + await streamToObject(createReadableStream([chunk]), { maxBufferSize: 4 }); + throw new Error("Should have thrown"); + } catch (e) { + ok(e.message.includes("maxBufferSize")); + } +}); + +// The size fallback is `length ?? byteLength ?? N`, NOT `length && byteLength`. +// A chunk with NO `length` but a truthy `byteLength` must count by byteLength. +// Under the `&&` (LogicalOperator) mutant, `undefined && byteLength` is +// undefined, so the fallback collapses to N (1 or 0) and the limit is not hit. +// Use a plain object exposing only `byteLength` so `?.length` is undefined. +const byteLenChunk = (n, extra = {}) => ({ byteLength: n, ...extra }); + +test(`${variant}: streamToArray counts a byteLength-only chunk by its byteLength`, async (_t) => { + // .on path: size 5 > 4 must throw (kills `?? -> &&` at the .on guard). + try { + await streamToArray(createReadableStream([byteLenChunk(5)]), { + maxBufferSize: 4, + }); + throw new Error("Should have thrown"); + } catch (e) { + ok(e.message.includes("maxBufferSize")); + } + // async path: same expectation. + try { + await streamToArray(asyncGen([byteLenChunk(5)]), { maxBufferSize: 4 }); + throw new Error("Should have thrown"); + } catch (e) { + ok(e.message.includes("maxBufferSize")); + } +}); + +test(`${variant}: streamToObject counts a byteLength-only chunk by its byteLength`, async (_t) => { + try { + await streamToObject(createReadableStream([byteLenChunk(5, { a: 1 })]), { + maxBufferSize: 4, + }); + throw new Error("Should have thrown"); + } catch (e) { + ok(e.message.includes("maxBufferSize")); + } + try { + await streamToObject(asyncGen([byteLenChunk(5, { a: 1 })]), { + maxBufferSize: 4, + }); + throw new Error("Should have thrown"); + } catch (e) { + ok(e.message.includes("maxBufferSize")); + } +}); + +test(`${variant}: streamToString counts a byteLength-only chunk by its byteLength`, async (_t) => { + // streamToString fallback is `?? 0`; a byteLength-only chunk of 5 still + // exceeds maxBufferSize 4 via byteLength (kills `?? -> &&`). + try { + await streamToString(createReadableStream([byteLenChunk(5)]), { + maxBufferSize: 4, + }); + throw new Error("Should have thrown"); + } catch (e) { + ok(e.message.includes("maxBufferSize")); + } + try { + await streamToString(asyncGen([byteLenChunk(5)]), { maxBufferSize: 4 }); + throw new Error("Should have thrown"); + } catch (e) { + ok(e.message.includes("maxBufferSize")); + } +}); + +// --- NULL_SENTINEL round-trip: a transform enqueue(null) flows through as null, +// AND a literal pushed null is treated as EOF (does not appear). --- +test(`${variant}: createReadableStream array null becomes a flowing null value`, async (_t) => { + // toSafe maps array `null` -> NULL_SENTINEL so it is not interpreted as EOF; + // the collector's fromSafe maps it back to null. + const out = await streamToArray(createReadableStream(["a", null, "b"])); + deepStrictEqual(out, ["a", null, "b"]); +}); + +// --- sanitizeObject: own-enumerable __proto__ key must be stripped. Use a +// literal own-enumerable key via Object.defineProperty so the +// `key === "__proto__"` guard is exercised through Object.keys. --- +test(`${variant}: streamToObject strips an own-enumerable __proto__ key`, async (_t) => { + const evil = {}; + Object.defineProperty(evil, "__proto__", { + value: { polluted: true }, + enumerable: true, + configurable: true, + writable: true, + }); + Object.defineProperty(evil, "safe", { + value: 1, + enumerable: true, + configurable: true, + writable: true, + }); + strictEqual(Object.keys(evil).includes("__proto__"), true); + const out = await streamToObject(asyncGen([evil])); + strictEqual(Object.hasOwn(out, "__proto__"), false); + strictEqual(out.safe, 1); + // Without the `key === "__proto__"` guard, `out["__proto__"] = ...` would + // replace out's prototype (out is a plain `{}`), leaking `polluted` and + // changing the prototype. The guard must keep a clean Object.prototype. + strictEqual(Object.getPrototypeOf(out), Object.prototype); + strictEqual(out.polluted, undefined); +}); + +// --- pipeline: lastStream index is length - 1 (kills `+ 1`). A single pure +// Readable needs an appended writable sink to terminate; with `+ 1` the index +// is undefined, isReadable(undefined) is false, no sink is appended, and +// pipelinePromise([readable]) rejects with "streams argument must be specified". +// This also kills the isReadable(lastStream) branch deletion. --- +test(`${variant}: pipeline appends a sink for a single pure readable`, async (_t) => { + const out = await withTimeout( + pipeline([createReadableStream(["a", "b", "c"])]), + ); + deepStrictEqual(out, {}); +}); + +// --- pipeline promise guard loop must actually iterate (kills loop `false`, +// `idx >= l`, block deletion, the `typeof ... then` check, and the index in the +// message). A promise at index 2 must be reported with that index. --- +test(`${variant}: pipeline reports the index of a promise-instead-of-stream`, async (_t) => { + const streams = [ + createReadableStream(["a"]), + createTransformStream(), + Promise.resolve(createTransformStream()), + ]; + try { + await pipeline(streams); + throw new Error("Should have thrown"); + } catch (e) { + strictEqual(e.message, "Promise instead of stream passed in at index 2"); + } +}); + +// --- pipejoin forwards stream errors to the onError callback (kills onError +// block deletion / process.nextTick block deletion and the on("error") +// string mutant). --- +test(`${variant}: pipejoin error handler receives error on the right event`, async (_t) => { + let got; + const streams = [ + createReadableStream(["a"]), + createTransformStream(() => { + throw new Error("boom2"); + }), + ]; + pipejoin(streams, (e) => { + got = e.message; + }); + await timeout(50); + strictEqual(got, "boom2"); +}); + +// pipejoin's DEFAULT onError rethrows asynchronously via process.nextTick. +// Deleting that body would silently swallow stream errors. Capture the rethrow +// through an uncaughtException listener (kills the onError default-block and the +// process.nextTick block deletions). Node only restored when done. +if (variant === "node") { + test(`${variant}: pipejoin default onError rethrows the error`, async (_t) => { + let caught; + const handler = (e) => { + caught = e.message; + }; + // Temporarily own uncaughtException so the async rethrow is observable + // without crashing the test process. + const prior = process.listeners("uncaughtException"); + for (const l of prior) process.removeListener("uncaughtException", l); + process.on("uncaughtException", handler); + try { + const streams = [ + createReadableStream(["a"]), + createTransformStream(() => { + throw new Error("default-rethrow"); + }), + ]; + const joined = pipejoin(streams); // default onError + joined.on("error", () => {}); + joined.resume(); + await timeout(100); + strictEqual(caught, "default-rethrow"); + } finally { + process.removeListener("uncaughtException", handler); + for (const l of prior) process.on("uncaughtException", l); + } + }); +} + +// --- createReadableStream branch coverage --- + +// Array.isArray branch: array maps null -> sentinel so an embedded null is +// preserved as a value (raw null would be EOF). (kills branch deletion / +// `false` / `true`). +test(`${variant}: createReadableStream array branch preserves embedded null`, async (_t) => { + const out = await streamToArray(createReadableStream([null, "x"])); + deepStrictEqual(out, [null, "x"]); +}); + +// object-with-byteLength branch (ArrayBuffer) yields a single Uint8Array chunk. +test(`${variant}: createReadableStream routes ArrayBuffer to byte chunker`, async (_t) => { + const buf = new Uint8Array([9, 8, 7]).buffer; + const out = await streamToArray(createReadableStream(buf)); + strictEqual(out.length, 1); + deepStrictEqual(Array.from(out[0]), [9, 8, 7]); +}); + +// String routing splits by chunkSize via substring (kills MethodExpression +// yield input2 and the position arithmetic). +test(`${variant}: createReadableStream chunks strings by chunkSize via substring`, async (_t) => { + const input = "abcdefgh"; + const out = await streamToArray( + createReadableStream(input, { chunkSize: 3 }), + ); + deepStrictEqual(out, ["abc", "def", "gh"]); +}); + +test(`${variant}: createReadableStream string chunk boundary is exact`, async (_t) => { + // length 6, chunkSize 3 -> exactly 2 full chunks, no empty trailing chunk + // (kills while `<=` which would emit an extra empty "" at position===length). + const out = await streamToArray( + createReadableStream("abcdef", { chunkSize: 3 }), + ); + deepStrictEqual(out, ["abc", "def"]); +}); + +// chunkSize <= 0 must throw (kills `<= 0` -> `< 0`, `false`, and message ""). +test(`${variant}: createReadableStream rejects zero chunkSize for strings`, (_t) => { + try { + createReadableStream("abc", { chunkSize: 0 }); + throw new Error("Should have thrown"); + } catch (e) { + ok(e.message.includes("positive number")); + } +}); + +test(`${variant}: createReadableStream rejects negative chunkSize for strings`, (_t) => { + try { + createReadableStream("abc", { chunkSize: -1 }); + throw new Error("Should have thrown"); + } catch (e) { + ok(e.message.includes("positive number")); + } +}); + +test(`${variant}: createReadableStream rejects zero chunkSize for ArrayBuffer`, (_t) => { + try { + createReadableStream(new Uint8Array([1, 2, 3]).buffer, { chunkSize: 0 }); + throw new Error("Should have thrown"); + } catch (e) { + ok(e.message.includes("positive number")); + } +}); + +test(`${variant}: createReadableStream rejects negative chunkSize for ArrayBuffer`, (_t) => { + try { + createReadableStream(new Uint8Array([1, 2, 3]).buffer, { chunkSize: -2 }); + throw new Error("Should have thrown"); + } catch (e) { + ok(e.message.includes("positive number")); + } +}); + +// ArrayBuffer chunking by size (kills while/position mutants and the subarray +// window arithmetic in the arraybuffer iterator). +if (variant === "node") { + test(`${variant}: createReadableStream chunks ArrayBuffer by chunkSize`, async (_t) => { + const buf = new Uint8Array([1, 2, 3, 4, 5]).buffer; + const out = await streamToArray( + createReadableStream(buf, { chunkSize: 2 }), + ); + deepStrictEqual( + out.map((c) => Array.from(c)), + [[1, 2], [3, 4], [5]], + ); + }); +} + +// createReadableStream() push queue guard: the `chunk !== null` half means +// pushing null (EOF) is always allowed even past the limit. +if (variant === "node") { + test(`${variant}: createReadableStream allows null push even at queue limit`, async (_t) => { + const stream = createReadableStream(undefined, { highWaterMark: 2 }); + stream.push("a"); + stream.push("b"); + // At the limit; pushing null (EOF) must NOT throw (kills `chunk !== null` + // -> `true`, which would throw on the null push). + stream.push(null); + const out = await streamToArray(stream); + deepStrictEqual(out, ["a", "b"]); + }); + + test(`${variant}: createReadableStream allows pushing up to the limit`, async (_t) => { + const stream = createReadableStream(undefined, { highWaterMark: 3 }); + stream.push("a"); + stream.push("b"); + stream.push("c"); + stream.push(null); + const out = await streamToArray(stream); + deepStrictEqual(out, ["a", "b", "c"]); + }); +} + +// --- createPassThroughStream default passThrough is identity (kills the +// ArrowFunction mutant `() => undefined`). With no transform fn, chunks must +// flow through unchanged. --- +test(`${variant}: createPassThroughStream default identity passes chunks through`, async (_t) => { + const out = await streamToArray( + pipejoin([createReadableStream(["a", "b"]), createPassThroughStream()]), + ); + deepStrictEqual(out, ["a", "b"]); +}); + +// --- The thenable check must be a strict `typeof result.then === "function"`. +// A handler that returns a non-null, non-thenable value (e.g. a string) must NOT +// be treated as a promise: with `&& true` (or `!== "function"`, or `=== ""`) +// the code would call `result.then(...)` on a string and throw. Returning a +// plain value must pass cleanly. --- +test(`${variant}: createPassThroughStream tolerates a non-thenable return value`, async (_t) => { + const out = await streamToArray( + pipejoin([ + createReadableStream(["a", "b"]), + createPassThroughStream((c) => `sync:${c}`), + ]), + ); + deepStrictEqual(out, ["a", "b"]); +}); + +test(`${variant}: createTransformStream tolerates a non-thenable return value`, async (_t) => { + const out = await streamToArray( + pipejoin([ + createReadableStream(["a", "b"]), + createTransformStream((c, enqueue) => { + enqueue(c); + return "sync-return"; + }), + ]), + ); + deepStrictEqual(out, ["a", "b"]); +}); + +test(`${variant}: createWritableStream tolerates a non-thenable write return`, async (_t) => { + const seen = []; + await pipeline([ + createReadableStream(["a", "b"]), + createWritableStream((c) => { + seen.push(c); + return `sync:${c}`; + }), + ]); + deepStrictEqual(seen, ["a", "b"]); +}); + +test(`${variant}: createPassThroughStream flush tolerates a non-thenable return`, async (_t) => { + const out = await streamToArray( + pipejoin([ + createReadableStream(["a"]), + createPassThroughStream( + (c) => c, + () => "flush-sync", + ), + ]), + ); + deepStrictEqual(out, ["a"]); +}); + +test(`${variant}: createTransformStream flush tolerates a non-thenable return`, async (_t) => { + const out = await streamToArray( + pipejoin([ + createReadableStream(["a"]), + createTransformStream( + (c, enqueue) => enqueue(c), + () => "flush-sync", + ), + ]), + ); + deepStrictEqual(out, ["a"]); +}); + +test(`${variant}: createWritableStream final tolerates a non-thenable return`, async (_t) => { + const seen = []; + await pipeline([ + createReadableStream(["a"]), + createWritableStream( + (c) => seen.push(c), + () => "final-sync", + ), + ]); + deepStrictEqual(seen, ["a"]); +}); + +// --- async vs sync result detection in create*Stream. A function returning a +// thenable must be awaited BEFORE the chunk is pushed / callback runs. Ordering +// proves the promise branch (kills `=== "function"` -> `!== "function"` / +// `true` / `false` / "" in the thenable checks). --- +test(`${variant}: createPassThroughStream awaits a returned promise before continuing`, async (_t) => { + const order = []; + const streams = [ + createReadableStream(["a"]), + createPassThroughStream(async () => { + order.push("transform-start"); + await timeout(20); + order.push("transform-end"); + }), + createWritableStream((c) => { + order.push(`write-${c}`); + }), + ]; + await pipeline(streams); + deepStrictEqual(order, ["transform-start", "transform-end", "write-a"]); +}); + +test(`${variant}: createTransformStream awaits a returned promise before continuing`, async (_t) => { + const order = []; + const streams = [ + createReadableStream(["a"]), + createTransformStream(async (chunk, enqueue) => { + order.push("t-start"); + await timeout(20); + order.push("t-end"); + enqueue(chunk); + }), + createWritableStream((c) => order.push(`w-${c}`)), + ]; + await pipeline(streams); + deepStrictEqual(order, ["t-start", "t-end", "w-a"]); +}); + +test(`${variant}: createWritableStream awaits a returned promise before final`, async (_t) => { + const order = []; + const streams = [ + createReadableStream(["a"]), + createWritableStream( + async () => { + order.push("write-start"); + await timeout(20); + order.push("write-end"); + }, + () => { + order.push("final"); + }, + ), + ]; + await pipeline(streams); + deepStrictEqual(order, ["write-start", "write-end", "final"]); +}); + +test(`${variant}: createPassThroughStream awaits an async flush before finishing`, async (_t) => { + const order = []; + const streams = [ + createReadableStream(["a"]), + createPassThroughStream( + () => order.push("pass"), + async () => { + order.push("flush-start"); + await timeout(20); + order.push("flush-end"); + }, + ), + createWritableStream(), + ]; + await pipeline(streams); + deepStrictEqual(order, ["pass", "flush-start", "flush-end"]); +}); + +test(`${variant}: createTransformStream awaits an async flush before finishing`, async (_t) => { + const order = []; + const streams = [ + createReadableStream(["a"]), + createTransformStream( + (c, enqueue) => { + order.push("t"); + enqueue(c); + }, + async () => { + order.push("flush-start"); + await timeout(20); + order.push("flush-end"); + }, + ), + createWritableStream(), + ]; + await pipeline(streams); + deepStrictEqual(order, ["t", "flush-start", "flush-end"]); +}); + +// --- deepClone / deepEqual preserve the original error as `cause` (kills +// ObjectLiteral -> {} which drops the cause). --- +test(`${variant}: deepClone attaches the original error as cause`, (_t) => { + try { + deepClone({ fn: () => {} }); + throw new Error("Should have thrown"); + } catch (e) { + ok(e.message.includes("clone chunk")); + ok(e.cause instanceof Error, "expected a cause error"); + } +}); + +test(`${variant}: deepEqual attaches the original error as cause`, (_t) => { + const a = {}; + a.self = a; + try { + deepEqual(a, a); + throw new Error("Should have thrown"); + } catch (e) { + ok(e.message.includes("stringify chunk")); + ok(e.cause instanceof Error, "expected a cause error"); + } +}); + +// --- shallowEqual: the `b == null` half of the guard. shallowEqual(obj, null) +// must be false; if `|| b == null` were dropped it would call Object.keys(null) +// and throw instead of returning false. --- +test(`${variant}: shallowEqual returns false when only b is null`, (_t) => { + strictEqual(shallowEqual({ a: 1 }, null), false); + strictEqual(shallowEqual({ a: 1 }, undefined), false); +}); + +// --- timeout abort: exact error shape (kills cause/code ObjectLiteral and +// StringLiteral mutants) for BOTH the already-aborted and abort-during paths. --- +test(`${variant}: timeout already-aborted rejects with AbortError cause code`, async (_t) => { + const controller = new AbortController(); + controller.abort(); + try { + await timeout(1000, { signal: controller.signal }); + throw new Error("Should have thrown"); + } catch (e) { + strictEqual(e.message, "Aborted"); + deepStrictEqual(e.cause, { code: "AbortError" }); + strictEqual(e.cause.code, "AbortError"); + } +}); + +test(`${variant}: timeout abort-during rejects with AbortError cause code`, async (_t) => { + const controller = new AbortController(); + const promise = timeout(60_000, { signal: controller.signal }); + controller.abort(); + try { + await promise; + throw new Error("Should have thrown"); + } catch (e) { + strictEqual(e.message, "Aborted"); + deepStrictEqual(e.cause, { code: "AbortError" }); + strictEqual(e.cause.code, "AbortError"); + } +}); + +// timeout abort handler `settled` guard: after an abort, the later timer firing +// must NOT resolve the already-rejected promise (double-settle is a no-op). +test(`${variant}: timeout abort wins the race; later timer does not resolve`, async (_t) => { + const controller = new AbortController(); + const promise = timeout(30, { signal: controller.signal }); + controller.abort(); + let resolved = false; + let rejected = false; + promise.then( + () => { + resolved = true; + }, + () => { + rejected = true; + }, + ); + // Wait past the original 30ms timer to ensure its callback, if it ran, + // cannot flip an already-settled promise to resolved. + await timeout(60); + strictEqual(rejected, true); + strictEqual(resolved, false); +}); + +test(`${variant}: timeout removes its abort listener after resolving normally`, async (_t) => { + const controller = new AbortController(); + const { signal } = controller; + let removedAbort = 0; + const realRemove = signal.removeEventListener.bind(signal); + signal.removeEventListener = (type, ...rest) => { + if (type === "abort") removedAbort += 1; + return realRemove(type, ...rest); + }; + await timeout(10, { signal }); + // On normal resolution the listener registered for "abort" must be removed + // (kills the `if (signal) signal.removeEventListener("abort", ...)` and the + // "" string mutant in the resolve path). + strictEqual(removedAbort, 1); +}); + +test(`${variant}: timeout removes its abort listener on the abort path`, async (_t) => { + const controller = new AbortController(); + const { signal } = controller; + let removedAbort = 0; + const realRemove = signal.removeEventListener.bind(signal); + signal.removeEventListener = (type, ...rest) => { + if (type === "abort") removedAbort += 1; + return realRemove(type, ...rest); + }; + const promise = timeout(60_000, { signal }); + controller.abort(); + await promise.catch(() => {}); + // The abort handler must remove its own "abort" listener (kills the + // removeEventListener("abort", ...) -> "" string mutant on the abort path). + strictEqual(removedAbort, 1); +}); + +// --- backpressureGauge: duration arithmetic is a SUBTRACTION (Date.now() - +// start), so durations are small/non-negative, not gigantic sums (kills `+`). --- +test(`${variant}: backpressureGauge pause/resume duration is a small subtraction`, async (_t) => { + const transform = createTransformStream(); + const metrics = backpressureGauge({ transform }); + transform.emit("pause"); + await timeout(15); + transform.emit("resume"); + const { duration } = metrics.transform.timeline[0]; + ok(duration >= 0, `duration should be >=0, got ${duration}`); + // A summed (Date.now()+timestamp) value would be ~2*Date.now() (>1e12). + ok(duration < 1e6, `duration should be small, got ${duration}`); +}); + +if (variant === "node") { + // total recorded via 'finish'/'close' for writable sinks, AND the + // double-record guard means total.timestamp is set exactly once. + test(`${variant}: backpressureGauge records writable total exactly once`, async (_t) => { + const writable = createWritableStream(); + const metrics = backpressureGauge({ writable }); + // Fire all three terminal events; guard must record total exactly once. + writable.emit("finish"); + const first = metrics.writable.total.timestamp; + const firstDuration = metrics.writable.total.duration; + strictEqual(typeof first, "number"); + await timeout(30); + writable.emit("close"); + writable.emit("end"); + // Both timestamp AND duration must be unchanged by the later events. The + // recorded timestamp is always startTimestamp (so it can't move), but + // duration is Date.now()-start, so a re-record after a 30ms wait would + // bump duration. The `!= null` guard must prevent that (kills it -> false). + strictEqual(metrics.writable.total.timestamp, first); + strictEqual(metrics.writable.total.duration, firstDuration); + ok(metrics.writable.total.duration >= 0); + ok(metrics.writable.total.duration < 1e6); + }); + + // 'finish' and 'close' events are both wired (kills on("") string mutants): + // a writable that emits only 'finish' (no 'end') must still get a total. + test(`${variant}: backpressureGauge records total on the finish event`, async (_t) => { + const writable = createWritableStream(); + const metrics = backpressureGauge({ writable }); + writable.emit("finish"); + strictEqual(typeof metrics.writable.total.timestamp, "number"); + }); + + test(`${variant}: backpressureGauge records total on the close event`, async (_t) => { + const writable = createWritableStream(); + const metrics = backpressureGauge({ writable }); + writable.emit("close"); + strictEqual(typeof metrics.writable.total.timestamp, "number"); + }); +} + +// --- pipeline derives objectMode from a trailing readable's state and pushes a +// sink built from a (non-empty) streamOptions object. With the readable-last +// case, object chunks must drain without a non-buffer-chunk error. (covers the +// isReadable branch and the streamOptions object literal.) --- +if (variant === "node") { + test(`${variant}: pipeline drains an object-mode readable-last stream`, async (_t) => { + const streams = [ + createReadableStream([{ a: 1 }, { b: 2 }]), + createTransformStream((c, enqueue) => enqueue(c)), + ]; + const out = await withTimeout(pipeline(streams)); + deepStrictEqual(out, {}); + }); +} diff --git a/packages/core/index.web.js b/packages/core/index.web.js index 16b5887..dd6edf9 100644 --- a/packages/core/index.web.js +++ b/packages/core/index.web.js @@ -3,9 +3,15 @@ /* global ReadableStream, TransformStream, WritableStream */ export const pipeline = async (streams, streamOptions = {}) => { + // Work on a copy so appending the terminal writable doesn't mutate the + // caller's array. + streams = [...streams]; // Ensure stream ends with only writable const lastStream = streams[streams.length - 1]; if (isReadable(lastStream)) { + // Web Streams have no objectMode flag, so (unlike the Node build, which + // derives objectMode from the source) the auto-appended terminal sink + // intentionally just forwards the caller's streamOptions. streams.push(createWritableStream(() => {}, streamOptions)); } @@ -76,6 +82,10 @@ export const streamToObject = async (stream, { maxBufferSize } = {}) => { export const streamToString = async (stream, { maxBufferSize } = {}) => { const chunks = []; let size = 0; + // A streaming TextDecoder so multibyte sequences split across byte chunks + // decode correctly. Mirrors Node's Buffer.concat(...).toString() semantics: + // byte chunks are decoded as UTF-8, anything else is String()-ified. + let decoder; for await (const chunk of stream) { if (maxBufferSize != null) { size += chunk?.length ?? chunk?.byteLength ?? 0; @@ -85,16 +95,58 @@ export const streamToString = async (stream, { maxBufferSize } = {}) => { ); } } - chunks.push(chunk); + if (ArrayBuffer.isView(chunk) || chunk instanceof ArrayBuffer) { + // Without { stream: true } a typed array of raw bytes would be + // coerced by Array.join into comma-separated decimal byte codes. + decoder ??= new TextDecoder(); + chunks.push(decoder.decode(chunk, { stream: true })); + } else { + chunks.push(`${chunk}`); + } } + // Flush any bytes buffered by the streaming decoder. + if (decoder) chunks.push(decoder.decode()); return chunks.join(""); }; +// Browser parity for the Node streamToBuffer. There is no Buffer in the web +// runtime, so this returns a concatenated Uint8Array (Node's Buffer is itself +// a Uint8Array, so byte consumers behave identically across builds). +export const streamToBuffer = async (stream, { maxBufferSize } = {}) => { + const value = []; + let size = 0; + for await (const chunk of stream) { + const buf = + chunk instanceof Uint8Array ? chunk : new TextEncoder().encode(chunk); + if (maxBufferSize != null) { + size += buf.byteLength; + if (size > maxBufferSize) { + throw new Error( + `streamToBuffer buffer exceeds maxBufferSize (${maxBufferSize})`, + ); + } + } + value.push(buf); + } + const total = value.reduce((n, b) => n + b.byteLength, 0); + const out = new Uint8Array(total); + let offset = 0; + for (const b of value) { + out.set(b, offset); + offset += b.byteLength; + } + return out; +}; + export const isReadable = (stream) => { + // Short-circuit non-objects so the `.readable` access can't throw on + // null/undefined/primitives (Node's instanceof check safely returns false). + if (stream == null || typeof stream !== "object") return false; return stream instanceof ReadableStream || !!stream.readable; }; export const isWritable = (stream) => { + if (stream == null || typeof stream !== "object") return false; return stream instanceof WritableStream || !!stream.writable; }; @@ -125,13 +177,29 @@ export const createReadableStream = (input, streamOptions = {}) => { if (chunkSize <= 0) throw new Error("chunkSize must be a positive number"); const queued = []; const { readableStrategy } = makeOptions(streamOptions); + // Shared drain logic for start() and pull() so both paths treat a queued + // null identically as EOF. Returns false once it has closed the stream. + const drainQueued = (controller) => { + while (queued.length) { + const chunk = queued.shift(); + if (chunk === null) { + controller.close(); + return false; + } + controller.enqueue(chunk); + } + return true; + }; const stream = new ReadableStream( { async start(controller) { - while (queued.length) { - const chunk = queued.shift(); - controller.enqueue(chunk); - } + // Drain pre-start pushes using the SAME null-as-EOF semantics as + // pull(); the WHATWG spec allows an async start(), so a terminating + // null queued before start runs must still close the stream. + if (!drainQueued(controller)) return; + // No input => manual-push mode (mirrors the node build's undefined + // branch): leave the stream open for stream.push()/pull(). + if (input === undefined) return; if (typeof input === "string") { let position = 0; const length = input.length; @@ -146,8 +214,18 @@ export const createReadableStream = (input, streamOptions = {}) => { controller.enqueue(input[i]); } controller.close(); - } else if (typeof input === "object" && input.byteLength) { - const bytes = new Uint8Array(input.buffer ?? input); + } else if ( + input != null && + typeof input === "object" && + input.byteLength + ) { + // Honor the view's byteOffset/byteLength; constructing + // new Uint8Array(input.buffer) over the whole backing buffer would + // leak adjacent heap (pooled Buffers / .subarray() views) and + // diverge from the Node build. + const bytes = ArrayBuffer.isView(input) + ? new Uint8Array(input.buffer, input.byteOffset, input.byteLength) + : new Uint8Array(input); let position = 0; const length = bytes.byteLength; while (position < length) { @@ -155,23 +233,36 @@ export const createReadableStream = (input, streamOptions = {}) => { position += chunkSize; } controller.close(); - } else if (["function", "object"].includes(typeof input)) { + } else if ( + input != null && + ["function", "object"].includes(typeof input) && + typeof input[Symbol.asyncIterator] === "function" + ) { for await (const chunk of input) { controller.enqueue(chunk); } controller.close(); - } - }, - pull(controller) { - while (queued.length) { - const chunk = queued.shift(); - if (chunk === null) { - controller.close(); - } else { + } else if ( + input != null && + typeof input === "object" && + typeof input[Symbol.iterator] === "function" + ) { + for (const chunk of input) { controller.enqueue(chunk); } + controller.close(); + } else { + // number/boolean/symbol/null/non-iterable object: a missing branch + // previously left the stream open forever (a silent hang). Error + // promptly to match Node's immediate throw. + controller.error( + new TypeError("createReadableStream: unsupported input type"), + ); } }, + pull(controller) { + drainQueued(controller); + }, }, readableStrategy, ); @@ -194,27 +285,50 @@ export const createPassThroughStream = (passThrough, flush, streamOptions) => { } const { signal } = streamOptions ?? {}; const { writableStrategy, readableStrategy } = makeOptions(streamOptions); + // Track the abort listener so we can remove it once the stream settles; + // otherwise a shared signal accumulates a listener per constructed stream. + // cleanup() is idempotent and is invoked from EVERY terminal path (clean + // flush, downstream cancel, and a thrown transform/flush callback), not just + // the clean flush — otherwise an errored/cancelled stream leaks its listener. + let onAbort; + const cleanup = () => { + if (onAbort) { + signal.removeEventListener("abort", onAbort); + onAbort = undefined; + } + }; return new TransformStream( { start(controller) { if (signal) { - signal.addEventListener("abort", () => { + onAbort = () => controller.error( signal.reason ?? new DOMException("Aborted", "AbortError"), ); - }); + signal.addEventListener("abort", onAbort, { once: true }); } }, async transform(chunk, controller) { - await passThrough(chunk); + try { + await passThrough(chunk); + } catch (e) { + cleanup(); + throw e; + } controller.enqueue(chunk); }, async flush(controller) { + cleanup(); if (flush) { await flush(); } controller.terminate(); }, + // Called when the readable side is cancelled or the writable side is + // aborted/errored (e.g. a downstream sink errors). + cancel() { + cleanup(); + }, }, writableStrategy, readableStrategy, @@ -229,24 +343,39 @@ export const createTransformStream = (transform, flush, streamOptions) => { } const { signal } = streamOptions ?? {}; const { writableStrategy, readableStrategy } = makeOptions(streamOptions); + // See createPassThroughStream for why cleanup() is wired into every terminal + // path rather than only the clean flush. + let onAbort; + const cleanup = () => { + if (onAbort) { + signal.removeEventListener("abort", onAbort); + onAbort = undefined; + } + }; return new TransformStream( { start(controller) { if (signal) { - signal.addEventListener("abort", () => { + onAbort = () => controller.error( signal.reason ?? new DOMException("Aborted", "AbortError"), ); - }); + signal.addEventListener("abort", onAbort, { once: true }); } }, async transform(chunk, controller) { const enqueue = (chunk) => { controller.enqueue(chunk); }; - await transform(chunk, enqueue); + try { + await transform(chunk, enqueue); + } catch (e) { + cleanup(); + throw e; + } }, async flush(controller) { + cleanup(); if (flush) { const enqueue = (chunk) => { controller.enqueue(chunk); @@ -255,6 +384,9 @@ export const createTransformStream = (transform, flush, streamOptions) => { } controller.terminate(); }, + cancel() { + cleanup(); + }, }, writableStrategy, readableStrategy, @@ -269,25 +401,45 @@ export const createWritableStream = (write, close, streamOptions) => { } const { signal } = streamOptions ?? {}; const { writableStrategy } = makeOptions(streamOptions); + // See createPassThroughStream for why cleanup() is wired into every terminal + // path (clean close, abort, and a thrown write/close callback). + let onAbort; + const cleanup = () => { + if (onAbort) { + signal.removeEventListener("abort", onAbort); + onAbort = undefined; + } + }; return new WritableStream( { start(controller) { if (signal) { - signal.addEventListener("abort", () => { + onAbort = () => controller.error( signal.reason ?? new DOMException("Aborted", "AbortError"), ); - }); + signal.addEventListener("abort", onAbort, { once: true }); } }, async write(chunk) { - await write(chunk); + try { + await write(chunk); + } catch (e) { + cleanup(); + throw e; + } }, async close() { + cleanup(); if (close) { await close(); } }, + // Called when the stream is aborted (signal fires or a downstream error + // propagates), where close() would never run. + abort() { + cleanup(); + }, }, writableStrategy, ); diff --git a/packages/core/package.json b/packages/core/package.json index 7c9e3dc..af06b60 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -39,6 +39,7 @@ "scripts": { "test": "npm run test:unit", "test:unit": "node --test", + "test:mutation": "cd ../.. && MUTATE_PACKAGE=\"$(basename \"$OLDPWD\")\" stryker run", "test:benchmark": "node __benchmarks__/index.js" }, "license": "MIT", diff --git a/packages/csv/README.md b/packages/csv/README.md index 84c4670..700fd93 100644 --- a/packages/csv/README.md +++ b/packages/csv/README.md @@ -1,6 +1,6 @@CSV parsing and formatting streams.
@@ -18,10 +18,10 @@
-
+
-
+
You can read the documentation at: https://datastream.js.org
diff --git a/packages/csv/index.test.js b/packages/csv/index.test.js index e11aaaa..80c9d4c 100644 --- a/packages/csv/index.test.js +++ b/packages/csv/index.test.js @@ -1773,3 +1773,1528 @@ test(`${variant}: csvCoerceValuesStream should handle uppercase boolean`, async deepStrictEqual(output, [{ val: true, val2: false }]); }); + +// *** FINDING: fast-path-too-many-columns-merged *** // +test(`${variant}: csvParseStream should not merge extra columns in fast unquoted path`, async (_t) => { + // A row with MORE fields than the established numCols must keep all + // fields separate (not collapse the surplus into the last field). + const streams = [ + createReadableStream("a,b,c\r\n1,2,3,4,5\r\n"), + csvParseStream(), + ]; + const stream = pipejoin(streams); + const output = await streamToArray(stream); + + deepStrictEqual(output, [ + ["a", "b", "c"], + ["1", "2", "3", "4", "5"], + ]); +}); + +test(`${variant}: csvParseStream fast and slow paths agree on over-long rows`, async (_t) => { + // Identical row data must parse identically whether or not a quote char + // appears elsewhere in the buffer (quote presence picks fast vs slow path). + const fastStreams = [ + createReadableStream("a,b,c\r\n1,2,3,4,5\r\n"), + csvParseStream(), + ]; + const slowStreams = [ + createReadableStream('a,b,c\r\n1,2,3,4,5\r\n"x",y,z\r\n'), + csvParseStream(), + ]; + const fast = await streamToArray(pipejoin(fastStreams)); + const slow = await streamToArray(pipejoin(slowStreams)); + + deepStrictEqual(fast[1], ["1", "2", "3", "4", "5"]); + deepStrictEqual(slow[1], ["1", "2", "3", "4", "5"]); +}); + +test(`${variant}: csvParseStream over-long rows are detectable as malformed`, async (_t) => { + const filter = csvRemoveMalformedRowsStream(); + const streams = [ + createReadableStream("a,b,c\r\n1,2,3,4,5\r\n6,7,8\r\n"), + csvParseStream(), + filter, + ]; + const stream = pipejoin(streams); + const output = await streamToArray(stream); + + deepStrictEqual(output, [ + ["a", "b", "c"], + ["6", "7", "8"], + ]); + deepStrictEqual(filter.result().value.MalformedRow.idx, [1]); +}); + +// *** FINDING: detect-quote-scans-whole-buffer *** // +test(`${variant}: csvDetectDelimitersStream should not detect apostrophe in data as quote char`, async (_t) => { + const detect = csvDetectDelimitersStream(); + const streams = [ + createReadableStream("quote,author\n'twas the night,Moore\nhello,World\n"), + detect, + ]; + await pipeline(streams); + + strictEqual(detect.result().value.quoteChar, '"'); +}); + +test(`${variant}: csvParseStream should parse data with apostrophes after auto-detect`, async (_t) => { + const detect = csvDetectDelimitersStream(); + const parse = csvParseStream({ + delimiterChar: () => detect.result().value.delimiterChar, + newlineChar: () => detect.result().value.newlineChar, + quoteChar: () => detect.result().value.quoteChar, + }); + const streams = [ + createReadableStream("quote,author\n'twas the night,Moore\nhello,World\n"), + detect, + parse, + ]; + const stream = pipejoin(streams); + const output = await streamToArray(stream); + + deepStrictEqual(output, [ + ["quote", "author"], + ["'twas the night", "Moore"], + ["hello", "World"], + ]); +}); + +// *** FINDING: custom-escape-not-inverse-of-format *** // +test(`${variant}: csvFormatStream/csvParseStream round-trip preserves escape char with custom escapeChar`, async (_t) => { + const value = 'a"b\\c'; + const formatStreams = [ + createReadableStream([[value, "next"]]), + csvFormatStream({ escapeChar: "\\" }), + ]; + const formatted = await streamToString(pipejoin(formatStreams)); + + const parseStreams = [ + createReadableStream(formatted), + csvParseStream({ escapeChar: "\\" }), + ]; + const parsed = await streamToArray(pipejoin(parseStreams)); + + deepStrictEqual(parsed, [[value, "next"]]); +}); + +// *** FINDING: custom-escape-lookback-parity *** // +test(`${variant}: csvParseStream should treat even run of escape chars as unescaped closing quote`, async (_t) => { + // "a\\" => field value is a\ (escaped backslash), then the closing quote + // is real, so the delimiter and following field are not swallowed. + const streams = [ + createReadableStream('"a\\\\",b\r\nc,d\r\n'), + csvParseStream({ escapeChar: "\\" }), + ]; + const stream = pipejoin(streams); + const output = await streamToArray(stream); + + deepStrictEqual(output, [ + ["a\\", "b"], + ["c", "d"], + ]); +}); + +// *** FINDING: detect-header-naive-newline-split *** // +test(`${variant}: csvDetectHeaderStream should respect quoted newline in header field`, async (_t) => { + const headers = csvDetectHeaderStream({ newlineChar: "\n" }); + const streams = [ + createReadableStream('"col\nwith newline",col2\nval1,val2\n'), + headers, + ]; + const stream = pipejoin(streams); + const output = await streamToString(stream); + + deepStrictEqual(headers.result().value.header, ["col\nwith newline", "col2"]); + strictEqual(output, "val1,val2\n"); +}); + +test(`${variant}: csvDetectHeaderStream should respect custom-escape quoted newline in header`, async (_t) => { + const headers = csvDetectHeaderStream({ + newlineChar: "\n", + escapeChar: "\\", + }); + const streams = [ + createReadableStream('"col\\"x\nnext",col2\nval1,val2\n'), + headers, + ]; + const stream = pipejoin(streams); + const output = await streamToString(stream); + + deepStrictEqual(headers.result().value.header, ['col"x\nnext', "col2"]); + strictEqual(output, "val1,val2\n"); +}); + +// *** FINDING: autocoerce-invalid-date *** // +test(`${variant}: csvCoerceValuesStream should keep invalid date string as string`, async (_t) => { + const streams = [ + createReadableStream([{ d: "2024-13-99" }]), + csvCoerceValuesStream(), + ]; + const stream = pipejoin(streams); + const output = await streamToArray(stream); + + deepStrictEqual(output, [{ d: "2024-13-99" }]); +}); + +// *** FINDING: csvArrayToObject-proto-header-drops-column *** // +test(`${variant}: csvArrayToObject should keep a __proto__ header as an own data property`, async (_t) => { + const streams = [ + createReadableStream([["polluted", "ok"]]), + csvArrayToObject({ headers: ["__proto__", "safe"] }), + ]; + const stream = pipejoin(streams); + const output = await streamToArray(stream); + + strictEqual(output.length, 1); + const row = output[0]; + // The __proto__ column must be stored as an own data property, not lost. + ok(Object.hasOwn(row, "__proto__")); + strictEqual(row.__proto__, "polluted"); + strictEqual(row.safe, "ok"); +}); + +// =================================================================== +// Mutation-killing tests (added to raise mutation score) +// =================================================================== + +// --- csvFormatStream: scanNeedsQuote first-char triggers --- +test(`${variant}: csvFormatStream should quote field with leading space`, async (_t) => { + const streams = [createReadableStream([[" lead", "ok"]]), csvFormatStream()]; + const output = await streamToString(pipejoin(streams)); + strictEqual(output, '" lead",ok\r\n'); +}); + +test(`${variant}: csvFormatStream should quote field with trailing space`, async (_t) => { + const streams = [createReadableStream([["trail ", "ok"]]), csvFormatStream()]; + const output = await streamToString(pipejoin(streams)); + strictEqual(output, '"trail ",ok\r\n'); +}); + +test(`${variant}: csvFormatStream should quote field with leading BOM`, async (_t) => { + const streams = [createReadableStream([["bom", "ok"]]), csvFormatStream()]; + const output = await streamToString(pipejoin(streams)); + strictEqual(output, '"bom",ok\r\n'); +}); + +test(`${variant}: csvFormatStream should not quote plain interior space`, async (_t) => { + const streams = [createReadableStream([["a b c", "ok"]]), csvFormatStream()]; + const output = await streamToString(pipejoin(streams)); + strictEqual(output, "a b c,ok\r\n"); +}); + +test(`${variant}: csvFormatStream should quote field containing carriage return`, async (_t) => { + const streams = [createReadableStream([["a\rb", "ok"]]), csvFormatStream()]; + const output = await streamToString(pipejoin(streams)); + strictEqual(output, '"a\rb",ok\r\n'); +}); + +// --- csvFormatStream: multi-char delimiter scan path --- +test(`${variant}: csvFormatStream should quote value containing multi-char delimiter`, async (_t) => { + const streams = [ + createReadableStream([["a::b", "plain"]]), + csvFormatStream({ delimiterChar: "::" }), + ]; + const output = await streamToString(pipejoin(streams)); + strictEqual(output, '"a::b"::plain\r\n'); +}); + +test(`${variant}: csvFormatStream multi-char delimiter should quote on quote char`, async (_t) => { + const streams = [ + createReadableStream([['has"quote', "plain"]]), + csvFormatStream({ delimiterChar: "::" }), + ]; + const output = await streamToString(pipejoin(streams)); + strictEqual(output, '"has""quote"::plain\r\n'); +}); + +test(`${variant}: csvFormatStream multi-char delimiter should not quote plain value`, async (_t) => { + const streams = [ + createReadableStream([["plain", "value"]]), + csvFormatStream({ delimiterChar: "::" }), + ]; + const output = await streamToString(pipejoin(streams)); + strictEqual(output, "plain::value\r\n"); +}); + +// --- csvFormatStream: wrapQuote with custom escape --- +test(`${variant}: csvFormatStream custom escape should escape escape char and quote char`, async (_t) => { + // escapeChar=\, value contains both \ and "; backslash doubled, quote -> \" + const streams = [ + createReadableStream([['a"b\\c', "ok"]]), + csvFormatStream({ escapeChar: "\\" }), + ]; + const output = await streamToString(pipejoin(streams)); + strictEqual(output, '"a\\"b\\\\c",ok\r\n'); +}); + +test(`${variant}: csvFormatStream custom escape should escape only escape char when no quote`, async (_t) => { + const streams = [ + createReadableStream([["a\\b,c", "ok"]]), + csvFormatStream({ escapeChar: "\\" }), + ]; + const output = await streamToString(pipejoin(streams)); + // contains delimiter so quoted; backslash doubled; no quote char present + strictEqual(output, '"a\\\\b,c",ok\r\n'); +}); + +// --- csvFormatStream: Date and number/non-string formatting (formatRowSlow) --- +test(`${variant}: csvFormatStream should format Date as ISO string`, async (_t) => { + const d = new Date("2024-01-15T10:30:00.000Z"); + const streams = [createReadableStream([[d, "ok"]]), csvFormatStream()]; + const output = await streamToString(pipejoin(streams)); + strictEqual(output, "2024-01-15T10:30:00.000Z,ok\r\n"); +}); + +test(`${variant}: csvFormatStream should format number via String`, async (_t) => { + const streams = [createReadableStream([[42, 3.14]]), csvFormatStream()]; + const output = await streamToString(pipejoin(streams)); + strictEqual(output, "42,3.14\r\n"); +}); + +test(`${variant}: csvFormatStream should format null and undefined as empty`, async (_t) => { + const streams = [ + createReadableStream([[null, undefined, "x"]]), + csvFormatStream(), + ]; + const output = await streamToString(pipejoin(streams)); + strictEqual(output, ",,x\r\n"); +}); + +test(`${variant}: csvFormatStream should format boolean via String in slow path`, async (_t) => { + // boolean true forces slow path (non-string); String(true) === "true" + const streams = [createReadableStream([[true, false]]), csvFormatStream()]; + const output = await streamToString(pipejoin(streams)); + strictEqual(output, "true,false\r\n"); +}); + +test(`${variant}: csvFormatStream should quote number-derived string needing quote`, async (_t) => { + // A negative number stringifies to "-42" which starts with '-', a quote trigger + const streams = [createReadableStream([[-42, "ok"]]), csvFormatStream()]; + const output = await streamToString(pipejoin(streams)); + strictEqual(output, '"-42",ok\r\n'); +}); + +// --- csvFormatStream: batch boundary (>= 64 rows flushed mid-stream) --- +test(`${variant}: csvFormatStream should emit batch at 64 rows then flush remainder`, async (_t) => { + const rows = []; + for (let i = 0; i < 70; i++) rows.push([String(i), "x"]); + const streams = [createReadableStream(rows), csvFormatStream()]; + const output = await streamToString(pipejoin(streams)); + const lines = output.split("\r\n").filter((l) => l.length > 0); + strictEqual(lines.length, 70); + strictEqual(lines[0], "0,x"); + strictEqual(lines[69], "69,x"); +}); + +// --- csvFormatStream: custom newlineChar separator --- +test(`${variant}: csvFormatStream should use custom newlineChar`, async (_t) => { + const streams = [ + createReadableStream([ + ["1", "2"], + ["3", "4"], + ]), + csvFormatStream({ newlineChar: "\n" }), + ]; + const output = await streamToString(pipejoin(streams)); + strictEqual(output, "1,2\n3,4\n"); +}); + +// --- csvFormatStream: custom quoteChar --- +test(`${variant}: csvFormatStream should use custom quoteChar`, async (_t) => { + const streams = [ + createReadableStream([["a,b", "ok"]]), + csvFormatStream({ quoteChar: "'" }), + ]; + const output = await streamToString(pipejoin(streams)); + strictEqual(output, "'a,b',ok\r\n"); +}); + +// --- csvFormatStream multi-char delimiter: trailing space / CR / LF triggers --- +test(`${variant}: csvFormatStream multi-char delimiter should quote trailing space`, async (_t) => { + const streams = [ + createReadableStream([["trail ", "ok"]]), + csvFormatStream({ delimiterChar: "::" }), + ]; + const output = await streamToString(pipejoin(streams)); + strictEqual(output, '"trail "::ok\r\n'); +}); + +test(`${variant}: csvFormatStream multi-char delimiter should quote on newline`, async (_t) => { + const streams = [ + createReadableStream([["a\nb", "ok"]]), + csvFormatStream({ delimiterChar: "::" }), + ]; + const output = await streamToString(pipejoin(streams)); + strictEqual(output, '"a\nb"::ok\r\n'); +}); + +test(`${variant}: csvFormatStream multi-char delimiter should quote on carriage return`, async (_t) => { + const streams = [ + createReadableStream([["a\rb", "ok"]]), + csvFormatStream({ delimiterChar: "::" }), + ]; + const output = await streamToString(pipejoin(streams)); + strictEqual(output, '"a\rb"::ok\r\n'); +}); + +test(`${variant}: csvFormatStream single-char delimiter should quote on linefeed only`, async (_t) => { + const streams = [createReadableStream([["a\nb", "ok"]]), csvFormatStream()]; + const output = await streamToString(pipejoin(streams)); + strictEqual(output, '"a\nb",ok\r\n'); +}); + +// --- csvCoerceValuesStream: number regex exponent shape --- +test(`${variant}: csvCoerceValuesStream should coerce exponent with explicit sign and multi-digit exponent`, async (_t) => { + const streams = [ + createReadableStream([{ a: "1e+10", b: "2e-05", c: "1.5E3" }]), + csvCoerceValuesStream(), + ]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [{ a: 1e10, b: 2e-5, c: 1500 }]); +}); + +test(`${variant}: csvCoerceValuesStream should keep malformed exponent as string`, async (_t) => { + const streams = [ + createReadableStream([{ a: "1e", b: "1e+", c: "1.2.3" }]), + csvCoerceValuesStream(), + ]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [{ a: "1e", b: "1e+", c: "1.2.3" }]); +}); + +test(`${variant}: csvCoerceValuesStream should not coerce string with trailing non-number text`, async (_t) => { + const streams = [ + createReadableStream([{ a: "12abc", d: "2024-01-15extra" }]), + csvCoerceValuesStream(), + ]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [{ a: "12abc", d: "2024-01-15extra" }]); +}); + +test(`${variant}: csvCoerceValuesStream should not coerce date missing leading anchor`, async (_t) => { + const streams = [ + createReadableStream([{ d: "x2024-01-15" }]), + csvCoerceValuesStream(), + ]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [{ d: "x2024-01-15" }]); +}); + +test(`${variant}: csvCoerceValuesStream should coerce date with time and timezone offset`, async (_t) => { + const streams = [ + createReadableStream([{ d: "2024-01-15T10:30:00+05:30" }]), + csvCoerceValuesStream(), + ]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [{ d: new Date("2024-01-15T10:30:00+05:30") }]); +}); + +// --- csvCoerceValuesStream: boolean first-char/length gating in autoCoerce --- +test(`${variant}: csvCoerceValuesStream should not treat 4-char non-true string as boolean`, async (_t) => { + const streams = [ + createReadableStream([{ a: "trUE", b: "tree", c: "True" }]), + csvCoerceValuesStream(), + ]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [{ a: true, b: "tree", c: true }]); +}); + +test(`${variant}: csvCoerceValuesStream should not coerce non-t/f boolean-length words`, async (_t) => { + const streams = [ + createReadableStream([{ a: "yes", b: "nope" }]), + csvCoerceValuesStream(), + ]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [{ a: "yes", b: "nope" }]); +}); + +test(`${variant}: csvCoerceValuesStream should not coerce truthy when length is wrong`, async (_t) => { + const streams = [ + createReadableStream([{ a: "truer", b: "falsey" }]), + csvCoerceValuesStream(), + ]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [{ a: "truer", b: "falsey" }]); +}); + +test(`${variant}: csvCoerceValuesStream should return null for empty string auto-coerce`, async (_t) => { + const streams = [createReadableStream([{ a: "" }]), csvCoerceValuesStream()]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [{ a: null }]); +}); + +test(`${variant}: csvCoerceValuesStream should coerce single-digit zero and nine`, async (_t) => { + const streams = [ + createReadableStream([{ a: "0", b: "9" }]), + csvCoerceValuesStream(), + ]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [{ a: 0, b: 9 }]); +}); + +test(`${variant}: csvCoerceValuesStream should keep plain non-numeric non-bool string`, async (_t) => { + const streams = [ + createReadableStream([{ a: "hello", b: "world" }]), + csvCoerceValuesStream(), + ]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [{ a: "hello", b: "world" }]); +}); + +// --- coerceToType boolean: string vs non-string --- +test(`${variant}: csvCoerceValuesStream explicit boolean should lowercase compare string`, async (_t) => { + const streams = [ + createReadableStream([{ a: "TRUE", b: "no", c: "true" }]), + csvCoerceValuesStream({ + columns: { a: "boolean", b: "boolean", c: "boolean" }, + }), + ]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [{ a: true, b: false, c: true }]); +}); + +test(`${variant}: csvCoerceValuesStream explicit boolean should use Boolean for non-string`, async (_t) => { + const streams = [ + createReadableStream([{ a: 1, b: 0 }]), + csvCoerceValuesStream({ columns: { a: "boolean", b: "boolean" } }), + ]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [{ a: true, b: false }]); +}); + +// --- coerceToType json with array --- +test(`${variant}: csvCoerceValuesStream explicit json should parse array`, async (_t) => { + const streams = [ + createReadableStream([{ a: "[1,2,3]" }]), + csvCoerceValuesStream({ columns: { a: "json" } }), + ]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [{ a: [1, 2, 3] }]); +}); + +// --- coerceToType default (unknown type) passthrough --- +test(`${variant}: csvCoerceValuesStream unknown column type should pass value unchanged`, async (_t) => { + const streams = [ + createReadableStream([{ a: "raw" }]), + csvCoerceValuesStream({ columns: { a: "string" } }), + ]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [{ a: "raw" }]); +}); + +// --- coerceToType number coerces hex-like and keeps decimals --- +test(`${variant}: csvCoerceValuesStream explicit number coerces decimal and hex`, async (_t) => { + const streams = [ + createReadableStream([{ a: "3.14", b: "0x1F" }]), + csvCoerceValuesStream({ columns: { a: "number", b: "number" } }), + ]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [{ a: 3.14, b: 31 }]); +}); + +// --- csvDetectDelimitersStream: quote bracketing precision --- +// A quote candidate must OPEN at a field start AND CLOSE at a field end to be +// recognised. The following exercise each isFieldStart / isFieldEnd branch. + +test(`${variant}: csvDetectDelimitersStream should detect quote opening at text start`, async (_t) => { + // "'a'" opens at i===0 and closes before a delimiter + const detect = csvDetectDelimitersStream(); + const streams = [createReadableStream("'a',b\n1,2\n"), detect]; + await pipeline(streams); + strictEqual(detect.result().value.quoteChar, "'"); +}); + +test(`${variant}: csvDetectDelimitersStream should detect quote after delimiter and closing at line end`, async (_t) => { + // second field 'b' opens after a comma and closes before the newline (LF) + const detect = csvDetectDelimitersStream(); + const streams = [createReadableStream("a,'b'\n1,2\n"), detect]; + await pipeline(streams); + strictEqual(detect.result().value.quoteChar, "'"); +}); + +test(`${variant}: csvDetectDelimitersStream should detect quote closing before CR`, async (_t) => { + // quoted field closes right before \r in a CRLF newline + const detect = csvDetectDelimitersStream(); + const streams = [createReadableStream("'a',b\r\n1,2\r\n"), detect]; + await pipeline(streams); + strictEqual(detect.result().value.quoteChar, "'"); + strictEqual(detect.result().value.newlineChar, "\r\n"); +}); + +test(`${variant}: csvDetectDelimitersStream should detect quote opening after newline`, async (_t) => { + // The only properly-bracketed quote is on row 2, opening right after the LF + const detect = csvDetectDelimitersStream({ chunkSize: 0 }); + const streams = [createReadableStream("a,b\n'c',d\n"), detect]; + await pipeline(streams); + strictEqual(detect.result().value.quoteChar, "'"); +}); + +test(`${variant}: csvDetectDelimitersStream should NOT detect quote that never closes at a field end`, async (_t) => { + // 'x is a field-start apostrophe with no closing quote at any field end. + // A later lone apostrophe sits mid-field (after a letter, not a boundary), + // so it neither opens nor closes a field -> default double-quote. + const detect = csvDetectDelimitersStream(); + const streams = [ + createReadableStream("name,note\n'x,it's fine\nhello,world\n"), + detect, + ]; + await pipeline(streams); + strictEqual(detect.result().value.quoteChar, '"'); +}); + +test(`${variant}: csvDetectDelimitersStream should set escapeChar equal to detected quoteChar`, async (_t) => { + const detect = csvDetectDelimitersStream(); + const streams = [createReadableStream("'a','b'\n1,2\n"), detect]; + await pipeline(streams); + strictEqual(detect.result().value.escapeChar, "'"); + strictEqual(detect.result().value.quoteChar, "'"); +}); + +test(`${variant}: csvDetectDelimitersStream should pick first delimiter by precedence (tab over comma)`, async (_t) => { + // Header contains BOTH a tab and a comma; detection order is [tab,pipe,semi,comma] + const detect = csvDetectDelimitersStream(); + const streams = [createReadableStream("a\tb,c\n1\t2,3\n"), detect]; + await pipeline(streams); + strictEqual(detect.result().value.delimiterChar, "\t"); +}); + +test(`${variant}: csvDetectDelimitersStream should pick pipe over semicolon and comma`, async (_t) => { + const detect = csvDetectDelimitersStream(); + const streams = [createReadableStream("a|b;c,d\n1|2;3,4\n"), detect]; + await pipeline(streams); + strictEqual(detect.result().value.delimiterChar, "|"); +}); + +test(`${variant}: csvDetectDelimitersStream should pick semicolon over comma`, async (_t) => { + const detect = csvDetectDelimitersStream(); + const streams = [createReadableStream("a;b,c\n1;2,3\n"), detect]; + await pipeline(streams); + strictEqual(detect.result().value.delimiterChar, ";"); +}); + +test(`${variant}: csvDetectDelimitersStream should default to double-quote when no quote present`, async (_t) => { + const detect = csvDetectDelimitersStream(); + const streams = [createReadableStream("a,b,c\n1,2,3\n"), detect]; + await pipeline(streams); + strictEqual(detect.result().value.quoteChar, '"'); +}); + +test(`${variant}: csvDetectDelimitersStream should set newlineChar from header match`, async (_t) => { + const detect = csvDetectDelimitersStream(); + const streams = [createReadableStream("a,b\r1,2\r"), detect]; + await pipeline(streams); + strictEqual(detect.result().value.newlineChar, "\r"); +}); + +// --- csvQuotedParser direct: numCols, escapes, tail, multi-char newline --- +test(`${variant}: csvQuotedParser establishes numCols from first row`, (_t) => { + const result = csvQuotedParser("a,b,c\r\n1,2,3\r\n"); + strictEqual(result.numCols, 3); + deepStrictEqual(result.rows, [ + ["a", "b", "c"], + ["1", "2", "3"], + ]); +}); + +test(`${variant}: csvQuotedParser returns tail for incomplete trailing row`, (_t) => { + const result = csvQuotedParser("a,b\r\n1,2\r\n3,4"); + deepStrictEqual(result.rows, [ + ["a", "b"], + ["1", "2"], + ]); + strictEqual(result.tail, "3,4"); +}); + +test(`${variant}: csvQuotedParser preserves quoted field with escaped quotes (no escapes flag)`, (_t) => { + const result = csvQuotedParser('"plain",x\r\n'); + deepStrictEqual(result.rows, [["plain", "x"]]); +}); + +test(`${variant}: csvQuotedParser keeps doubled-quote escapes`, (_t) => { + const result = csvQuotedParser('"a""b","c"\r\n'); + deepStrictEqual(result.rows, [['a"b', "c"]]); +}); + +test(`${variant}: csvQuotedParser handles short quoted row truncating to fi`, (_t) => { + // numCols established as 3, second row has a single quoted field -> length 1 + const result = csvQuotedParser('a,b,c\r\n"d"\r\n'); + deepStrictEqual(result.rows[0], ["a", "b", "c"]); + strictEqual(result.rows[1].length, 1); + deepStrictEqual(result.rows[1], ["d"]); +}); + +test(`${variant}: csvQuotedParser handles multi-char newline length>2`, (_t) => { + const result = csvQuotedParser("a,b||~c,d||~", { newlineChar: "||~" }, true); + deepStrictEqual(result.rows, [ + ["a", "b"], + ["c", "d"], + ]); +}); + +test(`${variant}: csvQuotedParser CRLF requires both chars (lone CR does not split)`, (_t) => { + // With CRLF newline, a lone \r mid-field must NOT terminate the row. + const result = csvQuotedParser('"a\rb",c\r\n', { newlineChar: "\r\n" }, true); + deepStrictEqual(result.rows, [["a\rb", "c"]]); +}); + +test(`${variant}: csvQuotedParser tracks unterminated quote error on flush`, (_t) => { + const result = csvQuotedParser('"abc', {}, true); + deepStrictEqual(result.rows, [["abc"]]); + ok(result.errors.UnterminatedQuote); + deepStrictEqual(result.errors.UnterminatedQuote.idx, [0]); +}); + +test(`${variant}: csvQuotedParser unterminated quote not flushing returns tail`, (_t) => { + const result = csvQuotedParser('a,b\r\n"abc', {}, false); + deepStrictEqual(result.rows, [["a", "b"]]); + strictEqual(result.tail, '"abc'); +}); + +test(`${variant}: csvQuotedParser custom escape unterminated keeps unescaped value on flush`, (_t) => { + const result = csvQuotedParser('"a\\"b', { escapeChar: "\\" }, true); + deepStrictEqual(result.rows, [['a"b']]); + ok(result.errors.UnterminatedQuote); +}); + +test(`${variant}: csvQuotedParser custom escape even run is real closing quote`, (_t) => { + const result = csvQuotedParser('"a\\\\",b\r\n', { escapeChar: "\\" }, true); + deepStrictEqual(result.rows, [["a\\", "b"]]); +}); + +test(`${variant}: csvQuotedParser custom escape odd run escapes the quote`, (_t) => { + const result = csvQuotedParser('"a\\"b",c\r\n', { escapeChar: "\\" }, true); + deepStrictEqual(result.rows, [['a"b', "c"]]); +}); + +// --- field size limit --- +test(`${variant}: csvParseStream should throw when quoted field exceeds fieldMaxSize`, async (_t) => { + // field length 11 (> 10) but buffer (17) stays under the 2x safety limit (20) + const val = "x".repeat(11); + const streams = [ + createReadableStream(`"${val}",y\r\n`), + csvParseStream({ fieldMaxSize: 10 }), + ]; + let threw = false; + try { + await pipeline(streams); + } catch (e) { + threw = true; + ok(/CSV field size/.test(e.message)); + } + ok(threw); +}); + +test(`${variant}: csvParseStream should accept quoted field at exactly fieldMaxSize`, async (_t) => { + const val = "x".repeat(10); + const streams = [ + createReadableStream(`"${val}",y\r\n`), + csvParseStream({ fieldMaxSize: 10 }), + ]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [[val, "y"]]); +}); + +test(`${variant}: csvParseStream should throw when custom-escape quoted field exceeds fieldMaxSize`, async (_t) => { + const val = "x".repeat(11); + const streams = [ + createReadableStream(`"${val}",y\r\n`), + csvParseStream({ escapeChar: "\\", fieldMaxSize: 10 }), + ]; + let threw = false; + try { + await pipeline(streams); + } catch (e) { + threw = true; + ok(/CSV field size/.test(e.message)); + } + ok(threw); +}); + +test(`${variant}: csvParseStream should throw on buffer exceeding safety limit`, async (_t) => { + // An unterminated quote that grows the buffer beyond fieldMaxSize*2 throws. + const big = `"${"x".repeat(60)}`; + const streams = [ + createReadableStream(big), + csvParseStream({ fieldMaxSize: 10, chunkSize: 1 }), + ]; + let threw = false; + try { + await pipeline(streams); + } catch (e) { + threw = true; + ok(/safety limit/.test(e.message)); + } + ok(threw); +}); + +// --- fast unquoted path: too-few columns (malformed) and surplus --- +test(`${variant}: csvParseStream fast path keeps too-few-column row as-is`, async (_t) => { + const streams = [ + createReadableStream("a,b,c\r\nd,e\r\nf,g,h\r\n"), + csvParseStream(), + ]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [ + ["a", "b", "c"], + ["d", "e"], + ["f", "g", "h"], + ]); +}); + +test(`${variant}: csvParseStream fast path keeps multiple full rows`, async (_t) => { + const streams = [ + createReadableStream("a,b\r\n1,2\r\n3,4\r\n5,6\r\n"), + csvParseStream(), + ]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [ + ["a", "b"], + ["1", "2"], + ["3", "4"], + ["5", "6"], + ]); +}); + +test(`${variant}: csvParseStream fast path partial last row without newline`, async (_t) => { + const streams = [createReadableStream("a,b\r\n1,2\r\n3,4"), csvParseStream()]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [ + ["a", "b"], + ["1", "2"], + ["3", "4"], + ]); +}); + +// --- multi-char newline (length 2 custom, not CRLF) --- +test(`${variant}: csvParseStream supports 2-char custom newline`, async (_t) => { + const streams = [ + createReadableStream("a,b~|1,2~|"), + csvParseStream({ newlineChar: "~|" }), + ]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [ + ["a", "b"], + ["1", "2"], + ]); +}); + +test(`${variant}: csvParseStream 2-char newline does not split on partial match`, async (_t) => { + // A lone '~' that is not followed by '|' must stay inside the field. + const streams = [ + createReadableStream('"a~b",c~|d,e~|'), + csvParseStream({ newlineChar: "~|" }), + ]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [ + ["a~b", "c"], + ["d", "e"], + ]); +}); + +// --- unquoted parser numCols + multi-row --- +test(`${variant}: csvUnquotedParser sets numCols and parses many rows`, (_t) => { + const result = csvUnquotedParser("a,b\r\n1,2\r\n3,4\r\n"); + strictEqual(result.numCols, 2); + deepStrictEqual(result.rows, [ + ["a", "b"], + ["1", "2"], + ["3", "4"], + ]); +}); + +test(`${variant}: csvUnquotedParser custom delimiter and newline`, (_t) => { + const result = csvUnquotedParser("a;b\nc;d\n", { + delimiterChar: ";", + newlineChar: "\n", + }); + deepStrictEqual(result.rows, [ + ["a", "b"], + ["c", "d"], + ]); +}); + +// --- csvDetectHeaderStream / findRowEnd quote & escape aware row scan --- +test(`${variant}: csvDetectHeaderStream multi-char delimiter splits header`, async (_t) => { + const headers = csvDetectHeaderStream({ + newlineChar: "\n", + delimiterChar: "::", + }); + const streams = [createReadableStream("a::b::c\n1::2::3\n"), headers]; + const output = await streamToString(pipejoin(streams)); + deepStrictEqual(headers.result().value.header, ["a", "b", "c"]); + strictEqual(output, "1::2::3\n"); +}); + +test(`${variant}: csvDetectHeaderStream respects delimiter inside quoted header field`, async (_t) => { + const headers = csvDetectHeaderStream({ newlineChar: "\n" }); + const streams = [createReadableStream('"a,b",c\n1,2\n'), headers]; + const output = await streamToString(pipejoin(streams)); + deepStrictEqual(headers.result().value.header, ["a,b", "c"]); + strictEqual(output, "1,2\n"); +}); + +test(`${variant}: csvDetectHeaderStream custom-escape even run closes header quote`, async (_t) => { + const headers = csvDetectHeaderStream({ + newlineChar: "\n", + escapeChar: "\\", + }); + const streams = [createReadableStream('"a\\\\",b\nv1,v2\n'), headers]; + const output = await streamToString(pipejoin(streams)); + deepStrictEqual(headers.result().value.header, ["a\\", "b"]); + strictEqual(output, "v1,v2\n"); +}); + +test(`${variant}: csvDetectHeaderStream passes through data after a quoted header newline`, async (_t) => { + const headers = csvDetectHeaderStream({ newlineChar: "\n" }); + const streams = [ + createReadableStream('"h1\nstill h1",h2\nr1a,r1b\nr2a,r2b\n'), + headers, + ]; + const output = await streamToString(pipejoin(streams)); + deepStrictEqual(headers.result().value.header, ["h1\nstill h1", "h2"]); + strictEqual(output, "r1a,r1b\nr2a,r2b\n"); +}); + +test(`${variant}: csvDetectHeaderStream CRLF header newline length`, async (_t) => { + const headers = csvDetectHeaderStream({ newlineChar: "\r\n" }); + const streams = [createReadableStream("a,b,c\r\n1,2,3\r\n"), headers]; + const output = await streamToString(pipejoin(streams)); + deepStrictEqual(headers.result().value.header, ["a", "b", "c"]); + strictEqual(output, "1,2,3\r\n"); +}); + +test(`${variant}: csvDetectHeaderStream emits remaining rest only when non-empty`, async (_t) => { + const headers = csvDetectHeaderStream({ newlineChar: "\n" }); + const streams = [createReadableStream("only,header\n"), headers]; + const output = await streamToString(pipejoin(streams)); + deepStrictEqual(headers.result().value.header, ["only", "header"]); + strictEqual(output, ""); +}); + +// --- csvRemoveMalformedRowsStream result key + default + idx --- +test(`${variant}: csvRemoveMalformedRowsStream default resultKey and message`, async (_t) => { + const filter = csvRemoveMalformedRowsStream(); + const streams = [createReadableStream([["a", "b"], ["c"]]), filter]; + const result = await pipeline(streams); + strictEqual(filter.result().key, "csvRemoveMalformedRows"); + deepStrictEqual(result.csvRemoveMalformedRows.MalformedRow.idx, [1]); + strictEqual( + filter.result().value.MalformedRow.message, + "Row has incorrect number of fields", + ); + strictEqual(filter.result().value.MalformedRow.id, "MalformedRow"); +}); + +test(`${variant}: csvRemoveMalformedRowsStream first row sets count, later mismatch dropped`, async (_t) => { + const filter = csvRemoveMalformedRowsStream(); + const streams = [ + createReadableStream([["a", "b", "c"], ["1", "2", "3"], ["x"]]), + filter, + ]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [ + ["a", "b", "c"], + ["1", "2", "3"], + ]); + deepStrictEqual(filter.result().value.MalformedRow.idx, [2]); +}); + +// --- csvRemoveEmptyRowsStream default resultKey + message --- +test(`${variant}: csvRemoveEmptyRowsStream default resultKey and message`, async (_t) => { + const filter = csvRemoveEmptyRowsStream(); + const streams = [ + createReadableStream([ + ["", ""], + ["1", "2"], + ]), + filter, + ]; + const result = await pipeline(streams); + strictEqual(filter.result().key, "csvRemoveEmptyRows"); + strictEqual(result.csvRemoveEmptyRows.EmptyRow.message, "Row is empty"); + strictEqual(result.csvRemoveEmptyRows.EmptyRow.id, "EmptyRow"); +}); + +test(`${variant}: csvRemoveEmptyRowsStream keeps row with one non-empty field`, async (_t) => { + const filter = csvRemoveEmptyRowsStream(); + const streams = [ + createReadableStream([ + ["", "x"], + ["", ""], + ]), + filter, + ]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [["", "x"]]); + deepStrictEqual(filter.result().value.EmptyRow.idx, [1]); +}); + +test(`${variant}: csvRemoveEmptyRowsStream keeps row whose only non-empty field is last`, async (_t) => { + const filter = csvRemoveEmptyRowsStream(); + const streams = [createReadableStream([["", "", "z"]]), filter]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [["", "", "z"]]); + deepStrictEqual(filter.result().value, {}); +}); + +// --- csvInjectHeaderStream injects header exactly once --- +test(`${variant}: csvInjectHeaderStream injects header exactly once`, async (_t) => { + const streams = [ + createReadableStream([ + ["1", "2"], + ["3", "4"], + ["5", "6"], + ]), + csvInjectHeaderStream({ header: ["a", "b"] }), + ]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [ + ["a", "b"], + ["1", "2"], + ["3", "4"], + ["5", "6"], + ]); +}); + +// --- csvParseStream chunkSize ready/join paths --- +test(`${variant}: csvParseStream single input chunk reaching chunkSize processes immediately`, async (_t) => { + const streams = [ + createReadableStream(["a,b,c,d,e\r\n", "1,2,3,4,5\r\n"]), + csvParseStream({ chunkSize: 5 }), + ]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [ + ["a", "b", "c", "d", "e"], + ["1", "2", "3", "4", "5"], + ]); +}); + +test(`${variant}: csvParseStream below chunkSize joins on flush`, async (_t) => { + const streams = [ + createReadableStream(["a,", "b\r\n", "1,", "2\r\n"]), + csvParseStream({ chunkSize: 1000 }), + ]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [ + ["a", "b"], + ["1", "2"], + ]); +}); + +test(`${variant}: csvParseStream default resultKey is csvErrors`, async (_t) => { + const streams = [createReadableStream("a,b\r\n"), csvParseStream()]; + const result = await pipeline(streams); + strictEqual(streams[1].result().key, "csvErrors"); + deepStrictEqual(result.csvErrors, {}); +}); + +// --- csvFormatStream multi-char delimiter: each first-char formula trigger --- +test(`${variant}: csvFormatStream multi-char delimiter quotes leading equals`, async (_t) => { + const streams = [ + createReadableStream([["=x", "ok"]]), + csvFormatStream({ delimiterChar: "::" }), + ]; + strictEqual(await streamToString(pipejoin(streams)), '"=x"::ok\r\n'); +}); + +test(`${variant}: csvFormatStream multi-char delimiter quotes leading plus`, async (_t) => { + const streams = [ + createReadableStream([["+x", "ok"]]), + csvFormatStream({ delimiterChar: "::" }), + ]; + strictEqual(await streamToString(pipejoin(streams)), '"+x"::ok\r\n'); +}); + +test(`${variant}: csvFormatStream multi-char delimiter quotes leading minus`, async (_t) => { + const streams = [ + createReadableStream([["-x", "ok"]]), + csvFormatStream({ delimiterChar: "::" }), + ]; + strictEqual(await streamToString(pipejoin(streams)), '"-x"::ok\r\n'); +}); + +test(`${variant}: csvFormatStream multi-char delimiter quotes leading at-sign`, async (_t) => { + const streams = [ + createReadableStream([["@x", "ok"]]), + csvFormatStream({ delimiterChar: "::" }), + ]; + strictEqual(await streamToString(pipejoin(streams)), '"@x"::ok\r\n'); +}); + +test(`${variant}: csvFormatStream multi-char delimiter quotes leading space`, async (_t) => { + const streams = [ + createReadableStream([[" x", "ok"]]), + csvFormatStream({ delimiterChar: "::" }), + ]; + strictEqual(await streamToString(pipejoin(streams)), '" x"::ok\r\n'); +}); + +test(`${variant}: csvFormatStream multi-char delimiter quotes leading BOM`, async (_t) => { + const streams = [ + createReadableStream([["x", "ok"]]), + csvFormatStream({ delimiterChar: "::" }), + ]; + strictEqual(await streamToString(pipejoin(streams)), '"x"::ok\r\n'); +}); + +test(`${variant}: csvFormatStream multi-char delimiter does NOT quote plain leading char`, async (_t) => { + const streams = [ + createReadableStream([["xyz", "ok"]]), + csvFormatStream({ delimiterChar: "::" }), + ]; + strictEqual(await streamToString(pipejoin(streams)), "xyz::ok\r\n"); +}); + +test(`${variant}: csvFormatStream multi-char delimiter quotes trailing space`, async (_t) => { + const streams = [ + createReadableStream([["trail ", "ok"]]), + csvFormatStream({ delimiterChar: "::" }), + ]; + strictEqual(await streamToString(pipejoin(streams)), '"trail "::ok\r\n'); +}); + +test(`${variant}: csvFormatStream multi-char delimiter quotes on newline`, async (_t) => { + const a = await streamToString( + pipejoin([ + createReadableStream([["a\nb", "ok"]]), + csvFormatStream({ delimiterChar: "::" }), + ]), + ); + strictEqual(a, '"a\nb"::ok\r\n'); +}); + +test(`${variant}: csvFormatStream multi-char delimiter quotes on carriage return`, async (_t) => { + const b = await streamToString( + pipejoin([ + createReadableStream([["a\rb", "ok"]]), + csvFormatStream({ delimiterChar: "::" }), + ]), + ); + strictEqual(b, '"a\rb"::ok\r\n'); +}); + +// --- csvFormatStream single-char delimiter: each first-char formula trigger --- +test(`${variant}: csvFormatStream single-char delimiter quotes leading at-sign`, async (_t) => { + const streams = [createReadableStream([["@x", "ok"]]), csvFormatStream()]; + strictEqual(await streamToString(pipejoin(streams)), '"@x",ok\r\n'); +}); + +test(`${variant}: csvFormatStream single-char delimiter quotes leading plus`, async (_t) => { + const streams = [createReadableStream([["+x", "ok"]]), csvFormatStream()]; + strictEqual(await streamToString(pipejoin(streams)), '"+x",ok\r\n'); +}); + +test(`${variant}: csvFormatStream single-char delimiter quotes leading minus`, async (_t) => { + const streams = [createReadableStream([["-x", "ok"]]), csvFormatStream()]; + strictEqual(await streamToString(pipejoin(streams)), '"-x",ok\r\n'); +}); + +test(`${variant}: csvFormatStream single-char delimiter quotes leading equals`, async (_t) => { + const streams = [createReadableStream([["=x", "ok"]]), csvFormatStream()]; + strictEqual(await streamToString(pipejoin(streams)), '"=x",ok\r\n'); +}); + +test(`${variant}: csvFormatStream single-char delimiter does NOT quote plain value`, async (_t) => { + const streams = [createReadableStream([["xyz", "ok"]]), csvFormatStream()]; + strictEqual(await streamToString(pipejoin(streams)), "xyz,ok\r\n"); +}); + +test(`${variant}: csvFormatStream single-char delimiter quotes trailing space`, async (_t) => { + const streams = [createReadableStream([["trail ", "ok"]]), csvFormatStream()]; + strictEqual(await streamToString(pipejoin(streams)), '"trail ",ok\r\n'); +}); + +test(`${variant}: csvFormatStream should quote field with leading BOM`, async (_t) => { + const streams = [createReadableStream([["bom", "ok"]]), csvFormatStream()]; + strictEqual(await streamToString(pipejoin(streams)), '"bom",ok\r\n'); +}); + +test(`${variant}: csvFormatStream should quote field with carriage return`, async (_t) => { + const streams = [createReadableStream([["a\rb", "ok"]]), csvFormatStream()]; + strictEqual(await streamToString(pipejoin(streams)), '"a\rb",ok\r\n'); +}); + +test(`${variant}: csvFormatStream should format Date as ISO string`, async (_t) => { + const d = new Date("2024-01-15T10:30:00.000Z"); + const streams = [createReadableStream([[d, "ok"]]), csvFormatStream()]; + strictEqual( + await streamToString(pipejoin(streams)), + "2024-01-15T10:30:00.000Z,ok\r\n", + ); +}); + +test(`${variant}: csvFormatStream should format number via String`, async (_t) => { + const streams = [createReadableStream([[42, 3.14]]), csvFormatStream()]; + strictEqual(await streamToString(pipejoin(streams)), "42,3.14\r\n"); +}); + +test(`${variant}: csvFormatStream should format boolean via String in slow path`, async (_t) => { + const streams = [createReadableStream([[true, false]]), csvFormatStream()]; + strictEqual(await streamToString(pipejoin(streams)), "true,false\r\n"); +}); + +test(`${variant}: csvFormatStream should quote negative number string`, async (_t) => { + const streams = [createReadableStream([[-42, "ok"]]), csvFormatStream()]; + strictEqual(await streamToString(pipejoin(streams)), '"-42",ok\r\n'); +}); + +test(`${variant}: csvFormatStream should format null and undefined as empty`, async (_t) => { + const streams = [ + createReadableStream([[null, undefined, "x"]]), + csvFormatStream(), + ]; + strictEqual(await streamToString(pipejoin(streams)), ",,x\r\n"); +}); + +test(`${variant}: csvFormatStream custom escape escapes escape and quote chars`, async (_t) => { + const streams = [ + createReadableStream([['a"b\\c', "ok"]]), + csvFormatStream({ escapeChar: "\\" }), + ]; + strictEqual(await streamToString(pipejoin(streams)), '"a\\"b\\\\c",ok\r\n'); +}); + +test(`${variant}: csvFormatStream custom escape escapes only escape char when no quote`, async (_t) => { + const streams = [ + createReadableStream([["a\\b,c", "ok"]]), + csvFormatStream({ escapeChar: "\\" }), + ]; + strictEqual(await streamToString(pipejoin(streams)), '"a\\\\b,c",ok\r\n'); +}); + +test(`${variant}: csvFormatStream batch boundary flushes at 64 rows`, async (_t) => { + const rows = []; + for (let i = 0; i < 70; i++) rows.push([String(i), "x"]); + const output = await streamToString( + pipejoin([createReadableStream(rows), csvFormatStream()]), + ); + const lines = output.split("\r\n").filter((l) => l.length > 0); + strictEqual(lines.length, 70); + strictEqual(lines[0], "0,x"); + strictEqual(lines[69], "69,x"); +}); + +test(`${variant}: csvFormatStream custom newlineChar separator`, async (_t) => { + const output = await streamToString( + pipejoin([ + createReadableStream([ + ["1", "2"], + ["3", "4"], + ]), + csvFormatStream({ newlineChar: "\n" }), + ]), + ); + strictEqual(output, "1,2\n3,4\n"); +}); + +test(`${variant}: csvFormatStream custom quoteChar`, async (_t) => { + const output = await streamToString( + pipejoin([ + createReadableStream([["a,b", "ok"]]), + csvFormatStream({ quoteChar: "'" }), + ]), + ); + strictEqual(output, "'a,b',ok\r\n"); +}); + +// --- Quoted-field post-quote newline dispatch: length 1 / 2 / >2 --- +test(`${variant}: csvQuotedParser quoted field then LF newline (length 1)`, (_t) => { + const result = csvQuotedParser('"a"\n"b"\n', { newlineChar: "\n" }, true); + deepStrictEqual(result.rows, [["a"], ["b"]]); +}); + +test(`${variant}: csvQuotedParser quoted field then CRLF newline (length 2)`, (_t) => { + const result = csvQuotedParser( + '"a"\r\n"b"\r\n', + { newlineChar: "\r\n" }, + true, + ); + deepStrictEqual(result.rows, [["a"], ["b"]]); +}); + +test(`${variant}: csvQuotedParser quoted field then lone CR is not a CRLF newline`, (_t) => { + const result = csvQuotedParser('"a"\rb,c\r\n', { newlineChar: "\r\n" }, true); + strictEqual(result.rows.length, 1); + strictEqual(result.rows[0][0], "a"); +}); + +test(`${variant}: csvQuotedParser quoted field then 3-char newline (length > 2)`, (_t) => { + const result = csvQuotedParser('"a"~|~"b"~|~', { newlineChar: "~|~" }, true); + deepStrictEqual(result.rows, [["a"], ["b"]]); +}); + +test(`${variant}: csvQuotedParser quoted field then partial 3-char newline is garbage`, (_t) => { + const result = csvQuotedParser('"a"~|x~|~', { newlineChar: "~|~" }, true); + strictEqual(result.rows.length, 1); + strictEqual(result.rows[0][0], "a"); +}); + +test(`${variant}: csvQuotedParser custom escape quoted field then LF newline`, (_t) => { + const result = csvQuotedParser( + '"a"\n"b"\n', + { newlineChar: "\n", escapeChar: "\\" }, + true, + ); + deepStrictEqual(result.rows, [["a"], ["b"]]); +}); + +test(`${variant}: csvQuotedParser custom escape quoted field then CRLF newline`, (_t) => { + const result = csvQuotedParser( + '"a"\r\n"b"\r\n', + { newlineChar: "\r\n", escapeChar: "\\" }, + true, + ); + deepStrictEqual(result.rows, [["a"], ["b"]]); +}); + +test(`${variant}: csvQuotedParser custom escape quoted field then 3-char newline`, (_t) => { + const result = csvQuotedParser( + '"a"~|~"b"~|~', + { newlineChar: "~|~", escapeChar: "\\" }, + true, + ); + deepStrictEqual(result.rows, [["a"], ["b"]]); +}); + +test(`${variant}: csvQuotedParser custom escape quoted field then lone CR not CRLF`, (_t) => { + const result = csvQuotedParser( + '"a"\rb,c\r\n', + { newlineChar: "\r\n", escapeChar: "\\" }, + true, + ); + strictEqual(result.rows.length, 1); + strictEqual(result.rows[0][0], "a"); +}); + +// --- csvCoerceValuesStream: iso8601 regex shape --- +test(`${variant}: csvCoerceValuesStream should coerce date with multi-digit fractional seconds`, async (_t) => { + const output = await streamToArray( + pipejoin([ + createReadableStream([{ d: "2024-01-15T10:30:00.123Z" }]), + csvCoerceValuesStream(), + ]), + ); + deepStrictEqual(output, [{ d: new Date("2024-01-15T10:30:00.123Z") }]); +}); + +test(`${variant}: csvCoerceValuesStream should coerce date with timezone offset without colon`, async (_t) => { + const output = await streamToArray( + pipejoin([ + createReadableStream([{ d: "2024-01-15T10:30:00+0530" }]), + csvCoerceValuesStream(), + ]), + ); + deepStrictEqual(output, [{ d: new Date("2024-01-15T10:30:00+0530") }]); +}); + +test(`${variant}: csvCoerceValuesStream should coerce date with timezone offset with colon`, async (_t) => { + const output = await streamToArray( + pipejoin([ + createReadableStream([{ d: "2024-01-15T10:30:00+05:30" }]), + csvCoerceValuesStream(), + ]), + ); + deepStrictEqual(output, [{ d: new Date("2024-01-15T10:30:00+05:30") }]); +}); + +test(`${variant}: csvCoerceValuesStream should coerce date with space separator and seconds`, async (_t) => { + const output = await streamToArray( + pipejoin([ + createReadableStream([{ d: "2024-01-15 10:30:45" }]), + csvCoerceValuesStream(), + ]), + ); + deepStrictEqual(output, [{ d: new Date("2024-01-15 10:30:45") }]); +}); + +test(`${variant}: csvCoerceValuesStream should coerce plain date-only value`, async (_t) => { + const output = await streamToArray( + pipejoin([ + createReadableStream([{ d: "2024-12-31" }]), + csvCoerceValuesStream(), + ]), + ); + deepStrictEqual(output, [{ d: new Date("2024-12-31") }]); +}); + +test(`${variant}: csvCoerceValuesStream should keep date with non-digit fractional as string`, async (_t) => { + const output = await streamToArray( + pipejoin([ + createReadableStream([{ d: "2024-01-15T10:30:00.abc" }]), + csvCoerceValuesStream(), + ]), + ); + deepStrictEqual(output, [{ d: "2024-01-15T10:30:00.abc" }]); +}); + +test(`${variant}: csvCoerceValuesStream should coerce exponent forms`, async (_t) => { + const output = await streamToArray( + pipejoin([ + createReadableStream([{ a: "1e+10", b: "2e-05", c: "1.5E3" }]), + csvCoerceValuesStream(), + ]), + ); + deepStrictEqual(output, [{ a: 1e10, b: 2e-5, c: 1500 }]); +}); + +test(`${variant}: csvCoerceValuesStream should keep malformed exponent as string`, async (_t) => { + const output = await streamToArray( + pipejoin([ + createReadableStream([{ a: "1e", b: "1e+", c: "1.2.3" }]), + csvCoerceValuesStream(), + ]), + ); + deepStrictEqual(output, [{ a: "1e", b: "1e+", c: "1.2.3" }]); +}); + +test(`${variant}: csvCoerceValuesStream should not coerce trailing non-number text`, async (_t) => { + const output = await streamToArray( + pipejoin([ + createReadableStream([{ a: "12abc", d: "2024-01-15extra" }]), + csvCoerceValuesStream(), + ]), + ); + deepStrictEqual(output, [{ a: "12abc", d: "2024-01-15extra" }]); +}); + +test(`${variant}: csvCoerceValuesStream should not coerce date missing leading anchor`, async (_t) => { + const output = await streamToArray( + pipejoin([ + createReadableStream([{ d: "x2024-01-15" }]), + csvCoerceValuesStream(), + ]), + ); + deepStrictEqual(output, [{ d: "x2024-01-15" }]); +}); + +test(`${variant}: csvCoerceValuesStream boolean first-char/length gating`, async (_t) => { + const output = await streamToArray( + pipejoin([ + createReadableStream([{ a: "trUE", b: "tree", c: "True", d: "truer" }]), + csvCoerceValuesStream(), + ]), + ); + deepStrictEqual(output, [{ a: true, b: "tree", c: true, d: "truer" }]); +}); + +test(`${variant}: csvCoerceValuesStream should return null for empty string auto-coerce`, async (_t) => { + const output = await streamToArray( + pipejoin([createReadableStream([{ a: "" }]), csvCoerceValuesStream()]), + ); + deepStrictEqual(output, [{ a: null }]); +}); + +test(`${variant}: csvCoerceValuesStream should coerce single-digit zero and nine`, async (_t) => { + const output = await streamToArray( + pipejoin([ + createReadableStream([{ a: "0", b: "9" }]), + csvCoerceValuesStream(), + ]), + ); + deepStrictEqual(output, [{ a: 0, b: 9 }]); +}); + +test(`${variant}: csvCoerceValuesStream explicit boolean lowercase compare`, async (_t) => { + const output = await streamToArray( + pipejoin([ + createReadableStream([{ a: "TRUE", b: "no", c: "true" }]), + csvCoerceValuesStream({ + columns: { a: "boolean", b: "boolean", c: "boolean" }, + }), + ]), + ); + deepStrictEqual(output, [{ a: true, b: false, c: true }]); +}); + +test(`${variant}: csvCoerceValuesStream explicit boolean Boolean for non-string`, async (_t) => { + const output = await streamToArray( + pipejoin([ + createReadableStream([{ a: 1, b: 0 }]), + csvCoerceValuesStream({ columns: { a: "boolean", b: "boolean" } }), + ]), + ); + deepStrictEqual(output, [{ a: true, b: false }]); +}); + +test(`${variant}: csvCoerceValuesStream explicit json parses array`, async (_t) => { + const output = await streamToArray( + pipejoin([ + createReadableStream([{ a: "[1,2,3]" }]), + csvCoerceValuesStream({ columns: { a: "json" } }), + ]), + ); + deepStrictEqual(output, [{ a: [1, 2, 3] }]); +}); + +// --- csvDetectDelimitersStream quote boundary precision --- +test(`${variant}: csvDetectDelimitersStream detects quote closing at end of text`, async (_t) => { + const detect = csvDetectDelimitersStream(); + await pipeline([createReadableStream("x,y\nz,'w'"), detect]); + strictEqual(detect.result().value.quoteChar, "'"); +}); + +test(`${variant}: csvDetectDelimitersStream detects quote opening after CR-only newline`, async (_t) => { + const detect = csvDetectDelimitersStream(); + await pipeline([createReadableStream("a,b\r'c',d\r"), detect]); + strictEqual(detect.result().value.quoteChar, "'"); + strictEqual(detect.result().value.newlineChar, "\r"); +}); + +test(`${variant}: csvDetectDelimitersStream detects quote closing before a delimiter`, async (_t) => { + const detect = csvDetectDelimitersStream(); + await pipeline([createReadableStream("'a',b,c\n1,2,3\n"), detect]); + strictEqual(detect.result().value.quoteChar, "'"); +}); + +test(`${variant}: csvDetectDelimitersStream detects quote opening at text start`, async (_t) => { + const detect = csvDetectDelimitersStream(); + await pipeline([createReadableStream("'a',b\n1,2\n"), detect]); + strictEqual(detect.result().value.quoteChar, "'"); +}); + +test(`${variant}: csvDetectDelimitersStream detects quote opening after newline`, async (_t) => { + const detect = csvDetectDelimitersStream(); + await pipeline([createReadableStream("a,b\n'c',d\n"), detect]); + strictEqual(detect.result().value.quoteChar, "'"); +}); + +test(`${variant}: csvDetectDelimitersStream does NOT detect a quote that never closes at a field end`, async (_t) => { + const detect = csvDetectDelimitersStream(); + await pipeline([ + createReadableStream("name,note\n'x,it's fine\nhello,world\n"), + detect, + ]); + strictEqual(detect.result().value.quoteChar, '"'); +}); + +test(`${variant}: csvDetectDelimitersStream sets escapeChar equal to detected quoteChar`, async (_t) => { + const detect = csvDetectDelimitersStream(); + await pipeline([createReadableStream("'a','b'\n1,2\n"), detect]); + strictEqual(detect.result().value.escapeChar, "'"); + strictEqual(detect.result().value.quoteChar, "'"); +}); + +test(`${variant}: csvDetectDelimitersStream picks tab over comma by precedence`, async (_t) => { + const detect = csvDetectDelimitersStream(); + await pipeline([createReadableStream("a\tb,c\n1\t2,3\n"), detect]); + strictEqual(detect.result().value.delimiterChar, "\t"); +}); + +test(`${variant}: csvDetectDelimitersStream picks pipe over semicolon and comma`, async (_t) => { + const detect = csvDetectDelimitersStream(); + await pipeline([createReadableStream("a|b;c,d\n1|2;3,4\n"), detect]); + strictEqual(detect.result().value.delimiterChar, "|"); +}); + +test(`${variant}: csvDetectDelimitersStream picks semicolon over comma`, async (_t) => { + const detect = csvDetectDelimitersStream(); + await pipeline([createReadableStream("a;b,c\n1;2,3\n"), detect]); + strictEqual(detect.result().value.delimiterChar, ";"); +}); + +test(`${variant}: csvDetectDelimitersStream defaults to double-quote when none present`, async (_t) => { + const detect = csvDetectDelimitersStream(); + await pipeline([createReadableStream("a,b,c\n1,2,3\n"), detect]); + strictEqual(detect.result().value.quoteChar, '"'); +}); diff --git a/packages/csv/package.json b/packages/csv/package.json index 3bbc4e1..3484b60 100644 --- a/packages/csv/package.json +++ b/packages/csv/package.json @@ -39,6 +39,7 @@ "scripts": { "test": "npm run test:unit", "test:unit": "node --test", + "test:mutation": "cd ../.. && MUTATE_PACKAGE=\"$(basename \"$OLDPWD\")\" stryker run", "test:benchmark": "node __benchmarks__/index.js" }, "license": "MIT", diff --git a/packages/digest/README.md b/packages/digest/README.md index a57f4a1..4f302c7 100644 --- a/packages/digest/README.md +++ b/packages/digest/README.md @@ -1,6 +1,6 @@Hash and checksum streams.
@@ -18,10 +18,10 @@
-
+
-
+
You can read the documentation at: https://datastream.js.org
diff --git a/packages/digest/index.d.ts b/packages/digest/index.d.ts index 014bca4..f379476 100644 --- a/packages/digest/index.d.ts +++ b/packages/digest/index.d.ts @@ -12,7 +12,11 @@ export type DigestAlgorithm = | "SHA2-512" | "SHA3-256" | "SHA3-384" - | "SHA3-512"; + | "SHA3-512" + // Native aliases accepted on both builds, normalized to the canonical name. + | "SHA256" + | "SHA384" + | "SHA512"; type DigestStreamResult = DatastreamPassThrough & { result: () => StreamResultHTTP fetch streams.
@@ -18,10 +18,10 @@
-
+
-
+
You can read the documentation at: https://datastream.js.org
diff --git a/packages/fetch/index.js b/packages/fetch/index.js index 865b94a..4270ced 100644 --- a/packages/fetch/index.js +++ b/packages/fetch/index.js @@ -22,6 +22,14 @@ const validatePaginationUrl = (nextUrl, origin) => { } }; +const originOf = (urlString) => { + try { + return new URL(urlString).origin; + } catch { + return undefined; + } +}; + const redactUrl = (urlString) => { try { const url = new URL(urlString); @@ -79,7 +87,13 @@ export const fetchWritableStream = async (options, streamOptions = {}) => { const write = (chunk) => { body.push(chunk); }; - const stream = createWritableStream(write, streamOptions); + // Signal end-of-body so the duplex request body terminates and the + // in-flight upload can complete. createReadableStream treats a pushed + // `null` as close on both the Node and Web builds. + const final = () => { + body.push(null); + }; + const stream = createWritableStream(write, final, streamOptions); stream.result = () => ({ key: "output", value }); return stream; }; @@ -117,7 +131,11 @@ async function* fetchGenerator(fetchOptions, streamOptions) { yield chunk; } } catch (error) { + // Binary branch: response is a Web ReadableStream with .cancel(). + // JSON branch: response is the fetchJson async generator with + // .return(). Call both so resources are released uniformly. await response?.cancel?.(); + await response?.return?.(); throw error; } // ensure there is rate limiting between req with different options @@ -146,6 +164,11 @@ async function* fetchJson(options, streamOptions) { options.prefetchResponse ?? (await fetchRateLimit(options, streamOptions)); delete options.prefetchResponse; + // NOTE: response.json() buffers the FULL body of this page into memory + // before any item is yielded — unlike the binary branch which streams + // chunk-by-chunk with backpressure. A server returning a very large + // single JSON document (or large pages) is fully materialized here, so + // keep per-page payloads bounded for untrusted endpoints. const body = await response.json(); url = parseLinkFromHeader(response.headers); url ??= parseNextPath(body, nextPath); @@ -187,13 +210,34 @@ const parseLinkFromHeader = (headers) => { return link?.match(nextLinkRegExp)?.[1]; }; -export const fetchRateLimit = async (options, streamOptions = {}) => { +// 3xx statuses that carry a Location and represent a redirect. +const redirectStatuses = new Set([301, 302, 303, 307, 308]); +const maxRedirects = 20; + +export const fetchRateLimit = async (options = {}, streamOptions = {}) => { + // Apply defaults FIRST so rateLimit (and every other option) is populated + // before it is read; otherwise a direct call without rateLimit computes + // `Date.now() + 1000 * undefined` = NaN for rateLimitTimestamp. + // Mutate the passed-in object in place (rather than reassigning to a clone) + // so callers — notably fetchGenerator, which reads back + // options.rateLimitTimestamp to carry rate limiting between configs — see + // the timestamp we compute below. + Object.assign(options, mergeOptions(options)); + const now = Date.now(); if (now < (options.rateLimitTimestamp ?? 0)) { await timeout(options.rateLimitTimestamp - now, streamOptions); } options.rateLimitTimestamp = Date.now() + 1000 * options.rateLimit; - options = mergeOptions(options); // for when called directly + + // Same-origin redirect pinning (SSRF defence). The initial origin is pinned + // to the original request URL; redirects to a different origin are blocked + // by default so a server cannot 3xx us into internal/metadata endpoints. + // Callers can opt out by setting `redirect` explicitly ("follow"/"error"). + const callerRedirect = options.redirect; + const manageRedirects = callerRedirect === undefined; + // __origin is set by fetchGenerator; derive it for direct callers. + const initialOrigin = options.__origin ?? originOf(options.url); const { method, @@ -202,7 +246,6 @@ export const fetchRateLimit = async (options, streamOptions = {}) => { mode, credentials, cache, - redirect, referrer, referrerPolicy, integrity, @@ -216,7 +259,9 @@ export const fetchRateLimit = async (options, streamOptions = {}) => { mode, credentials, cache, - redirect, + // When we manage redirects ourselves we ask the platform NOT to follow + // them so we can validate each Location before re-issuing. + redirect: manageRedirects ? "manual" : callerRedirect, referrer, referrerPolicy, integrity, @@ -224,7 +269,67 @@ export const fetchRateLimit = async (options, streamOptions = {}) => { duplex, signal: streamOptions.signal, }; - const response = await fetch(options.url, fetchInit); + let response = await fetch(options.url, fetchInit); + + // Manually follow / validate redirects when we own redirect handling. + if (manageRedirects) { + let redirectCount = 0; + while ( + redirectStatuses.has(response.status) && + response.headers.has("Location") + ) { + const safeUrl = redactUrl(options.url); + if (++redirectCount > maxRedirects) { + await response.body?.cancel(); + throw new Error( + `fetch ${options.method} ${safeUrl} exceeded ${maxRedirects} redirects`, + { + cause: { + status: response.status, + url: safeUrl, + method: options.method, + }, + }, + ); + } + const location = response.headers.get("Location"); + let target; + try { + target = new URL(location, options.url); + } catch { + await response.body?.cancel(); + throw new Error( + `fetch ${options.method} ${safeUrl} returned an invalid redirect Location`, + { + cause: { + status: response.status, + url: safeUrl, + method: options.method, + }, + }, + ); + } + if (target.origin !== initialOrigin) { + await response.body?.cancel(); + throw new Error( + `fetch ${options.method} ${safeUrl} blocked cross-origin redirect (${target.origin} does not match ${initialOrigin})`, + { + cause: { + status: response.status, + url: safeUrl, + location: redactUrl(target.toString()), + origin: initialOrigin, + method: options.method, + }, + }, + ); + } + await response.body?.cancel(); + options.url = target.toString(); + response = await fetch(options.url, fetchInit); + } + } + if (!response.ok) { const safeUrl = redactUrl(options.url); // 429 Too Many Requests @@ -238,7 +343,7 @@ export const fetchRateLimit = async (options, streamOptions = {}) => { { cause: { status: response.status, - url: options.url, + url: safeUrl, method: options.method, }, }, @@ -258,7 +363,7 @@ export const fetchRateLimit = async (options, streamOptions = {}) => { throw new Error(`fetch ${response.status} ${options.method} ${safeUrl}`, { cause: { status: response.status, - url: options.url, + url: safeUrl, method: options.method, }, }); diff --git a/packages/fetch/index.test.js b/packages/fetch/index.test.js index 5c20385..9b55825 100644 --- a/packages/fetch/index.test.js +++ b/packages/fetch/index.test.js @@ -4,6 +4,7 @@ import { deepStrictEqual, ok, strictEqual } from "node:assert"; import test from "node:test"; import { createPassThroughStream, + createTransformStream, pipejoin, pipeline, streamToArray, @@ -333,6 +334,238 @@ test(`${variant}: fetchResponseStream should throw on non-ok response`, async (_ } }); +test(`${variant}: fetchResponseStream error cause must not leak the unredacted URL`, async (_t) => { + const originalFetch = global.fetch; + const secretUrl = + "https://user:pass@example.org/secret?token=abc123&api_key=zzz"; + global.fetch = async (url) => { + if (url.startsWith("https://user:pass@example.org/secret")) { + return new Response("", { status: 404, statusText: "Not Found" }); + } + return originalFetch(url); + }; + fetchSetDefaults({ headers: { Accept: "application/json" } }); + try { + const stream = fetchResponseStream([{ url: secretUrl }]); + await streamToArray(stream); + throw new Error("Should have thrown"); + } catch (error) { + // message is redacted + ok(!error.message.includes("token=abc123"), "message leaked query token"); + ok(!error.message.includes("user:pass"), "message leaked credentials"); + // cause.url MUST be redacted too + ok( + !String(error.cause.url).includes("token=abc123"), + `cause.url leaked query token: ${error.cause.url}`, + ); + ok( + !String(error.cause.url).includes("api_key=zzz"), + `cause.url leaked api_key: ${error.cause.url}`, + ); + ok( + !String(error.cause.url).includes("user:pass"), + `cause.url leaked credentials: ${error.cause.url}`, + ); + ok( + String(error.cause.url).includes("[REDACTED]"), + `cause.url not redacted: ${error.cause.url}`, + ); + } finally { + global.fetch = originalFetch; + fetchSetDefaults({ headers: { Accept: "application/json" } }); + } +}); + +test(`${variant}: fetchRateLimit 429 max-retries error cause must not leak the unredacted URL`, async (_t) => { + const originalFetch = global.fetch; + const secretUrl = "https://example.org/always-429?token=secret-429"; + global.fetch = () => + Promise.resolve( + new Response("rate limited", { + status: 429, + statusText: "Too Many Requests", + }), + ); + fetchSetDefaults({ rateLimit: 0 }); + try { + const stream = fetchResponseStream([ + { url: secretUrl, rateLimit: 0, retryMaxCount: 2 }, + ]); + await streamToArray(stream); + throw new Error("Should have thrown"); + } catch (error) { + ok(error.message.includes("max retries")); + ok( + !error.message.includes("token=secret-429"), + "message leaked query token", + ); + ok( + !String(error.cause.url).includes("token=secret-429"), + `cause.url leaked query token: ${error.cause.url}`, + ); + ok( + String(error.cause.url).includes("[REDACTED]"), + `cause.url not redacted: ${error.cause.url}`, + ); + } finally { + global.fetch = originalFetch; + fetchSetDefaults({ rateLimit: 0.01 }); + } +}); + +// *** SSRF: redirect handling *** // +test(`${variant}: fetchResponseStream should block cross-origin redirects (SSRF)`, async (_t) => { + const originalFetch = global.fetch; + let metadataFetched = false; + global.fetch = async (url, init) => { + if (url === "https://example.org/redirect-ssrf") { + // Simulate a server 302-redirecting to a cloud metadata endpoint. + // With redirect:"manual" the platform returns the 3xx unfollowed. + deepStrictEqual(init.redirect, "manual"); + return new Response("", { + status: 302, + statusText: "Found", + headers: new Headers({ + Location: "http://169.254.169.254/latest/meta-data/", + }), + }); + } + if (url === "http://169.254.169.254/latest/meta-data/") { + metadataFetched = true; + return new Response("creds", { status: 200 }); + } + return originalFetch(url); + }; + fetchSetDefaults({ headers: { Accept: "application/json" } }); + try { + const stream = fetchResponseStream([ + { url: "https://example.org/redirect-ssrf" }, + ]); + await streamToArray(stream); + throw new Error("Should have thrown"); + } catch (error) { + ok( + error.message.includes("redirect"), + `expected redirect error, got: ${error.message}`, + ); + strictEqual(metadataFetched, false, "cross-origin redirect was followed"); + } finally { + global.fetch = originalFetch; + fetchSetDefaults({ headers: { Accept: "application/json" } }); + } +}); + +test(`${variant}: fetchResponseStream cross-origin redirect error must not leak unredacted URL`, async (_t) => { + const originalFetch = global.fetch; + const secretUrl = "https://example.org/redirect-secret?token=abc123"; + global.fetch = async (url) => { + if (url === secretUrl) { + return new Response("", { + status: 301, + statusText: "Moved Permanently", + headers: new Headers({ + Location: "http://127.0.0.1:9000/internal?password=leak", + }), + }); + } + return originalFetch(url); + }; + fetchSetDefaults({ headers: { Accept: "application/json" } }); + try { + const stream = fetchResponseStream([{ url: secretUrl }]); + await streamToArray(stream); + throw new Error("Should have thrown"); + } catch (error) { + ok( + !error.message.includes("token=abc123"), + "redirect error leaked source token", + ); + ok( + !error.message.includes("password=leak"), + "redirect error leaked destination secret", + ); + ok( + !String(error.cause?.url ?? "").includes("token=abc123"), + `cause.url leaked source token: ${error.cause?.url}`, + ); + ok( + !String(error.cause?.location ?? "").includes("password=leak"), + `cause.location leaked destination secret: ${error.cause?.location}`, + ); + } finally { + global.fetch = originalFetch; + fetchSetDefaults({ headers: { Accept: "application/json" } }); + } +}); + +test(`${variant}: fetchResponseStream should follow same-origin redirects`, async (_t) => { + const originalFetch = global.fetch; + global.fetch = async (url) => { + if (url === "https://example.org/redirect-same") { + return new Response("", { + status: 302, + statusText: "Found", + headers: new Headers({ + Location: "https://example.org/redirect-target", + }), + }); + } + if (url === "https://example.org/redirect-target") { + return new Response(JSON.stringify({ ok: true }), { + status: 200, + headers: new Headers({ "Content-Type": "application/json" }), + }); + } + return originalFetch(url); + }; + fetchSetDefaults({ dataPath: "", headers: { Accept: "application/json" } }); + try { + const stream = fetchResponseStream([ + { url: "https://example.org/redirect-same" }, + ]); + const output = await streamToArray(stream); + deepStrictEqual(output, [{ ok: true }]); + } finally { + global.fetch = originalFetch; + fetchSetDefaults({ + dataPath: undefined, + headers: { Accept: "application/json" }, + }); + } +}); + +test(`${variant}: fetchResponseStream should honor explicit redirect option (opt-in follow)`, async (_t) => { + const originalFetch = global.fetch; + let sawFollow = false; + global.fetch = async (url, init) => { + if (url === "https://example.org/redirect-optin") { + sawFollow = init.redirect === "follow"; + // With redirect:"follow" the platform resolves the redirect itself, + // so the mock just returns the final response. + return new Response(JSON.stringify({ ok: true }), { + status: 200, + headers: new Headers({ "Content-Type": "application/json" }), + }); + } + return originalFetch(url); + }; + fetchSetDefaults({ dataPath: "", headers: { Accept: "application/json" } }); + try { + const stream = fetchResponseStream([ + { url: "https://example.org/redirect-optin", redirect: "follow" }, + ]); + const output = await streamToArray(stream); + deepStrictEqual(output, [{ ok: true }]); + ok(sawFollow, "explicit redirect:follow was not passed through"); + } finally { + global.fetch = originalFetch; + fetchSetDefaults({ + dataPath: undefined, + headers: { Accept: "application/json" }, + }); + } +}); + // *** fetchWritableStream *** // test(`${variant}: fetchWritableStream should create writable stream for upload`, async (_t) => { const originalFetch = global.fetch; @@ -364,7 +597,47 @@ test(`${variant}: fetchWritableStream should create writable stream for upload`, global.fetch = originalFetch; }); -test(`${variant}: fetchRateLimit should handle rate limit delay`, async (_t) => { +test(`${variant}: fetchWritableStream should close the request body on end`, async (_t) => { + const originalFetch = global.fetch; + + let resolveBody; + const bodyDone = new Promise((resolve) => { + resolveBody = resolve; + }); + + global.fetch = async (_url, options) => { + // Drain the duplex request body to completion in the background. + // If end-of-body is never signaled, this never resolves and the + // test times out. + (async () => { + const received = []; + for await (const chunk of options.body) { + received.push(chunk); + } + resolveBody(received); + })(); + return new Response(JSON.stringify({ uploaded: true }), { + status: 200, + headers: new Headers({ "Content-Type": "application/json" }), + }); + }; + + const stream = await fetchWritableStream({ + url: "https://example.org/upload", + method: "POST", + }); + + stream.write("alpha"); + stream.write("beta"); + stream.end(); + + const received = await bodyDone; + deepStrictEqual(received, ["alpha", "beta"]); + + global.fetch = originalFetch; +}); + +test(`${variant}: fetchRateLimit should delay between configs within one stream`, async (_t) => { const originalFetch = global.fetch; const fetchCallTimes = []; @@ -376,21 +649,46 @@ test(`${variant}: fetchRateLimit should handle rate limit delay`, async (_t) => }); }; - fetchSetDefaults({ rateLimit: 0.1 }); // 100ms delay - - const config1 = [{ url: "https://example.org/test1" }]; - const stream1 = fetchResponseStream(config1); - await streamToArray(stream1); - - const config2 = [{ url: "https://example.org/test2" }]; - const stream2 = fetchResponseStream(config2); - await streamToArray(stream2); + // A single config array of >=2 entries so the in-generator + // rateLimitTimestamp carries over between the two requests. + const config = [ + { url: "https://example.org/test1", rateLimit: 0.1, dataPath: "" }, + { url: "https://example.org/test2", rateLimit: 0.1, dataPath: "" }, + ]; + const stream = fetchResponseStream(config); + await streamToArray(stream); global.fetch = originalFetch; - fetchSetDefaults({ rateLimit: 0.01 }); // Reset to default - // Second call should have been delayed strictEqual(fetchCallTimes.length, 2); + // rateLimit 0.1 => ~100ms enforced delay between the two calls. + ok( + fetchCallTimes[1] - fetchCallTimes[0] >= 90, + `expected >=~100ms delay between configs, got ${ + fetchCallTimes[1] - fetchCallTimes[0] + }ms`, + ); +}); + +test(`${variant}: fetchRateLimit direct call defaults rateLimit before computing timestamp`, async (_t) => { + const { fetchRateLimit } = await import("@datastream/fetch"); + const originalFetch = global.fetch; + global.fetch = async () => + new Response(JSON.stringify({ ok: true }), { + status: 200, + headers: new Headers({ "Content-Type": "application/json" }), + }); + try { + // Direct call with no rateLimit in options: timestamp must NOT be NaN. + const options = { url: "https://example.org/direct-rl" }; + await fetchRateLimit(options); + ok( + Number.isFinite(options.rateLimitTimestamp), + `rateLimitTimestamp should be finite, got ${options.rateLimitTimestamp}`, + ); + } finally { + global.fetch = originalFetch; + } }); test(`${variant}: fetchResponseStream should handle content-type with suffix`, async (_t) => { @@ -504,6 +802,54 @@ test(`${variant}: fetchRateLimit should throw after max retries on persistent 42 } }); +// *** JSON pagination cleanup on downstream error *** // +test(`${variant}: fetchResponseStream should stop JSON pagination when consumer errors`, async (_t) => { + const originalFetch = global.fetch; + let page2Fetched = false; + global.fetch = async (url) => { + if (url === "https://example.org/cancel-json/1") { + return new Response( + JSON.stringify({ + data: [{ id: 1 }, { id: 2 }], + next: "https://example.org/cancel-json/2", + }), + { + status: 200, + headers: new Headers({ "Content-Type": "application/json" }), + }, + ); + } + if (url === "https://example.org/cancel-json/2") { + page2Fetched = true; + return new Response(JSON.stringify({ data: [{ id: 3 }], next: "" }), { + status: 200, + headers: new Headers({ "Content-Type": "application/json" }), + }); + } + return originalFetch(url); + }; + + fetchSetDefaults({ dataPath: "data", nextPath: "next" }); + const failing = createTransformStream(() => { + throw new Error("downstream boom"); + }); + try { + await pipeline([ + fetchResponseStream({ url: "https://example.org/cancel-json/1" }), + failing, + ]); + throw new Error("Should have thrown"); + } catch (e) { + ok(e.message.includes("downstream boom")); + // On error, the JSON generator must be returned so pagination stops; + // page 2 must never be fetched. + strictEqual(page2Fetched, false); + } finally { + global.fetch = originalFetch; + fetchSetDefaults({ dataPath: undefined, nextPath: undefined }); + } +}); + // *** SSRF protection: same-origin pagination *** // test(`${variant}: fetchResponseStream should reject Link header with cross-origin URL`, async (_t) => { const originalFetch = global.fetch; @@ -653,3 +999,1406 @@ test(`${variant}: default export should include all stream functions`, (_t) => { "setDefaults", ]); }); + +// *** validatePaginationUrl: invalid URL catch block and error message *** // +test(`${variant}: fetchResponseStream should throw with message for invalid pagination URL in Link header`, async (_t) => { + const originalFetch = global.fetch; + global.fetch = async (url) => { + if (url === "https://example.org/bad-link") { + return new Response(JSON.stringify({ data: [{ id: 1 }] }), { + status: 200, + headers: new Headers({ + "Content-Type": "application/json", + Link: 'File system streams.
@@ -18,10 +18,10 @@
-
+
-
+
You can read the documentation at: https://datastream.js.org
diff --git a/packages/file/index.node.js b/packages/file/index.node.js index 66603c5..fda6ee9 100644 --- a/packages/file/index.node.js +++ b/packages/file/index.node.js @@ -33,12 +33,14 @@ export const fileWriteStream = ( if (basePath != null) { const fd = openSync( path, - constants.O_WRONLY | - constants.O_CREAT | - constants.O_TRUNC | - constants.O_NOFOLLOW, + constants.O_WRONLY | constants.O_CREAT | constants.O_NOFOLLOW, ); - return createWriteStream(null, { ...makeOptions(streamOptions), fd }); + // `flags` is ignored by createWriteStream when an `fd` is supplied (the + // file is already open), so it is omitted here. + return createWriteStream(null, { + ...makeOptions(streamOptions), + fd, + }); } return createWriteStream(path, makeOptions(streamOptions)); }; diff --git a/packages/file/index.test.js b/packages/file/index.test.js index 196cfa8..7b5a22a 100644 --- a/packages/file/index.test.js +++ b/packages/file/index.test.js @@ -1,7 +1,13 @@ // Copyright 2026 will Farrell, and datastream contributors. // SPDX-License-Identifier: MIT import { deepStrictEqual, strictEqual, throws } from "node:assert"; -import { mkdtempSync, rmSync, symlinkSync, writeFileSync } from "node:fs"; +import { + mkdtempSync, + readFileSync, + rmSync, + symlinkSync, + writeFileSync, +} from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; import test from "node:test"; @@ -38,6 +44,87 @@ test(`${variant}: fileReadStream should read a file`, async () => { strictEqual(output, testContent); }); +// *** fileReadStream with basePath - success case *** // +test(`${variant}: fileReadStream with basePath should read a file`, async () => { + const stream = fileReadStream({ path: testFile, basePath: testDir }); + const output = await streamToString(stream); + strictEqual(output, testContent); +}); + +// *** fileReadStream without basePath should follow symlinks *** // +test(`${variant}: fileReadStream without basePath can read through symlink`, async () => { + const linkPath = join(testDir, "sym-no-base.csv"); + try { + symlinkSync(testFile, linkPath); + } catch (_) { + // already exists + } + // Without basePath, no O_NOFOLLOW - symlinks are followed (read succeeds) + const stream = fileReadStream({ path: linkPath }); + const output = await streamToString(stream); + strictEqual(output, testContent); +}); + +// *** fileWriteStream without basePath - follows symlinks *** // +test(`${variant}: fileWriteStream without basePath can write through symlink`, async () => { + const outFile = join(testDir, "real-target.csv"); + writeFileSync(outFile, ""); + const writeLinkPath = join(testDir, "write-sym-no-base.csv"); + try { + symlinkSync(outFile, writeLinkPath); + } catch (_) { + // already exists + } + // Without basePath: no O_NOFOLLOW - symlinks are followed (write succeeds) + const stream = fileWriteStream({ path: writeLinkPath }); + await new Promise((resolve, reject) => { + stream.on("finish", resolve); + stream.on("error", reject); + stream.write(Buffer.from("via-symlink")); + stream.end(); + }); + strictEqual(readFileSync(outFile, "utf8"), "via-symlink"); +}); + +// *** fileWriteStream with basePath - success case *** // +test(`${variant}: fileWriteStream with basePath should write a new file`, async () => { + const outFile = join(testDir, "written.csv"); + const stream = fileWriteStream({ path: outFile, basePath: testDir }); + await new Promise((resolve, reject) => { + stream.on("finish", resolve); + stream.on("error", reject); + stream.write(Buffer.from("written content")); + stream.end(); + }); + strictEqual(readFileSync(outFile, "utf8"), "written content"); +}); + +// *** fileReadStream with basePath - streamOptions passed through *** // +test(`${variant}: fileReadStream with basePath passes streamOptions`, async () => { + const stream = fileReadStream( + { path: testFile, basePath: testDir }, + { highWaterMark: 1 }, + ); + const output = await streamToString(stream); + strictEqual(output, testContent); +}); + +// *** fileWriteStream with basePath - streamOptions passed through *** // +test(`${variant}: fileWriteStream with basePath passes streamOptions`, async () => { + const outFile = join(testDir, "opts.csv"); + const stream = fileWriteStream( + { path: outFile, basePath: testDir }, + { highWaterMark: 1 }, + ); + await new Promise((resolve, reject) => { + stream.on("finish", resolve); + stream.on("error", reject); + stream.write(Buffer.from("opts")); + stream.end(); + }); + strictEqual(readFileSync(outFile, "utf8"), "opts"); +}); + // *** Path traversal *** // test(`${variant}: fileReadStream should reject path traversal`, () => { throws(() => fileReadStream({ path: "/etc/passwd", basePath: testDir }), { @@ -71,15 +158,44 @@ test(`${variant}: fileReadStream should reject sibling-prefix bypass`, () => { ); }); +// *** Path traversal - basePath itself (rel === '') *** // +test(`${variant}: fileReadStream rejects when path equals basePath`, () => { + throws(() => fileReadStream({ path: testDir, basePath: testDir }), { + message: "Path traversal detected", + }); +}); + +test(`${variant}: fileWriteStream rejects when path equals basePath`, () => { + throws(() => fileWriteStream({ path: testDir, basePath: testDir }), { + message: "Path traversal detected", + }); +}); + // *** Symlink rejection *** // test(`${variant}: fileReadStream should reject symlinks`, () => { const linkPath = join(testDir, "link.csv"); - symlinkSync(testFile, linkPath); + try { + symlinkSync(testFile, linkPath); + } catch (_) { + // already exists + } throws(() => fileReadStream({ path: linkPath, basePath: testDir }), { message: "Symbolic links are not allowed", }); }); +test(`${variant}: fileWriteStream should reject symlinks`, () => { + const linkPath = join(testDir, "write-link.csv"); + try { + symlinkSync(testFile, linkPath); + } catch (_) { + // already exists + } + throws(() => fileWriteStream({ path: linkPath, basePath: testDir }), { + message: "Symbolic links are not allowed", + }); +}); + // *** Extension enforcement *** // test(`${variant}: fileReadStream should accept matching extension`, async () => { const stream = fileReadStream({ path: testFile, types: csvTypes }); @@ -108,12 +224,82 @@ test(`${variant}: fileWriteStream should reject non-matching extension`, () => { ); }); +// *** ENOENT is allowed (new file for write) *** // +test(`${variant}: fileWriteStream with basePath allows new file (ENOENT ok)`, async () => { + const outFile = join(testDir, "brand-new.csv"); + const stream = fileWriteStream({ path: outFile, basePath: testDir }); + await new Promise((resolve, reject) => { + stream.on("finish", resolve); + stream.on("error", reject); + stream.write(Buffer.from("new")); + stream.end(); + }); + strictEqual(readFileSync(outFile, "utf8"), "new"); +}); + +// *** Path not found for non-ENOENT stat errors *** // +test(`${variant}: fileReadStream throws Path not found for non-ENOENT stat error`, () => { + // testFile is a regular file, not a directory - accessing subpath causes ENOTDIR + const notDir = join(testFile, "inside.csv"); + throws(() => fileReadStream({ path: notDir, basePath: testDir }), { + message: "Path not found", + }); +}); + +// *** Path not found error has a cause *** // +test(`${variant}: fileReadStream Path not found error carries cause`, () => { + const notDir = join(testFile, "inside.csv"); + throws( + () => fileReadStream({ path: notDir, basePath: testDir }), + (e) => { + strictEqual(e.message, "Path not found"); + strictEqual(typeof e.cause, "object"); + return true; + }, + ); +}); + // *** No basePath = no path checks *** // test(`${variant}: fileReadStream allows any path without basePath`, async () => { const stream = fileReadStream({ path: testFile }); await streamToString(stream); }); +// *** fileWriteStream with basePath: failed constructor leaves existing file intact *** // +test(`${variant}: fileWriteStream with basePath preserves existing file when stream constructor fails`, () => { + const guardFile = join(testDir, "guard.csv"); + const originalContent = "important,data\n1,2,3\n"; + writeFileSync(guardFile, originalContent); + // {start:-5} is an invalid option that makes createWriteStream throw synchronously + throws( + () => + fileWriteStream({ path: guardFile, basePath: testDir }, { start: -5 }), + (e) => typeof e === "object" && e !== null, + ); + // The file must still contain its original content — not be wiped to zero bytes + strictEqual(readFileSync(guardFile, "utf8"), originalContent); +}); + +// *** fd-based streams when basePath is provided *** // +// When basePath is set, fileReadStream must use openSync+O_NOFOLLOW and pass the +// resulting fd to createReadStream (not the file path). The returned stream's .fd +// property is already a number in that case, whereas a path-based stream has .fd===null +// until the OS opens it. Mutants that skip the if(basePath!=null) block would produce +// a path-based stream whose .fd is null at construction time. +test(`${variant}: fileReadStream with basePath returns an fd-based stream`, () => { + const stream = fileReadStream({ path: testFile, basePath: testDir }); + strictEqual(typeof stream.fd, "number"); + stream.destroy(); +}); + +test(`${variant}: fileWriteStream with basePath returns an fd-based stream`, () => { + const outFile = join(testDir, "fd-write-check.csv"); + writeFileSync(outFile, ""); + const stream = fileWriteStream({ path: outFile, basePath: testDir }); + strictEqual(typeof stream.fd, "number"); + stream.destroy(); +}); + // *** default export *** // test(`${variant}: default export should include all stream functions`, () => { deepStrictEqual(Object.keys(fileDefault).sort(), [ diff --git a/packages/file/index.web.js b/packages/file/index.web.js index fbdc19c..95cd95a 100644 --- a/packages/file/index.web.js +++ b/packages/file/index.web.js @@ -2,9 +2,26 @@ // SPDX-License-Identifier: MIT import { createReadableStream } from "@datastream/core"; +const enforceType = (name, types = []) => { + if (!types.length) return; + const dotIdx = name.lastIndexOf("."); + const pathExt = dotIdx >= 0 ? name.slice(dotIdx) : ""; + for (const type of types) { + for (const mime in type.accept) { + for (const ext of type.accept[mime]) { + if (pathExt === ext) { + return; + } + } + } + } + throw new Error("Invalid extension"); +}; + export const fileReadStream = async ({ types }, _streamOptions = {}) => { const [fileHandle] = await window.showOpenFilePicker({ types }); const fileData = await fileHandle.getFile(); + enforceType(fileData.name, types); return createReadableStream(fileData); }; @@ -13,6 +30,7 @@ export const fileWriteStream = async ({ path, types }, _streamOptions = {}) => { suggestedName: path, types, }); + enforceType(fileHandle.name, types); return fileHandle.createWritable(); }; diff --git a/packages/file/package.json b/packages/file/package.json index ddc35a0..7567b05 100644 --- a/packages/file/package.json +++ b/packages/file/package.json @@ -39,6 +39,7 @@ "scripts": { "test": "npm run test:unit", "test:unit": "node --test", + "test:mutation": "cd ../.. && MUTATE_PACKAGE=\"$(basename \"$OLDPWD\")\" stryker run", "test:benchmark": "node __benchmarks__/index.js" }, "license": "MIT", diff --git a/packages/indexeddb/README.md b/packages/indexeddb/README.md index 826d3ba..a837b0b 100644 --- a/packages/indexeddb/README.md +++ b/packages/indexeddb/README.md @@ -1,6 +1,6 @@IndexedDB streams.
@@ -18,10 +18,10 @@
-
+
-
+
You can read the documentation at: https://datastream.js.org
diff --git a/packages/indexeddb/index.test.js b/packages/indexeddb/index.test.js index f281b81..25097d8 100644 --- a/packages/indexeddb/index.test.js +++ b/packages/indexeddb/index.test.js @@ -1,6 +1,6 @@ -import { deepStrictEqual, ok, strictEqual } from "node:assert"; +import { deepStrictEqual, ok, rejects, strictEqual } from "node:assert"; import test from "node:test"; -import { +import indexeddbDefault, { indexedDBReadStream, indexedDBWriteStream, } from "@datastream/indexeddb"; @@ -111,44 +111,237 @@ if (!isBrowser) { strictEqual(e.message, "indexedDBWriteStream: Not supported"); } }); + + test(`${variant}: default export should expose readStream and writeStream`, (_t) => { + strictEqual(typeof indexeddbDefault.readStream, "function"); + strictEqual(typeof indexeddbDefault.writeStream, "function"); + // They must be the named exports (same reference). + strictEqual(indexeddbDefault.readStream, indexedDBReadStream); + strictEqual(indexeddbDefault.writeStream, indexedDBWriteStream); + }); } -// *** web variant: indexedDBReadStream with index *** // -if (variant === "webstream") { - test(`${variant}: indexedDBReadStream should use index and key when provided`, { - skip: "requires web implementation", - }, async (_t) => { - const mockCursor = { - async *[Symbol.asyncIterator]() { - yield { id: 1, name: "a" }; - yield { id: 2, name: "b" }; - }, +// *** web variant: exercise the real web implementation directly *** // +// Per project memory, `--conditions=webstream` loads the node build, so the web +// code is exercised by importing `index.web.js` directly with mocked `idb` +// objects shaped like the real library (async iterators that yield IDBCursor +// objects exposing `.value`). +// +// NOTE: `streamToArray` uses event-based stream consumption which doesn't work +// under `--test-force-exit` (used by Stryker). Use `for await` instead so the +// test Promise settles before Node forces an exit. +const readAll = async (stream) => { + const out = []; + for await (const chunk of stream) { + out.push(chunk); + } + return out; +}; +{ + const { + indexedDBReadStream: webReadStream, + indexedDBWriteStream: webWriteStream, + } = await import("./index.web.js"); + + // Build a mock that mimics idb: stores/indexes return async iterators of + // IDBCursor-shaped objects ({ value }). `iterate(key)` filters by `name`. + const makeCursors = (records) => ({ + async *[Symbol.asyncIterator]() { + for (const record of records) { + yield { value: record }; + } + }, + }); + const makeStore = (records) => ({ + iterate: () => makeCursors(records), + index: (_name) => ({ + iterate: (key) => makeCursors(records.filter((r) => r.name === key)), + }), + add: async (record) => { + records.push(record); + }, + }); + const makeDb = (records, { onTransaction } = {}) => ({ + transaction: (_store, _mode) => { + onTransaction?.(); + return { store: makeStore(records), done: Promise.resolve() }; + }, + }); + + test(`web: indexedDBReadStream yields stored records (cursor.value), not raw cursors`, async (_t) => { + const records = [ + { id: 1, name: "a" }, + { id: 2, name: "b" }, + ]; + const stream = await webReadStream({ + db: makeDb(records), + store: "test", + }); + + const output = await readAll(stream); + + deepStrictEqual(output.length, 2); + // Real stored records, not IDBCursor objects. + deepStrictEqual(output[0], { id: 1, name: "a" }); + deepStrictEqual(output[1], { id: 2, name: "b" }); + // Guard against the regression of emitting the wrapping cursor object. + strictEqual(output[0].value, undefined); + }); + + test(`web: indexedDBReadStream uses index + key when provided`, async (_t) => { + const records = [ + { id: 1, name: "a" }, + { id: 2, name: "b" }, + { id: 3, name: "a" }, + ]; + const stream = await webReadStream({ + db: makeDb(records), + store: "test", + index: "name", + key: "a", + }); + + const output = await readAll(stream); + + // Only the two records whose name === "a" come back via the index. + strictEqual(output.length, 2); + deepStrictEqual(output[0], { id: 1, name: "a" }); + deepStrictEqual(output[1], { id: 3, name: "a" }); + }); + + test(`web: indexedDBReadStream uses the index for a falsy-but-valid key (0)`, async (_t) => { + // key === 0 is a valid IndexedDB key. The store records use name 0 vs 1. + const records = [ + { id: 1, name: 0 }, + { id: 2, name: 1 }, + { id: 3, name: 0 }, + ]; + const stream = await webReadStream({ + db: makeDb(records), + store: "test", + index: "name", + key: 0, + }); + + const output = await readAll(stream); + + // With the buggy `if (index && key)` guard, key 0 is falsy and the whole + // store (all 3) would be returned instead of the 2 name===0 records. + strictEqual(output.length, 2); + deepStrictEqual(output[0], { id: 1, name: 0 }); + deepStrictEqual(output[1], { id: 3, name: 0 }); + }); + + test(`web: indexedDBReadStream uses the index for an empty-string key ("")`, async (_t) => { + const records = [ + { id: 1, name: "" }, + { id: 2, name: "x" }, + ]; + const stream = await webReadStream({ + db: makeDb(records), + store: "test", + index: "name", + key: "", + }); + + const output = await readAll(stream); + + strictEqual(output.length, 1); + deepStrictEqual(output[0], { id: 1, name: "" }); + }); + + test(`web: indexedDBReadStream removes the abort listener on normal completion`, async (_t) => { + // Spy on a real AbortController's listener registration to assert the + // wrapper's own "abort" listener is removed once iteration settles, so a + // shared signal does not accumulate one listener per constructed stream. + const controller = new AbortController(); + const { signal } = controller; + let listeners = 0; + const realAdd = signal.addEventListener.bind(signal); + const realRemove = signal.removeEventListener.bind(signal); + signal.addEventListener = (...args) => { + listeners += 1; + return realAdd(...args); }; - const mockIndex = { - iterate: (_key) => mockCursor, + signal.removeEventListener = (...args) => { + listeners -= 1; + return realRemove(...args); }; - const mockStore = { - index: (_name) => mockIndex, - [Symbol.asyncIterator]: async function* () { - yield { id: 1, name: "a" }; - yield { id: 2, name: "b" }; - yield { id: 3, name: "c" }; + const records = [{ id: 1, name: "a" }]; + + const stream = await webReadStream( + { db: makeDb(records), store: "test" }, + { signal }, + ); + await readAll(stream); + // Allow the underlying stream's terminal "close" handlers to run so any + // listener teardown (wrapper + core) has settled before asserting. + await new Promise((resolve) => setImmediate(resolve)); + + // On normal completion every registered listener must be removed (the + // wrapper's "abort" listener leaked here before the fix). + strictEqual(listeners, 0); + }); + + test(`web: indexedDBReadStream stops iterating once the signal aborts`, async (_t) => { + const controller = new AbortController(); + let produced = 0; + const cursors = { + async *[Symbol.asyncIterator]() { + for (let id = 1; id <= 5; id++) { + produced += 1; + // Abort partway through to verify iteration breaks early. + if (id === 2) controller.abort(); + yield { value: { id } }; + } }, }; - const mockDb = { - transaction: (_store) => ({ store: mockStore }), + const db = { + transaction: () => ({ + store: { iterate: () => cursors, index: () => ({}) }, + done: Promise.resolve(), + }), }; - const stream = await indexedDBReadStream({ - db: mockDb, - store: "test", - index: "name", - key: "a", + const stream = await webReadStream( + { db, store: "test" }, + { signal: controller.signal }, + ); + + // Aborting must stop the stream rather than draining all 5 records. + await rejects( + async () => { + for await (const _ of stream) { + // drain + } + }, + { name: "AbortError" }, + ); + ok(produced < 5, `expected early stop, produced ${produced}`); + }); + + test(`web: indexedDBWriteStream opens a fresh transaction per chunk (no auto-commit reuse)`, async (_t) => { + // A shared transaction would auto-commit between async chunks and throw + // TransactionInactiveError. Assert each write gets its own transaction. + let transactions = 0; + const records = [ + { id: 1, value: "a" }, + { id: 2, value: "b" }, + { id: 3, value: "c" }, + ]; + const db = makeDb([], { + onTransaction: () => { + transactions += 1; + }, }); - const { streamToArray } = await import("@datastream/core"); - const output = await streamToArray(stream); - // Should return filtered results (2 items from index), not all 3 from store - strictEqual(output.length, 2); + const writeStream = await webWriteStream({ db, store: "test" }); + for (const record of records) { + writeStream.write(record); + } + writeStream.end(); + await new Promise((resolve) => writeStream.on("finish", resolve)); + + strictEqual(transactions, records.length); }); } diff --git a/packages/indexeddb/index.web.js b/packages/indexeddb/index.web.js index 33c813e..1000a5e 100644 --- a/packages/indexeddb/index.web.js +++ b/packages/indexeddb/index.web.js @@ -9,25 +9,61 @@ export const indexedDBReadStream = async ( { db, store, index, key }, streamOptions = {}, ) => { - let input = db.transaction(store).store; - if (index && key) { - input = input.index(index).iterate(key); + const tx = db.transaction(store); + let source = tx.store; + // A falsy-but-valid index key (0 or "") must still select the index. Only + // treat the index as absent when it is null/undefined, and only treat the + // key as omitted when it is strictly undefined (null is a valid key range). + if (index != null && key !== undefined) { + source = source.index(index).iterate(key); + } else { + source = source.iterate(); } - return createReadableStream(input, streamOptions); + const { signal } = streamOptions; + // idb's async iterators yield IDBCursor objects, not the stored records. + // Map each cursor to its `.value` before handing the source to the core + // stream factory; otherwise consumers receive raw cursors instead of data. + // Honor an AbortSignal by stopping iteration when it fires, and ALWAYS + // remove the listener once iteration settles so a shared signal does not + // accumulate one listener per stream (leak on normal completion). + const records = (async function* () { + let aborted = signal?.aborted ?? false; + let onAbort; + if (signal && !aborted) { + onAbort = () => { + aborted = true; + }; + signal.addEventListener("abort", onAbort, { once: true }); + } + try { + for await (const cursor of source) { + if (aborted) break; + yield cursor.value; + } + } finally { + if (signal && onAbort) { + signal.removeEventListener("abort", onAbort); + onAbort = undefined; + } + } + })(); + return createReadableStream(records, streamOptions); }; export const indexedDBWriteStream = async ( { db, store }, streamOptions = {}, ) => { - const tx = db.transaction(store, "readwrite"); + // A single shared transaction auto-commits as soon as it goes idle between + // async chunks, throwing TransactionInactiveError on the next write. Open a + // fresh readwrite transaction per chunk so each add() runs inside an active + // transaction, and await its completion to preserve ordering/backpressure. const write = async (chunk) => { + const tx = db.transaction(store, "readwrite"); await tx.store.add(chunk); - }; - const final = async () => { await tx.done; }; - return createWritableStream(write, final, streamOptions); + return createWritableStream(write, streamOptions); }; export default { diff --git a/packages/indexeddb/package.json b/packages/indexeddb/package.json index b0c0a59..de9137a 100644 --- a/packages/indexeddb/package.json +++ b/packages/indexeddb/package.json @@ -39,6 +39,7 @@ "scripts": { "test": "npm run test:unit", "test:unit": "node --test", + "test:mutation": "cd ../.. && MUTATE_PACKAGE=\"$(basename \"$OLDPWD\")\" stryker run", "test:benchmark": "node __benchmarks__/index.js" }, "license": "MIT", diff --git a/packages/ipfs/README.md b/packages/ipfs/README.md index 6c8002d..0a912ba 100644 --- a/packages/ipfs/README.md +++ b/packages/ipfs/README.md @@ -1,6 +1,6 @@IPFS streams.
@@ -18,10 +18,10 @@
-
+
-
+
You can read the documentation at: https://datastream.js.org
diff --git a/packages/ipfs/index.js b/packages/ipfs/index.js index e82382b..3ed38eb 100644 --- a/packages/ipfs/index.js +++ b/packages/ipfs/index.js @@ -1,28 +1,147 @@ // Copyright 2026 will Farrell, and datastream contributors. // SPDX-License-Identifier: MIT -import { createPassThroughStream } from "@datastream/core"; +import { + createPassThroughStream, + createReadableStream, +} from "@datastream/core"; -export const ipfsGetStream = async ({ node, cid }, _streamOptions = {}) => { - return node.get(cid); +export const ipfsGetStream = async ({ node, cid }, streamOptions = {}) => { + const source = await node.get(cid); + return createReadableStream(source, streamOptions); }; export const ipfsAddStream = async ( { node, resultKey } = {}, streamOptions = {}, ) => { - const chunks = []; let cid; - const stream = createPassThroughStream( - (chunk) => { - chunks.push(chunk); + // Bridge the pass-through's per-chunk callbacks into an async iterable so + // node.add consumes the stream incrementally instead of buffering it all + // in memory. A single-slot pull handshake gives real backpressure: each + // produced chunk is held until source() pulls it, so the transform's + // transform() callback only completes once node.add has consumed the chunk. + let slot; // the chunk currently waiting to be pulled, when filled === true + let filled = false; + let done = false; + let error; + // Set once node.add settles. A client may resolve without draining the + // source (it took what it needed); once that happens there is no consumer + // left to pull, so remaining chunks pass straight through without parking. + let consumerDone = false; + // Resolves when a produced chunk has been pulled by source() (back-pressure + // release for the producer). + let resolvePulled; + // Resolves when a chunk has been produced (or done/error set) for source(). + let resolveProduced; + const onProduced = () => { + resolveProduced?.(); + resolveProduced = undefined; + }; + const onPulled = () => { + resolvePulled?.(); + resolvePulled = undefined; + }; + + async function* source() { + while (true) { + if (error) throw error; + if (filled) { + const chunk = slot; + slot = undefined; + filled = false; + // Release the producer now that this chunk has been pulled. + onPulled(); + yield chunk; + continue; + } + if (done) return; + // Wait for the next chunk (or done/error) to be produced. + await new Promise((resolve) => { + resolveProduced = resolve; + }); + } + } + + // Kick off the add so it pulls from the source as chunks arrive. Wrap in + // Promise.resolve so a client whose add() returns synchronously (or any + // non-Promise thenable) is normalized — mirrors ipfsGetStream's `await + // node.get`, and avoids a cryptic "add(...).then is not a function". + const addPromise = Promise.resolve(node.add(source())).then( + (result) => { + // The consumer is finished; release any parked producer so a client + // that resolves without draining the source can't deadlock the + // transform. Do this before validating the shape so the producer is + // released even on a malformed result. + consumerDone = true; + onPulled(); + // Guard against a legacy / differently-shaped client that resolves + // without { cid }; surface a clear, actionable error instead of an + // opaque "Cannot read properties of undefined (reading 'cid')". + if (result == null || typeof result !== "object" || !("cid" in result)) { + throw new Error("node.add did not return { cid }"); + } + cid = result.cid; + }, + (e) => { + // Record the consumer failure so a still-blocked producer is released + // with the error instead of hanging. + error ??= e; + consumerDone = true; + onPulled(); + throw e; }, + ); + // Swallow the rejection on this reference; the flush() handler awaits and + // re-throws so the pipeline still sees it, but an unobserved teardown path + // must not surface an unhandled rejection. + addPromise.catch(() => {}); + + const stream = createPassThroughStream( + (chunk) => + // Park the chunk and resolve only once source() has pulled it. This + // awaited promise is what applies backpressure to upstream. + new Promise((resolve, reject) => { + if (error) { + reject(error); + return; + } + // No consumer left to pull (node.add already settled): pass + // through immediately instead of parking forever. + if (consumerDone) { + resolve(); + return; + } + slot = chunk; + filled = true; + onProduced(); + resolvePulled = () => { + if (error) reject(error); + else resolve(); + }; + }), async () => { - const result = await node.add(chunks); - cid = result.cid; + done = true; + onProduced(); + await addPromise; }, streamOptions, ); + // If the transform errors or is destroyed (e.g. aborted, or an upstream + // pipeline error tears it down), neither transform() nor flush() will run + // again. Inject the error into source() so the generator throws and + // node.add settles instead of stranding forever on a parked promise. + const teardown = (e) => { + if (done) return; + error ??= e ?? new Error("ipfsAddStream destroyed"); + // Wake both sides: source() so it throws, and any parked producer so its + // transform() callback rejects. + onProduced(); + onPulled(); + }; + stream.on("error", teardown); + stream.on("close", () => teardown()); + stream.result = () => ({ key: resultKey ?? "cid", value: cid, diff --git a/packages/ipfs/index.test.js b/packages/ipfs/index.test.js index fc24dd7..d446eef 100644 --- a/packages/ipfs/index.test.js +++ b/packages/ipfs/index.test.js @@ -1,9 +1,10 @@ // Copyright 2026 will Farrell, and datastream contributors. // SPDX-License-Identifier: MIT -import { deepStrictEqual, strictEqual } from "node:assert"; +import { deepStrictEqual, rejects, strictEqual } from "node:assert"; import test from "node:test"; import { createReadableStream, + isReadable, pipejoin, pipeline, streamToArray, @@ -56,13 +57,55 @@ test(`${variant}: ipfsGetStream should work in a pipeline`, async () => { deepStrictEqual(output, chunks); }); +test(`${variant}: ipfsGetStream should normalize a raw async iterable into a platform stream`, async () => { + // node.get can hand back whatever the client uses (here a bare async + // generator). ipfsGetStream must normalize it to a platform stream so + // downstream pipeline behavior is consistent across environments. + const node = { + get(_cid) { + return (async function* () { + yield "x"; + yield "y"; + })(); + }, + }; + const stream = await ipfsGetStream({ node, cid: "QmIter" }); + strictEqual(isReadable(stream), true); + const output = await streamToArray(stream); + deepStrictEqual(output, ["x", "y"]); +}); + +test(`${variant}: ipfsGetStream should await an async node.get (PromiseJSON and NDJSON (JSON Lines) parsing and formatting transform streams.
@@ -18,10 +18,10 @@
-
+
-
+
You can read the documentation at: https://datastream.js.org
diff --git a/packages/json/index.d.ts b/packages/json/index.d.ts index e223ced..72e4f31 100644 --- a/packages/json/index.d.ts +++ b/packages/json/index.d.ts @@ -24,7 +24,6 @@ export function ndjsonParseStream( export function ndjsonFormatStream( options?: { - space?: number | string; resultKey?: string; }, streamOptions?: StreamOptions, diff --git a/packages/json/index.test.js b/packages/json/index.test.js index 607820c..d29f127 100644 --- a/packages/json/index.test.js +++ b/packages/json/index.test.js @@ -344,3 +344,588 @@ test(`${variant}: jsonFormatStream roundtrip with jsonParseStream`, async (_t) = deepStrictEqual(output, input); }); + +// *** Additional tests to improve mutation score *** // + +// --- ndjsonParseStream: error deduplication (trackError guard) --- +test(`${variant}: ndjsonParseStream should accumulate idx list for repeated ParseError`, async (_t) => { + const parse = ndjsonParseStream(); + const streams = [createReadableStream("bad1\nbad2\nbad3\n"), parse]; + await streamToArray(pipejoin(streams)); + const { value } = parse.result(); + // All three errors under same ParseError key - idx has 3 entries + deepStrictEqual(value.ParseError.id, "ParseError"); + deepStrictEqual(value.ParseError.message, "Invalid JSON"); + deepStrictEqual(value.ParseError.idx, [0, 1, 2]); +}); + +// --- ndjsonParseStream: maxBufferSize boundary (> not >=) --- +test(`${variant}: ndjsonParseStream should not throw at exactly maxBufferSize`, async (_t) => { + // buffer.length + chunk.length > maxBufferSize: equal should NOT throw + const maxBufferSize = 10; + let error; + try { + await pipeline([ + createReadableStream("a".repeat(10)), + ndjsonParseStream({ maxBufferSize }), + ]); + } catch (e) { + error = e; + } + deepStrictEqual(error, undefined); +}); + +test(`${variant}: ndjsonParseStream should throw one byte over maxBufferSize`, async (_t) => { + // Two chunks: first 10 chars (no newline → stays in buffer), then 1 more → 11 > 10 + let error; + try { + await pipeline([ + createReadableStream(["a".repeat(10), "b"]), + ndjsonParseStream({ maxBufferSize: 10 }), + ]); + } catch (e) { + error = e; + } + deepStrictEqual(error?.message?.includes("maxBufferSize"), true); +}); + +// --- ndjsonParseStream: error message uses addition (not subtraction) --- +test(`${variant}: ndjsonParseStream error message contains combined length and limit`, async (_t) => { + let error; + try { + await pipeline([ + createReadableStream(["a".repeat(10), "b".repeat(5)]), + ndjsonParseStream({ maxBufferSize: 12 }), + ]); + } catch (e) { + error = e; + } + // buffer.length (10) + chunk.length (5) = 15; limit = 12 + deepStrictEqual(error?.message?.includes("15"), true); + deepStrictEqual(error?.message?.includes("12"), true); +}); + +// --- ndjsonParseStream: trimEnd (not trimStart) for lines --- +test(`${variant}: ndjsonParseStream flush trims trailing whitespace (\\r) on last line`, async (_t) => { + // No trailing newline; line ends with \r. trimEnd removes it, trimStart would not. + const streams = [createReadableStream('{"a":1}\r'), ndjsonParseStream()]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [{ a: 1 }]); +}); + +// --- ndjsonParseStream: flush catch block (not empty) --- +test(`${variant}: ndjsonParseStream flush should track error for invalid JSON without trailing newline`, async (_t) => { + const parse = ndjsonParseStream(); + const streams = [createReadableStream("not-json"), parse]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, []); + const { value } = parse.result(); + deepStrictEqual(value.ParseError?.id, "ParseError"); + deepStrictEqual(value.ParseError?.message, "Invalid JSON"); + deepStrictEqual(value.ParseError?.idx, [0]); +}); + +// --- ndjsonParseStream: flush idx++ (not --) --- +test(`${variant}: ndjsonParseStream flush should use correct idx for flushed error`, async (_t) => { + // One valid transform line, one invalid flush line → error at idx 1 + const parse = ndjsonParseStream(); + const streams = [createReadableStream('{"a":1}\nbad'), parse]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [{ a: 1 }]); + const { value } = parse.result(); + deepStrictEqual(value.ParseError.idx, [1]); +}); + +// --- ndjsonParseStream: resultKey --- +test(`${variant}: ndjsonParseStream should use custom resultKey`, async (_t) => { + const parse = ndjsonParseStream({ resultKey: "myErrors" }); + const streams = [createReadableStream('{"a":1}\n'), parse]; + await streamToArray(pipejoin(streams)); + const { key } = parse.result(); + deepStrictEqual(key, "myErrors"); +}); + +// --- ndjsonFormatStream: batching >= 64 --- +test(`${variant}: ndjsonFormatStream should flush eagerly after exactly 64 items`, async (_t) => { + const items = Array.from({ length: 64 }, (_, i) => ({ i })); + const streams = [createReadableStream(items), ndjsonFormatStream()]; + const combined = (await streamToArray(pipejoin(streams))).join(""); + const lines = combined.trim().split("\n"); + deepStrictEqual(lines.length, 64); + deepStrictEqual(JSON.parse(lines[0]), { i: 0 }); + deepStrictEqual(JSON.parse(lines[63]), { i: 63 }); +}); + +test(`${variant}: ndjsonFormatStream should handle 65 items (one full batch plus one)`, async (_t) => { + const items = Array.from({ length: 65 }, (_, i) => ({ i })); + const streams = [createReadableStream(items), ndjsonFormatStream()]; + const combined = (await streamToArray(pipejoin(streams))).join(""); + const lines = combined.trim().split("\n"); + deepStrictEqual(lines.length, 65); + deepStrictEqual(JSON.parse(lines[64]), { i: 64 }); +}); + +// --- ndjsonFormatStream: newline separator (not empty string) --- +test(`${variant}: ndjsonFormatStream items joined with newline separator`, async (_t) => { + const streams = [ + createReadableStream([{ a: 1 }, { b: 2 }]), + ndjsonFormatStream(), + ]; + const combined = (await streamToArray(pipejoin(streams))).join(""); + deepStrictEqual(combined.endsWith("\n"), true); + const lines = combined.split("\n").filter((l) => l.length > 0); + deepStrictEqual(lines.length, 2); + deepStrictEqual(lines[0], '{"a":1}'); + deepStrictEqual(lines[1], '{"b":2}'); +}); + +// --- ndjsonFormatStream: flush only when batch.length > 0 --- +test(`${variant}: ndjsonFormatStream should not emit anything when no items`, async (_t) => { + const streams = [createReadableStream([]), ndjsonFormatStream()]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, []); +}); + +test(`${variant}: ndjsonFormatStream should flush single item`, async (_t) => { + const streams = [createReadableStream([{ x: 42 }]), ndjsonFormatStream()]; + const combined = (await streamToArray(pipejoin(streams))).join(""); + deepStrictEqual(combined, '{"x":42}\n'); +}); + +// --- ndjsonFormatStream: space option --- +test(`${variant}: ndjsonFormatStream should use space option for pretty-printing`, async (_t) => { + const streams = [ + createReadableStream([{ a: 1 }]), + ndjsonFormatStream({ space: 2 }), + ]; + const combined = (await streamToArray(pipejoin(streams))).join(""); + deepStrictEqual(combined, '{\n "a": 1\n}\n'); +}); + +// --- jsonParseStream: trackError deduplication --- +test(`${variant}: jsonParseStream should accumulate idx list for repeated ParseError`, async (_t) => { + const parse = jsonParseStream(); + const streams = [createReadableStream("[bad1,bad2,bad3]"), parse]; + await streamToArray(pipejoin(streams)); + const { value } = parse.result(); + deepStrictEqual(value.ParseError.id, "ParseError"); + deepStrictEqual(value.ParseError.message, "Invalid JSON"); + deepStrictEqual(value.ParseError.idx, [0, 1, 2]); +}); + +// --- jsonParseStream: maxValueSize boundary (> not >=) --- +test(`${variant}: jsonParseStream should not throw at exactly maxValueSize`, async (_t) => { + // element "12345" is 5 chars, not > 5, should parse fine + const streams = [ + createReadableStream("[12345]"), + jsonParseStream({ maxValueSize: 5 }), + ]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [12345]); +}); + +test(`${variant}: jsonParseStream should throw when element exceeds maxValueSize`, async (_t) => { + // "[ 123456 ]" → raw element " 123456 " = 8 chars > 5 + let error; + try { + await pipeline([ + createReadableStream("[ 123456 ]"), + jsonParseStream({ maxValueSize: 5 }), + ]); + } catch (e) { + error = e; + } + deepStrictEqual(error?.message?.includes("maxValueSize"), true); +}); + +// --- jsonParseStream: emitElement trims text before parse --- +test(`${variant}: jsonParseStream should skip whitespace-only elements without error`, async (_t) => { + // Exercises trimmed.length === 0 early return in emitElement + const streams = [createReadableStream("[ ]"), jsonParseStream()]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, []); +}); + +// --- jsonParseStream: escaped char handling --- +test(`${variant}: jsonParseStream should handle escaped quote in string`, async (_t) => { + const streams = [createReadableStream('[{"a":"x\\"y"}]'), jsonParseStream()]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [{ a: 'x"y' }]); +}); + +test(`${variant}: jsonParseStream should handle double backslash in string`, async (_t) => { + const streams = [createReadableStream('[{"a":"\\\\"}]'), jsonParseStream()]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [{ a: "\\" }]); +}); + +// --- jsonParseStream: inString prevents depth changes for brackets in strings --- +test(`${variant}: jsonParseStream should not count brackets inside strings as depth`, async (_t) => { + const streams = [ + createReadableStream('[{"a":"[{nested}]"}]'), + jsonParseStream(), + ]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [{ a: "[{nested}]" }]); +}); + +// --- jsonParseStream: string as top-level element (opens inString) --- +test(`${variant}: jsonParseStream should parse string elements at top level`, async (_t) => { + const streams = [ + createReadableStream('["hello","world"]'), + jsonParseStream(), + ]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, ["hello", "world"]); +}); + +// --- jsonParseStream: whitespace chars (tab 0x09, LF 0x0a, CR 0x0d) --- +test(`${variant}: jsonParseStream should treat tab as whitespace before elements`, async (_t) => { + const streams = [createReadableStream("[1,\t2,\t3]"), jsonParseStream()]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [1, 2, 3]); +}); + +test(`${variant}: jsonParseStream should treat CR as whitespace before elements`, async (_t) => { + const streams = [createReadableStream("[1,\r2,\r3]"), jsonParseStream()]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [1, 2, 3]); +}); + +// --- jsonParseStream: buffer trimming (trimFrom) --- +test(`${variant}: jsonParseStream should work correctly with many small chunks`, async (_t) => { + const chunks = ["[", '{"a":', "1}", ",", '{"b":', "2}", "]"]; + const streams = [createReadableStream(chunks), jsonParseStream()]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [{ a: 1 }, { b: 2 }]); +}); + +test(`${variant}: jsonParseStream should handle multiple elements across chunks`, async (_t) => { + const chunks = ['[{"a":1},', '{"b":2},', '{"c":3}]']; + const streams = [createReadableStream(chunks), jsonParseStream()]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [{ a: 1 }, { b: 2 }, { c: 3 }]); +}); + +// --- jsonParseStream: flush ']' guard --- +test(`${variant}: jsonParseStream flush should not emit lone closing bracket as element`, async (_t) => { + const streams = [createReadableStream("[1,2]"), jsonParseStream()]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [1, 2]); +}); + +// --- jsonParseStream: sawNonWhitespace for NoArrayStart --- +test(`${variant}: jsonParseStream whitespace-only input should not flag NoArrayStart`, async (_t) => { + const parse = jsonParseStream(); + const streams = [createReadableStream(" \n\t "), parse]; + await streamToArray(pipejoin(streams)); + const { value } = parse.result(); + deepStrictEqual(value.NoArrayStart, undefined); +}); + +test(`${variant}: jsonParseStream non-whitespace without [ should flag NoArrayStart with message`, async (_t) => { + const parse = jsonParseStream(); + const streams = [createReadableStream("abc"), parse]; + await streamToArray(pipejoin(streams)); + const { value } = parse.result(); + deepStrictEqual(value.NoArrayStart?.id, "NoArrayStart"); + deepStrictEqual( + value.NoArrayStart?.message, + "Input did not contain a top-level array", + ); +}); + +// --- jsonParseStream: maxBufferSize error message uses addition --- +test(`${variant}: jsonParseStream maxBufferSize error message contains combined length`, async (_t) => { + let error; + try { + await pipeline([ + createReadableStream(`[{"a":"${"x".repeat(10)}"}]`), + jsonParseStream({ maxBufferSize: 15 }), + ]); + } catch (e) { + error = e; + } + deepStrictEqual(error?.message?.includes("maxBufferSize"), true); + // The message includes the buffer + chunk length (not subtraction) + // Since "[{\"a\":\"" = 7 chars stays in buffer, then adding more chars triggers limit + // Just verify the format matches expected pattern + deepStrictEqual(error?.message?.includes("exceeds"), true); +}); + +// --- jsonParseStream: flush handles no elementStart gracefully --- +test(`${variant}: jsonParseStream flush with no elementStart does not crash`, async (_t) => { + const streams = [createReadableStream('[{"a":1}]'), jsonParseStream()]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [{ a: 1 }]); +}); + +// --- jsonParseStream: depth tracking --- +test(`${variant}: jsonParseStream should parse deeply nested objects`, async (_t) => { + const streams = [ + createReadableStream('[{"a":{"b":{"c":1}}}]'), + jsonParseStream(), + ]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [{ a: { b: { c: 1 } } }]); +}); + +// --- jsonParseStream: error idx ordering --- +test(`${variant}: jsonParseStream error idx should reflect insertion order`, async (_t) => { + const parse = jsonParseStream(); + const streams = [ + createReadableStream('[{"a":1},bad,{"b":2},worse,{"c":3}]'), + parse, + ]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [{ a: 1 }, { b: 2 }, { c: 3 }]); + const { value } = parse.result(); + deepStrictEqual(value.ParseError.idx, [1, 3]); +}); + +// --- jsonParseStream: resultKey --- +test(`${variant}: jsonParseStream should use custom resultKey`, async (_t) => { + const parse = jsonParseStream({ resultKey: "myErrors" }); + const streams = [createReadableStream('[{"a":1}]'), parse]; + await streamToArray(pipejoin(streams)); + const { key } = parse.result(); + deepStrictEqual(key, "myErrors"); +}); + +// --- jsonFormatStream: first/non-first item separator --- +test(`${variant}: jsonFormatStream first element uses [ prefix; rest use comma-newline`, async (_t) => { + const streams = [ + createReadableStream([{ a: 1 }, { b: 2 }, { c: 3 }]), + jsonFormatStream(), + ]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output[0], '[{"a":1}'); + deepStrictEqual(output[1], ',\n{"b":2}'); + deepStrictEqual(output[2], ',\n{"c":3}'); +}); + +// --- jsonFormatStream: flush emits \n] for non-empty --- +test(`${variant}: jsonFormatStream flush emits newline-bracket for non-empty stream`, async (_t) => { + const streams = [createReadableStream([{ a: 1 }]), jsonFormatStream()]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output[output.length - 1], "\n]"); +}); + +test(`${variant}: jsonFormatStream single number produces correct JSON array`, async (_t) => { + const streams = [createReadableStream([42]), jsonFormatStream()]; + const combined = (await streamToArray(pipejoin(streams))).join(""); + deepStrictEqual(combined, "[42\n]"); +}); + +// --- jsonParseStream: mixed object and string elements --- +test(`${variant}: jsonParseStream should parse mixed object and string elements`, async (_t) => { + const streams = [ + createReadableStream('[{"a":1},"hello"]'), + jsonParseStream(), + ]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [{ a: 1 }, "hello"]); +}); + +// --- jsonParseStream: flush emitElement with ']' trimmed --- +test(`${variant}: jsonParseStream flush should emit incomplete element at end of stream`, async (_t) => { + // Input split across chunks where last chunk has no closing bracket scanned + // to exercise flush emitElement path + const streams = [ + createReadableStream(['[{"a":1},', '{"b":2']), + jsonParseStream(), + ]; + const output = await streamToArray(pipejoin(streams)); + // {"b":2 is incomplete JSON but flush emits it, parse fails → tracked as error + deepStrictEqual(output, [{ a: 1 }]); + // The incomplete element causes a ParseError +}); + +// --- ndjsonParseStream: transform empty line skip guard --- +test(`${variant}: ndjsonParseStream should count idx correctly when skipping empty lines`, async (_t) => { + // Two valid lines with empty lines in between + // Empty lines don't increment idx, so second parse error should be at idx 1 + const parse = ndjsonParseStream(); + const streams = [createReadableStream('{"a":1}\n\nbad\n{"c":3}\n'), parse]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [{ a: 1 }, { c: 3 }]); + const { value } = parse.result(); + deepStrictEqual(value.ParseError.idx, [1]); +}); + +// --- jsonParseStream: flush element with actual content --- +test(`${variant}: jsonParseStream flush emits element for incomplete array without closing bracket`, async (_t) => { + // Array missing closing ] - flush should emit what it has + const parse = jsonParseStream(); + const streams = [createReadableStream('[{"a":1},{"b":2}'), parse]; + const output = await streamToArray(pipejoin(streams)); + // {"a":1} is emitted during scan; {"b":2} has no closing } so it stays in buffer + // flush tries to emit the remaining element + deepStrictEqual(output.length >= 1, true); + deepStrictEqual(output[0], { a: 1 }); +}); + +// *** Second-round targeted tests for remaining survivors *** // + +// --- ndjsonFormatStream: chunk count distinguishes >= 64 from > 64 --- +test(`${variant}: ndjsonFormatStream 65 items should produce 2 output chunks`, async (_t) => { + // Real (>= 64): at item 64, eager flush -> 64-item chunk; flush() -> 1-item chunk -> 2 chunks + // Mutant (> 64): at item 65, eager flush -> 65-item chunk; flush() nothing -> 1 chunk + const items = Array.from({ length: 65 }, (_, i) => ({ i })); + const streams = [createReadableStream(items), ndjsonFormatStream()]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output.length, 2); + const firstChunkLines = output[0].split("\n").filter((l) => l.length > 0); + deepStrictEqual(firstChunkLines.length, 64); + const secondChunkLines = output[1].split("\n").filter((l) => l.length > 0); + deepStrictEqual(secondChunkLines.length, 1); +}); + +test(`${variant}: ndjsonFormatStream 2 items should produce 1 output chunk not 2`, async (_t) => { + // if(true) mutant: emits 1 item per chunk -> 2 chunks; real >= 64: via flush -> 1 chunk + const items = [{ a: 1 }, { b: 2 }]; + const streams = [createReadableStream(items), ndjsonFormatStream()]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output.length, 1); + const lines = output[0].split("\n").filter((l) => l.length > 0); + deepStrictEqual(lines.length, 2); +}); + +// --- ndjsonParseStream: flush idx increments after multiple valid lines --- +test(`${variant}: ndjsonParseStream flush idx is 3 after 3 valid transform lines`, async (_t) => { + const parse = ndjsonParseStream(); + const streams = [ + createReadableStream('{"a":1}\n{"b":2}\n{"c":3}\nbad'), + parse, + ]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [{ a: 1 }, { b: 2 }, { c: 3 }]); + const { value } = parse.result(); + deepStrictEqual(value.ParseError.idx, [3]); +}); + +// --- jsonParseStream: initial buffer must be empty --- +test(`${variant}: jsonParseStream initial buffer must be empty string`, async (_t) => { + const parse = jsonParseStream(); + const streams = [createReadableStream("[1]"), parse]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [1]); + const { value } = parse.result(); + deepStrictEqual(value.NoArrayStart, undefined); +}); + +// --- jsonParseStream: inString=true when quote encountered --- +test(`${variant}: jsonParseStream handles string split across chunks`, async (_t) => { + const streams = [createReadableStream(['["hel', 'lo"]']), jsonParseStream()]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, ["hello"]); +}); + +test(`${variant}: jsonParseStream string with braces does not affect depth`, async (_t) => { + const streams = [createReadableStream('["a{b}c"]'), jsonParseStream()]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, ["a{b}c"]); +}); + +// --- jsonParseStream: maxBufferSize error uses addition not subtraction --- +test(`${variant}: jsonParseStream maxBufferSize error message uses addition`, async (_t) => { + // After "[1234" processed, buffer trimmed to "1234" (4 chars) + // Then ",5678]" (6 chars): 4+6=10 > 6; subtraction mutant: 4-6=-2 + let error; + try { + await pipeline([ + createReadableStream(["[1234", ",5678]"]), + jsonParseStream({ maxBufferSize: 6 }), + ]); + } catch (e) { + error = e; + } + deepStrictEqual(error?.message?.includes("maxBufferSize"), true); + deepStrictEqual(error?.message?.includes("10"), true); +}); + +// --- jsonParseStream: maxBufferSize boundary (> not >=) --- +test(`${variant}: jsonParseStream does not throw at exactly maxBufferSize`, async (_t) => { + const streams = [ + createReadableStream("[1]"), + jsonParseStream({ maxBufferSize: 3 }), + ]; + let error; + try { + await streamToArray(pipejoin(streams)); + } catch (e) { + error = e; + } + deepStrictEqual(error, undefined); +}); + +test(`${variant}: jsonParseStream throws one byte over maxBufferSize`, async (_t) => { + let error; + try { + await pipeline([ + createReadableStream(["[1", ",2]"]), + jsonParseStream({ maxBufferSize: 2 }), + ]); + } catch (e) { + error = e; + } + deepStrictEqual(error?.message?.includes("maxBufferSize"), true); +}); + +// --- jsonParseStream flush: does not emit when elementStart === -1 --- +test(`${variant}: jsonParseStream flush does not double-emit completed elements`, async (_t) => { + const streams = [createReadableStream("[1,2]"), jsonParseStream()]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [1, 2]); + deepStrictEqual(output.length, 2); +}); + +// --- jsonParseStream flush: emits when elementStart !== -1 and buffer non-empty --- +test(`${variant}: jsonParseStream flush emits in-progress element`, async (_t) => { + const parse = jsonParseStream(); + const streams = [createReadableStream("[42"), parse]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [42]); +}); + +test(`${variant}: jsonParseStream flush uses elementStart offset correctly`, async (_t) => { + const parse = jsonParseStream(); + const streams = [createReadableStream("[ 42"), parse]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [42]); +}); + +// --- jsonParseStream flush: trimmed !== "]" --- +test(`${variant}: jsonParseStream flush does not emit lone closing bracket`, async (_t) => { + const streams = [createReadableStream("[1]"), jsonParseStream()]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [1]); + deepStrictEqual(output.length, 1); +}); + +// --- jsonParseStream flush: buffer reset to empty --- +test(`${variant}: jsonParseStream flush resets buffer to empty string`, async (_t) => { + const parse = jsonParseStream(); + const streams = [createReadableStream("[1,2,3]"), parse]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [1, 2, 3]); + const { value } = parse.result(); + deepStrictEqual(value.NoArrayStart, undefined); + deepStrictEqual(value.ParseError, undefined); +}); + +// --- jsonParseStream: single-char chunking exercises trimFrom --- +test(`${variant}: jsonParseStream handles single-char chunking`, async (_t) => { + const jsonStr = "[1,2,3,4,5]"; + const chunks = jsonStr.split(""); + const streams = [createReadableStream(chunks), jsonParseStream()]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [1, 2, 3, 4, 5]); +}); + +// --- jsonParseStream: element with surrounding whitespace (trim in emitElement) --- +test(`${variant}: jsonParseStream correctly parses element with surrounding spaces`, async (_t) => { + const streams = [createReadableStream("[ 42 ]"), jsonParseStream()]; + const output = await streamToArray(pipejoin(streams)); + deepStrictEqual(output, [42]); +}); diff --git a/packages/json/package.json b/packages/json/package.json index f14b946..88a50a6 100644 --- a/packages/json/package.json +++ b/packages/json/package.json @@ -39,6 +39,7 @@ "scripts": { "test": "npm run test:unit", "test:unit": "node --test", + "test:mutation": "cd ../.. && MUTATE_PACKAGE=\"$(basename \"$OLDPWD\")\" stryker run", "test:benchmark": "node __benchmarks__/index.js" }, "license": "MIT", diff --git a/packages/object/README.md b/packages/object/README.md index 915d58f..0b41113 100644 --- a/packages/object/README.md +++ b/packages/object/README.md @@ -1,6 +1,6 @@Object manipulation streams.
@@ -18,10 +18,10 @@
-
+
-
+
You can read the documentation at: https://datastream.js.org
diff --git a/packages/object/index.js b/packages/object/index.js index 61cec69..17b43fc 100644 --- a/packages/object/index.js +++ b/packages/object/index.js @@ -31,7 +31,7 @@ export const objectBatchStream = ( let previousId; let batch; const transform = (chunk, enqueue) => { - const id = keys.map((key) => chunk[key]).join(" "); + const id = JSON.stringify(keys.map((key) => chunk[key])); if (previousId !== id) { if (batch) { enqueue(batch); @@ -163,7 +163,9 @@ export const objectKeyMapStream = ({ keys }, streamOptions = {}) => { export const objectValueMapStream = ({ key, values }, streamOptions = {}) => { const transform = (chunk, enqueue) => { - chunk[key] = values[chunk[key]]; + if (Object.hasOwn(values, chunk[key])) { + chunk[key] = values[chunk[key]]; + } enqueue(chunk); }; return createTransformStream(transform, streamOptions); diff --git a/packages/object/index.test.js b/packages/object/index.test.js index 6c0a741..bc8271b 100644 --- a/packages/object/index.test.js +++ b/packages/object/index.test.js @@ -7,7 +7,7 @@ import { streamToArray, } from "@datastream/core"; -import { +import objectDefault, { objectBatchStream, objectCountStream, objectFromEntriesStream, @@ -557,6 +557,40 @@ test(`${variant}: objectBatchStream should enforce maxBatchSize`, async (_t) => ); }); +// *** objectBatchStream collision-proof grouping key *** // +test(`${variant}: objectBatchStream should keep distinct key tuples in separate batches when values contain spaces`, async (_t) => { + // ["a b","c"] and ["a","b c"] both join to "a b c" with space-delimiter — + // they must produce two separate batches, not one merged batch. + const input = [ + { x: "a b", y: "c" }, + { x: "a", y: "b c" }, + ]; + const streams = [ + createReadableStream(input), + objectBatchStream({ keys: ["x", "y"] }), + ]; + + const stream = pipejoin(streams); + const output = await streamToArray(stream); + + deepStrictEqual(output, [[{ x: "a b", y: "c" }], [{ x: "a", y: "b c" }]]); +}); + +// *** objectValueMapStream preserves unmapped keys *** // +test(`${variant}: objectValueMapStream should preserve the original value for keys not present in the map`, async (_t) => { + const input = [{ status: "active" }, { status: "unknown" }]; + const streams = [ + createReadableStream(input), + objectValueMapStream({ key: "status", values: { active: 1, inactive: 0 } }), + ]; + + const stream = pipejoin(streams); + const output = await streamToArray(stream); + + // "unknown" is not in the map — original value must be preserved + deepStrictEqual(output, [{ status: 1 }, { status: "unknown" }]); +}); + // *** objectPivotLongToWideStream should not mutate input *** // test(`${variant}: objectPivotLongToWideStream should not mutate input chunks`, async (_t) => { const input = [ @@ -579,3 +613,52 @@ test(`${variant}: objectPivotLongToWideStream should not mutate input chunks`, a // Original input[0][0] should be unchanged deepStrictEqual(input[0][0], originalFirst); }); + +// *** objectReadableStream default empty input *** // +test(`${variant}: objectReadableStream should produce empty output when called with no args`, async (_t) => { + const streams = [objectReadableStream()]; + const output = await streamToArray(streams[0]); + deepStrictEqual(output, []); +}); + +// *** objectBatchStream should produce no output on empty input *** // +test(`${variant}: objectBatchStream should produce no output when input is empty`, async (_t) => { + const streams = [ + createReadableStream([]), + objectBatchStream({ keys: ["a"] }), + ]; + const stream = pipejoin(streams); + const output = await streamToArray(stream); + deepStrictEqual(output, []); +}); + +// *** objectToEntriesStream should produce empty arrays when keys is empty *** // +test(`${variant}: objectToEntriesStream should produce empty array when keys is empty`, async (_t) => { + const input = [{ a: 1, b: 2 }]; + const streams = [ + createReadableStream(input), + objectToEntriesStream({ keys: [] }), + ]; + const stream = pipejoin(streams); + const output = await streamToArray(stream); + deepStrictEqual(output, [[]]); +}); + +// *** default export contains all stream factories *** // +test(`${variant}: default export should contain all stream factories`, async (_t) => { + strictEqual(typeof objectDefault.readableStream, "function"); + strictEqual(typeof objectDefault.countStream, "function"); + strictEqual(typeof objectDefault.pickStream, "function"); + strictEqual(typeof objectDefault.omitStream, "function"); + strictEqual(typeof objectDefault.batchStream, "function"); + strictEqual(typeof objectDefault.pivotLongToWideStream, "function"); + strictEqual(typeof objectDefault.pivotWideToLongStream, "function"); + strictEqual(typeof objectDefault.keyValueStream, "function"); + strictEqual(typeof objectDefault.keyValuesStream, "function"); + strictEqual(typeof objectDefault.keyJoinStream, "function"); + strictEqual(typeof objectDefault.keyMapStream, "function"); + strictEqual(typeof objectDefault.valueMapStream, "function"); + strictEqual(typeof objectDefault.fromEntriesStream, "function"); + strictEqual(typeof objectDefault.toEntriesStream, "function"); + strictEqual(typeof objectDefault.skipConsecutiveDuplicatesStream, "function"); +}); diff --git a/packages/object/package.json b/packages/object/package.json index c922759..ba8331b 100644 --- a/packages/object/package.json +++ b/packages/object/package.json @@ -39,6 +39,7 @@ "scripts": { "test": "npm run test:unit", "test:unit": "node --test", + "test:mutation": "cd ../.. && MUTATE_PACKAGE=\"$(basename \"$OLDPWD\")\" stryker run", "test:benchmark": "node __benchmarks__/index.js" }, "license": "MIT", diff --git a/packages/string/README.md b/packages/string/README.md index 9f86585..e630ed7 100644 --- a/packages/string/README.md +++ b/packages/string/README.md @@ -1,6 +1,6 @@String manipulation streams.
@@ -18,10 +18,10 @@
-
+
-
+
You can read the documentation at: https://datastream.js.org
diff --git a/packages/string/index.d.ts b/packages/string/index.d.ts index 0be1c1f..2ec80a4 100644 --- a/packages/string/index.d.ts +++ b/packages/string/index.d.ts @@ -32,24 +32,30 @@ export function stringCountStream( result: () => StreamResultJSON schema validation streams.
@@ -18,10 +18,10 @@
-
+
-
+
You can read the documentation at: https://datastream.js.org
diff --git a/packages/validate/index.js b/packages/validate/index.js index 56b65fb..5588449 100644 --- a/packages/validate/index.js +++ b/packages/validate/index.js @@ -26,9 +26,16 @@ export const validateStream = ( allowCoerceTypes, resultKey, maxErrorRows = Infinity, - }, + maxErrorKeys = 1000, + } = {}, streamOptions = {}, ) => { + if (!schema) { + throw new Error( + "validateStream requires a schema (JSON Schema object or compiled AJV function)", + ); + } + idxStart ??= 0; if (typeof schema !== "function") { @@ -36,18 +43,48 @@ export const validateStream = ( } const value = {}; // aka errors + let valueCount = 0; // track distinct id count without Object.keys() per error let idx = idxStart - 1; const transform = (chunk, enqueue) => { idx += 1; - const data = - allowCoerceTypes === false ? structuredClone(chunk) : undefined; - const chunkValid = schema(chunk); + + let emitChunk; + let validateTarget; + + if (allowCoerceTypes === false) { + // Validate on a clone so AJV coercion does not mutate the original. + // Emit the original (uncoerced) chunk. + try { + validateTarget = structuredClone(chunk); + } catch { + // Non-cloneable: fall back to validating the original (best-effort) + validateTarget = chunk; + } + emitChunk = chunk; + } else { + // Clone before validation so AJV coercion does not mutate caller's object. + // Emit the coerced clone. + try { + validateTarget = structuredClone(chunk); + } catch { + // Non-cloneable: validate the original (caller's object may be mutated) + validateTarget = chunk; + } + emitChunk = validateTarget; + } + + const chunkValid = schema(validateTarget); if (!chunkValid) { for (const error of schema.errors) { const { id, keys, message } = processError(error); if (!value[id]) { + // Stop creating new entries once maxErrorKeys cap is reached + if (valueCount >= maxErrorKeys) { + continue; + } value[id] = { id, keys, message, idx: [] }; + valueCount += 1; } if (value[id].idx.length < maxErrorRows) { value[id].idx.push(idx); @@ -55,7 +92,7 @@ export const validateStream = ( } } if (chunkValid || onErrorEnqueue) { - enqueue(data ?? chunk); + enqueue(emitChunk); } }; const stream = createTransformStream(transform, streamOptions); @@ -76,7 +113,8 @@ const processError = (error) => { }); keys = [...new Set(keys.sort())]; } else { - keys.push(makeKeys(error)); + const key = makeKeys(error); + if (key) keys.push(key); } if (!error.instancePath && keys.length) { id += `/${keys.join("|")}`; diff --git a/packages/validate/index.test.js b/packages/validate/index.test.js index 5f3eefc..7d399b7 100644 --- a/packages/validate/index.test.js +++ b/packages/validate/index.test.js @@ -368,8 +368,8 @@ test(`${variant}: validateStream should handle root-level type error`, async (_t ok(Object.keys(result.validate).length > 0); const errorKey = Object.keys(result.validate)[0]; - // makeKeys returns "" for root-level errors (empty instancePath) - deepStrictEqual(result.validate[errorKey].keys, [""]); + // root-level errors produce an empty makeKeys result; empty keys are filtered out + deepStrictEqual(result.validate[errorKey].keys, []); }); test(`${variant}: validateStream should handle errorMessage with root-level error`, async (_t) => { @@ -446,7 +446,330 @@ test(`${variant}: validateStream should cap error indices with maxErrorRows`, as ok(result.validate[errorKey].idx.length <= 10); }); +// *** maxErrorKeys *** // +test(`${variant}: validateStream should cap distinct error ids with maxErrorKeys`, async (_t) => { + // Feed 500 rows, each with a unique extra property name → would produce 500 distinct ids + const schema = { + type: "object", + additionalProperties: false, + properties: { a: { type: "number" } }, + }; + const input = Array.from({ length: 500 }, (_, i) => ({ + a: 1, + [`extra_${i}`]: i, + })); + const streams = [ + createReadableStream(input), + validateStream({ schema, maxErrorKeys: 50 }), + ]; + const result = await pipeline(streams); + + // Should never exceed maxErrorKeys distinct entries + ok(Object.keys(result.validate).length <= 50); +}); + +test(`${variant}: validateStream should default maxErrorKeys to 1000`, async (_t) => { + // 1500 rows each with a unique extra property → default cap of 1000 should kick in + const schema = { + type: "object", + additionalProperties: false, + properties: { a: { type: "number" } }, + }; + const input = Array.from({ length: 1500 }, (_, i) => ({ + a: 1, + [`extra_${i}`]: i, + })); + const streams = [createReadableStream(input), validateStream({ schema })]; + const result = await pipeline(streams); + + ok(Object.keys(result.validate).length <= 1000); +}); + +// *** allowCoerceTypes:false with non-cloneable chunks *** // +test(`${variant}: validateStream should not throw when allowCoerceTypes:false and chunk contains non-cloneable value`, async (_t) => { + const schema = { + type: "object", + properties: { a: { type: "number" } }, + required: ["a"], + }; + // Chunk with a function (not structuredClone-able) + const input = [{ a: 1, fn: () => {} }]; + + const streams = [ + createReadableStream(input), + validateStream({ schema, allowCoerceTypes: false }), + ]; + // Should not throw — should fall back to original chunk + const result = await pipeline(streams); + ok(result, "pipeline should complete without error"); +}); + +// *** root-level errors: no trailing-slash id, no empty-string key *** // +test(`${variant}: validateStream root-level error should not have trailing-slash id or empty-string key`, async (_t) => { + const schema = { type: "object" }; + const input = ["not-an-object"]; + const streams = [createReadableStream(input), validateStream({ schema })]; + const result = await pipeline(streams); + + ok(Object.keys(result.validate).length > 0); + for (const [id, entry] of Object.entries(result.validate)) { + // id must not end with '/' + strictEqual(id.endsWith("/"), false, `id '${id}' must not end with '/'`); + // keys must not include '' + strictEqual( + entry.keys.includes(""), + false, + `keys must not include empty string`, + ); + } +}); + +// *** default path should not mutate caller's input *** // +test(`${variant}: validateStream should emit a clone so caller input is not mutated`, async (_t) => { + // coerceTypes:true would mutate {a:'1'} → {a:1} on the original object + const original = { a: "1" }; + const input = [original]; + const schema = { + type: "object", + properties: { a: { type: "number" } }, + required: ["a"], + }; + + const streams = [createReadableStream(input), validateStream({ schema })]; + const output = await streamToArray(pipejoin(streams)); + + // The emitted chunk should be coerced + strictEqual(output[0].a, 1); + // But the original reference must NOT be mutated + strictEqual( + original.a, + "1", + "caller's original object must not be mutated in place", + ); +}); + +// *** no-schema branded error *** // +test(`${variant}: validateStream should throw a branded error when schema is missing`, (_t) => { + try { + validateStream({}); + ok(false, "should have thrown"); + } catch (err) { + ok( + err.message.includes("validateStream") && err.message.includes("schema"), + `expected branded error mentioning validateStream and schema, got: ${err.message}`, + ); + } +}); + // *** default export *** // test(`${variant}: default export should be validateStream`, (_t) => { strictEqual(validateDefault, validateStream); }); + +// *** transpileSchema strict:true mode *** // +test(`${variant}: transpileSchema should use strict:true by default and reject schemas with unknown keywords`, (_t) => { + // In strict mode, AJV throws on unknown keywords in schemas + let threw = false; + try { + transpileSchema({ type: "object", unknownKeyword: true }); + } catch { + threw = true; + } + // strict:false would silently accept unknown keywords; strict:true throws + strictEqual( + threw, + true, + "transpileSchema should throw on unknown keywords in strict mode", + ); +}); + +// *** transpileSchema useDefaults:"empty" *** // +test(`${variant}: transpileSchema should apply default values for empty strings (useDefaults:"empty")`, async (_t) => { + // useDefaults:"empty" fills defaults even when value is an empty string + const schema = { + type: "object", + properties: { + name: { type: "string", default: "fallback" }, + }, + }; + const input = [{ name: "" }]; + const streams = [createReadableStream(input), validateStream({ schema })]; + const output = await streamToArray(pipejoin(streams)); + // useDefaults:"empty" should replace empty string with the default + deepStrictEqual(output[0].name, "fallback"); +}); + +// *** catch block fallback: non-cloneable in allowCoerceTypes:false path *** // +test(`${variant}: validateStream allowCoerceTypes:false with non-cloneable chunk emits original chunk`, async (_t) => { + const schema = { + type: "object", + properties: { a: { type: "string" } }, + }; + const original = { a: "hello", fn: () => {} }; + const input = [original]; + const streams = [ + createReadableStream(input), + validateStream({ schema, allowCoerceTypes: false }), + ]; + const output = await streamToArray(pipejoin(streams)); + // Should emit the original object reference (the chunk itself, not a clone) + strictEqual( + output[0], + original, + "non-cloneable chunk should emit original reference when allowCoerceTypes:false", + ); + strictEqual(output[0].a, "hello"); +}); + +// *** catch block fallback: non-cloneable in default (coerce) path *** // +test(`${variant}: validateStream default coerce path with non-cloneable chunk still emits chunk`, async (_t) => { + const schema = { + type: "object", + properties: { a: { type: "string" } }, + }; + const original = { a: "hello", fn: () => {} }; + const input = [original]; + const streams = [createReadableStream(input), validateStream({ schema })]; + const output = await streamToArray(pipejoin(streams)); + // Should emit something (the original chunk when clone fails) + strictEqual(output[0].a, "hello"); +}); + +// *** if (!value[id]) guard: same error should accumulate idx, not reset *** // +test(`${variant}: validateStream should accumulate idx for repeated same-key errors`, async (_t) => { + // Multiple rows with same type error → same id → idx should accumulate + const input = [{ a: "bad" }, { a: "bad" }, { a: "bad" }]; + const schema = { + type: "object", + properties: { a: { type: "number" } }, + }; + const streams = [createReadableStream(input), validateStream({ schema })]; + const result = await pipeline(streams); + const errorKey = Object.keys(result.validate)[0]; + // All three rows should appear in idx + deepStrictEqual(result.validate[errorKey].idx, [0, 1, 2]); +}); + +// *** if (chunkValid || onErrorEnqueue): invalid items NOT enqueued by default *** // +test(`${variant}: validateStream should not enqueue invalid items when onErrorEnqueue is not set`, async (_t) => { + const input = [ + { a: "valid_number_string" }, + { a: "definitely-not-a-number" }, + ]; + const schema = { + type: "object", + properties: { a: { type: "number" } }, + }; + const streams = [createReadableStream(input), validateStream({ schema })]; + const stream = pipejoin(streams); + const output = await streamToArray(stream); + // Only valid (coerced) items should be emitted — "definitely-not-a-number" can't coerce + // "valid_number_string" also can't coerce; both invalid → output empty + deepStrictEqual(output.length, 0); +}); + +// *** errorMessage keyword: branch must populate keys from sub-errors *** // +test(`${variant}: validateStream errorMessage should collect keys from sub-errors`, async (_t) => { + const schema = { + type: "object", + properties: { + age: { type: "number" }, + }, + required: ["age"], + errorMessage: { + properties: { + age: "Age must be a number", + }, + }, + }; + const input = [{ age: "not-a-number" }]; + const streams = [createReadableStream(input), validateStream({ schema })]; + const result = await pipeline(streams); + + ok(Object.keys(result.validate).length > 0); + const errorEntry = result.validate["#/errorMessage"]; + ok(errorEntry, "errorMessage error entry should exist"); + // Keys should be populated from the sub-error (age) + ok( + errorEntry.keys.includes("age"), + `keys should include 'age', got: ${JSON.stringify(errorEntry.keys)}`, + ); + strictEqual(errorEntry.message, "Age must be a number"); +}); + +// *** errorMessage keys sorted and deduped *** // +test(`${variant}: validateStream errorMessage should sort keys alphabetically (z_field before a_field in required → sorted as a_field|z_field)`, async (_t) => { + // Required array has z_field FIRST so AJV returns sub-errors as [z_field, a_field]. + // The sort() must reorder them to [a_field, z_field] for the id to be correct. + const schema = { + type: "object", + properties: { + z_field: { type: "string" }, + a_field: { type: "string" }, + }, + required: ["z_field", "a_field"], + errorMessage: { + required: "Both fields are required", + }, + }; + const input = [{}]; + const streams = [createReadableStream(input), validateStream({ schema })]; + const result = await pipeline(streams); + + ok(Object.keys(result.validate).length > 0); + // Without sort: id would be "#/errorMessage/z_field|a_field" + // With sort: id must be "#/errorMessage/a_field|z_field" + const errorEntry = result.validate["#/errorMessage/a_field|z_field"]; + ok( + errorEntry, + "error entry id '#/errorMessage/a_field|z_field' must exist (keys sorted)", + ); + deepStrictEqual(errorEntry.keys, ["a_field", "z_field"]); + strictEqual(errorEntry.message, "Both fields are required"); +}); + +// *** errorMessage: falsy makeKeys values should NOT be pushed into keys *** // +test(`${variant}: validateStream errorMessage sub-errors with empty instancePath produce no empty string keys`, async (_t) => { + const schema = { + type: "object", + errorMessage: "Must be an object", + }; + const input = ["not-an-object"]; + const streams = [createReadableStream(input), validateStream({ schema })]; + const result = await pipeline(streams); + + ok(Object.keys(result.validate).length > 0); + for (const entry of Object.values(result.validate)) { + strictEqual( + entry.keys.includes(""), + false, + "keys must not include empty string from errorMessage sub-errors", + ); + } +}); + +// *** id suffix: multiple keys joined with "|" not "" *** // +test(`${variant}: validateStream error id should join multiple keys with pipe separator`, async (_t) => { + // Use required errorMessage with two required fields. Both missing → two sub-errors + // → keys = ["a_field", "b_field"] → id = "#/errorMessage/a_field|b_field" + const schema = { + type: "object", + properties: { + b_field: { type: "string" }, + a_field: { type: "string" }, + }, + required: ["a_field", "b_field"], + errorMessage: { + required: "Fields a_field and b_field are required", + }, + }; + const input = [{}]; + const streams = [createReadableStream(input), validateStream({ schema })]; + const result = await pipeline(streams); + + // The entry id MUST be "#/errorMessage/a_field|b_field" — pipe not empty-string join + const errorEntry = result.validate["#/errorMessage/a_field|b_field"]; + ok(errorEntry, "error entry id '#/errorMessage/a_field|b_field' must exist"); + deepStrictEqual(errorEntry.keys, ["a_field", "b_field"]); + strictEqual(errorEntry.message, "Fields a_field and b_field are required"); +}); diff --git a/packages/validate/package.json b/packages/validate/package.json index b91380a..9447742 100644 --- a/packages/validate/package.json +++ b/packages/validate/package.json @@ -39,6 +39,7 @@ "scripts": { "test": "npm run test:unit", "test:unit": "node --test", + "test:mutation": "cd ../.. && MUTATE_PACKAGE=\"$(basename \"$OLDPWD\")\" stryker run", "test:benchmark": "node __benchmarks__/index.js" }, "license": "MIT", diff --git a/stryker.config.mjs b/stryker.config.mjs new file mode 100644 index 0000000..d907e1a --- /dev/null +++ b/stryker.config.mjs @@ -0,0 +1,21 @@ +// Copyright 2026 will Farrell, and datastream contributors. +// SPDX-License-Identifier: MIT +const pkg = process.env.MUTATE_PACKAGE; +const base = pkg ? `packages/${pkg}` : "packages"; + +/** @type {import('@stryker-mutator/api/core').PartialStrykerOptions} */ +export default { + packageManager: "npm", + testRunner: "command", + commandRunner: { + command: `node --test --conditions=node --test-force-exit ./${base}/**/*.test.js`, + }, + coverageAnalysis: "off", + mutate: [`${base}/**/*.node.mjs`, "!**/*.map", "!**/node_modules/**"], + plugins: ["@stryker-mutator/*"], + reporters: ["progress", "clear-text"], + thresholds: { high: 100, low: 100, break: 100 }, + tempDirName: pkg + ? `/tmp/stryker/@datastream/${pkg}` + : "/tmp/stryker/@datastream", +}; From 75f016e51375414fb3ec964e351fae0c411ddb4f Mon Sep 17 00:00:00 2001 From: will Farrell` guard (space/tab/LF/CR). ---
+const whitespaceLeadCases = {
+ space: "[ 123]",
+ tab: "[\t\t\t\t123]",
+ "line feed": "[\n\n\n\n123]",
+ "carriage return": "[\r\r\r\r123]",
+};
+for (const [name, input] of Object.entries(whitespaceLeadCases)) {
+ test(`${variant}: jsonParseStream skips leading ${name} so raw value stays within maxValueSize`, async (_t) => {
+ // trimmed "123" = 3 chars (<= 5); padded " 123" = 7 chars (> 5).
+ const streams = [
+ createReadableStream(input),
+ jsonParseStream({ maxValueSize: 5 }),
+ ];
+ const output = await streamToArray(pipejoin(streams));
+ deepStrictEqual(output, [123]);
+ });
+}
+
+// --- scanner buffer trim: after each fully-consumed element the processed
+// portion must be trimmed from the buffer so it does not grow unbounded. With a
+// small maxBufferSize, 50+ tiny elements split across chunks only fit if the
+// buffer is trimmed (kills the `trimFrom` ternary and the unconditional trim
+// being skipped). ---
+test(`${variant}: jsonParseStream trims consumed buffer so many chunks fit a small maxBufferSize`, async (_t) => {
+ const chunks = ["["];
+ for (let i = 0; i < 50; i++) chunks.push("1,");
+ chunks.push("1]");
+ const parse = jsonParseStream({ maxBufferSize: 10 });
+ const output = await streamToArray(
+ pipejoin([createReadableStream(chunks), parse]),
+ );
+ deepStrictEqual(output.length, 51);
+ deepStrictEqual(output[0], 1);
+ const { value } = parse.result();
+ deepStrictEqual(value.ParseError, undefined);
+});
+
+// --- scanner trim: an in-progress element must NOT be trimmed away. When the
+// buffer ends mid-element across a chunk boundary, trimFrom must be elementStart
+// (not scanPos), so the partial element is preserved for the next chunk. ---
+test(`${variant}: jsonParseStream preserves an in-progress element across a chunk boundary`, async (_t) => {
+ const parse = jsonParseStream();
+ const streams = [createReadableStream(['[{"abc":', "123}]"]), parse];
+ const output = await streamToArray(pipejoin(streams));
+ deepStrictEqual(output, [{ abc: 123 }]);
+ const { value } = parse.result();
+ deepStrictEqual(value.ParseError, undefined);
+});
+
+// --- scanner trim: after a chunk ends exactly on a comma (no element in
+// progress, buffer fully consumed), the next chunk's leading whitespace must
+// still be skipped. If the trim incorrectly left elementStart pointing at 0,
+// the next element's raw text would absorb that leading whitespace and overflow
+// maxValueSize. Pins the `if (elementStart !== -1)` trim-reset guard. ---
+test(`${variant}: jsonParseStream keeps elementStart unset across a comma-aligned chunk boundary`, async (_t) => {
+ const streams = [
+ createReadableStream(["[1,", " 123]"]),
+ jsonParseStream({ maxValueSize: 4 }),
+ ];
+ const output = await streamToArray(pipejoin(streams));
+ deepStrictEqual(output, [1, 123]);
+});
+
+// --- flush: a lone closing bracket left in the buffer must NOT be emitted as an
+// element (kills `trimmed !== "]"` -> `!== ""`). Construct a stream where the
+// final buffer is exactly "]". ---
+test(`${variant}: jsonParseStream flush ignores a trailing lone closing bracket`, async (_t) => {
+ // "[1" is scanned (element 1 in progress -> emitted at flush); a separate
+ // trailing "]" chunk arrives but, with the array still "open" at depth 0 and
+ // element 1 already pending, exercises the flush `]` guard.
+ const parse = jsonParseStream();
+ const streams = [createReadableStream(["[", "1", "]"]), parse];
+ const output = await streamToArray(pipejoin(streams));
+ deepStrictEqual(output, [1]);
+ const { value } = parse.result();
+ deepStrictEqual(value.ParseError, undefined);
+});
From 5e7cd0b7fee2ac658dd3b51d31bacaf225ab0f4e Mon Sep 17 00:00:00 2001
From: will Farrell
Date: Sun, 31 May 2026 21:13:09 -0600
Subject: [PATCH 09/27] fix: pattern
Signed-off-by: will Farrell
---
packages/aws/s3.js | 30 +++++++++++++-----------------
1 file changed, 13 insertions(+), 17 deletions(-)
diff --git a/packages/aws/s3.js b/packages/aws/s3.js
index 4741250..58eaf79 100644
--- a/packages/aws/s3.js
+++ b/packages/aws/s3.js
@@ -25,27 +25,23 @@ export const awsS3GetObjectStream = async (options, streamOptions = {}) => {
throw new Error("S3.GetObject not found", { cause: params });
}
const stream = createReadableStream(Body, streamOptions);
- // Tie the SDK Body lifecycle to the returned wrapper: if the consumer
- // errors/aborts, tear down Body so the underlying HTTP connection is not
- // leaked.
+ // Tie the SDK Body (live socket-backed readable) lifecycle to the returned
+ // wrapper: if the consumer errors/aborts, tear down Body so the underlying
+ // HTTP connection is not leaked.
const teardownBody = () => {
- // Node Body is a Readable (destroy); web Body is a WHATWG ReadableStream
- // (cancel). Call whichever exists, ignoring teardown errors so releasing
- // the socket cannot re-throw on an already-failed Body.
+ // The node SDK Body is a Readable (destroy). The try/catch swallows teardown
+ // errors so releasing the socket cannot re-throw on an already-failed Body
+ // (and tolerates a Body that does not expose destroy()).
try {
- Body.destroy?.();
- } catch {}
- try {
- Body.cancel?.();
+ Body.destroy();
} catch {}
};
- // If the wrapper exposes an 'error' event (a node Readable), clean up on it.
- if (typeof stream?.on === "function") {
- stream.on("error", teardownBody);
- }
- // The web wrapper is a WHATWG ReadableStream with no 'error' event, so wire
- // teardown to the abort signal so socket teardown on consumer abort is
- // consistent across builds.
+ // Node build: createReadableStream returns a node Readable; clean up on its
+ // 'error' event (without an error argument, so releasing the socket does not
+ // re-emit an unhandled 'error' on the already-failed Body).
+ stream.on("error", teardownBody);
+ // Any build given an abort signal also wires teardown to the abort signal so
+ // socket teardown on consumer abort is consistent across builds.
const { signal } = streamOptions;
if (signal) {
if (signal.aborted) {
From 6b379055de2bc953e2128db17ebd548c6b2a045b Mon Sep 17 00:00:00 2001
From: will Farrell
Date: Sun, 31 May 2026 21:25:13 -0600
Subject: [PATCH 10/27] chore: clean up
Signed-off-by: will Farrell
---
package.json | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/package.json b/package.json
index b763415..19f4ab0 100644
--- a/package.json
+++ b/package.json
@@ -31,8 +31,8 @@
"test:sast:gitleaks:git": "gitleaks git . --redact --no-banner",
"test:sast:license": "license-check-and-add check -f .license.config.json",
"test:sast:lockfile": "lockfile-lint --path package-lock.json --type npm --allowed-hosts npm --validate-https",
- "test:sast:semgrep": "semgrep scan --config auto",
- "test:sast:trivy": "trivy fs --scanners vuln,license --include-dev-deps --ignored-licenses 0BSD,Apache-2.0,BSD-1-Clause,BSD-2-Clause,BSD-3-Clause,CC0-1.0,CC-BY-4.0,ISC,MIT,MPL-2.0,BlueOak-1.0.0,Python-2.0,LGPL-3.0-or-later --exit-code 1 --skip-files '**/bun.lock' --disable-telemetry .",
+ "test:sast:semgrep": "semgrep scan --config auto --error",
+ "test:sast:trivy": "trivy fs --scanners vuln,license --include-dev-deps --ignored-licenses 0BSD,Apache-2.0,BSD-1-Clause,BSD-2-Clause,BSD-3-Clause,CC0-1.0,CC-BY-4.0,ISC,MIT,MPL-2.0,BlueOak-1.0.0,Unlicense,Python-2.0,LGPL-3.0-or-later --exit-code 1 --skip-files '**/bun.lock' --disable-telemetry .",
"test:sast:trufflehog": "trufflehog filesystem --only-verified --log-level=-1 ./",
"test:sast:zizmor": "zizmor .github/workflows/",
"test:types": "tstyche",
From 4e6d110e6efed0677f64150a3f208e450c431b84 Mon Sep 17 00:00:00 2001
From: will Farrell
Date: Mon, 1 Jun 2026 05:32:58 -0600
Subject: [PATCH 11/27] ci: project name
Signed-off-by: will Farrell
---
websites/datastream.js.org/package.json | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/websites/datastream.js.org/package.json b/websites/datastream.js.org/package.json
index cc03387..b522c84 100644
--- a/websites/datastream.js.org/package.json
+++ b/websites/datastream.js.org/package.json
@@ -4,6 +4,10 @@
"private": true,
"version": "0.5.0",
"type": "module",
+ "engines": {
+ "node": ">=24"
+ },
+ "engineStrict": true,
"scripts": {
"start": "vite dev",
"preview": "vite preview",
@@ -14,7 +18,7 @@
"build:styles:extract": "ds extract --input-dir ./.svelte-kit --theme ./src/styles/theme.css --output-dir src/styles/",
"build:styles:optimize": "ds optimize-styles ./.svelte-kit",
"release:login": "wrangler login --browser false",
- "release:domain": "curl https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/pages/projects/datastream/domains -H 'Content-Type: application/json' -H 'Authorization: Bearer ${API_KEY_W_PAGES_EDIT}' -d '{\"name\": \"datastream.js.org\"}'",
+ "release:domain": "curl https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/pages/projects/datastreamjs/domains -H 'Content-Type: application/json' -H 'Authorization: Bearer ${API_KEY_W_PAGES_EDIT}' -d '{\"name\": \"datastream.js.org\"}'",
"release:deploy": "wrangler pages deploy"
},
"dependencies": {
@@ -40,10 +44,5 @@
"vite-plugin-sitemap": "^0.8.0",
"vite-plugin-sri": "^0.0.2",
"wrangler": "^4.0.0"
- },
- "overrides": {
- "@sveltejs/kit": {
- "cookie": "0.7.2"
- }
}
}
From 39aa1d87f65d926db702b47f01c5df3d3c4d1575 Mon Sep 17 00:00:00 2001
From: will Farrell
Date: Thu, 11 Jun 2026 21:03:17 -0600
Subject: [PATCH 12/27] chore: dep update
Signed-off-by: will Farrell
---
.github/workflows/ossf-scorecard.yml | 2 +-
.github/workflows/test-dast.yml | 2 +-
.github/workflows/test-dco.yml | 2 +-
.github/workflows/test-lint.yml | 2 +-
.github/workflows/test-mutation.yml | 4 +-
.github/workflows/test-perf.yml | 2 +-
.github/workflows/test-sast.yml | 20 +-
.github/workflows/test-types.yml | 2 +-
.github/workflows/test-unit.yml | 2 +-
.../workflows/website-cloudflare-pages.yml | 2 +-
.gitignore | 6 +
README.md | 2 +
biome.json | 2 +-
package-lock.json | 3684 ++++++++++++++---
package.json | 2 +-
packages/aws/package.json | 4 +-
packages/base64/package.json | 4 +-
packages/charset/package.json | 4 +-
packages/compress/package.json | 4 +-
packages/core/package.json | 4 +-
packages/csv/package.json | 4 +-
packages/digest/package.json | 4 +-
packages/encrypt/index.node.js | 2 +-
packages/encrypt/index.web.js | 2 +-
packages/encrypt/package.json | 2 +-
packages/fetch/package.json | 4 +-
packages/file/package.json | 4 +-
packages/indexeddb/package.json | 4 +-
packages/ipfs/package.json | 4 +-
packages/json/package.json | 4 +-
packages/object/package.json | 4 +-
packages/string/package.json | 4 +-
packages/validate/package.json | 4 +-
.../src/components/docs/AsideNav.svelte | 5 +
.../datastream.js.org/src/routes/+page.svelte | 20 +
35 files changed, 3269 insertions(+), 558 deletions(-)
diff --git a/.github/workflows/ossf-scorecard.yml b/.github/workflows/ossf-scorecard.yml
index 6fda20b..2c78601 100644
--- a/.github/workflows/ossf-scorecard.yml
+++ b/.github/workflows/ossf-scorecard.yml
@@ -34,7 +34,7 @@ jobs:
steps:
- name: Harden runner
- uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1
+ uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit
disable-telemetry: true
diff --git a/.github/workflows/test-dast.yml b/.github/workflows/test-dast.yml
index afd79d8..83e0ee9 100644
--- a/.github/workflows/test-dast.yml
+++ b/.github/workflows/test-dast.yml
@@ -21,7 +21,7 @@ jobs:
steps:
- name: Harden runner
- uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1
+ uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit
disable-telemetry: true
diff --git a/.github/workflows/test-dco.yml b/.github/workflows/test-dco.yml
index a48471b..2bd395d 100644
--- a/.github/workflows/test-dco.yml
+++ b/.github/workflows/test-dco.yml
@@ -17,7 +17,7 @@ jobs:
timeout-minutes: 10
steps:
- name: Harden runner
- uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1
+ uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit
disable-telemetry: true
diff --git a/.github/workflows/test-lint.yml b/.github/workflows/test-lint.yml
index d4d3eef..9a99215 100644
--- a/.github/workflows/test-lint.yml
+++ b/.github/workflows/test-lint.yml
@@ -21,7 +21,7 @@ jobs:
steps:
- name: Harden runner
- uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1
+ uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit
disable-telemetry: true
diff --git a/.github/workflows/test-mutation.yml b/.github/workflows/test-mutation.yml
index 208e3aa..8820f2b 100644
--- a/.github/workflows/test-mutation.yml
+++ b/.github/workflows/test-mutation.yml
@@ -22,7 +22,7 @@ jobs:
packages: ${{ steps.list.outputs.packages }}
steps:
- name: Harden runner
- uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1
+ uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit
disable-telemetry: true
@@ -47,7 +47,7 @@ jobs:
steps:
- name: Harden runner
- uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1
+ uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit
disable-telemetry: true
diff --git a/.github/workflows/test-perf.yml b/.github/workflows/test-perf.yml
index 89d5459..8ba2ab9 100644
--- a/.github/workflows/test-perf.yml
+++ b/.github/workflows/test-perf.yml
@@ -21,7 +21,7 @@ jobs:
steps:
- name: Harden runner
- uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1
+ uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit
disable-telemetry: true
diff --git a/.github/workflows/test-sast.yml b/.github/workflows/test-sast.yml
index 9ccfb0d..142b61b 100644
--- a/.github/workflows/test-sast.yml
+++ b/.github/workflows/test-sast.yml
@@ -25,7 +25,7 @@ jobs:
if: (github.actor != 'dependabot[bot]')
steps:
- name: Harden runner
- uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1
+ uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit
disable-telemetry: true
@@ -53,7 +53,7 @@ jobs:
if: (github.actor != 'dependabot[bot]')
steps:
- name: Harden runner
- uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1
+ uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit
disable-telemetry: true
@@ -102,7 +102,7 @@ jobs:
if: (github.actor != 'dependabot[bot]')
steps:
- name: Harden runner
- uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1
+ uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit
disable-telemetry: true
@@ -131,7 +131,7 @@ jobs:
steps:
- name: Harden runner
- uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1
+ uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit
disable-telemetry: true
@@ -169,7 +169,7 @@ jobs:
steps:
- name: Harden runner
- uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1
+ uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit
disable-telemetry: true
@@ -200,7 +200,7 @@ jobs:
container:
# https://hub.docker.com/r/semgrep/semgrep/tags
- image: semgrep/semgrep:1.111.0 # v1.111.0
+ image: semgrep/semgrep@sha256:3e6e5065d9e68abffddffdb536a8db2d79a8fa92dc424daa48d3a4b7d9bc65d0 # v1.111.0
if: (github.actor != 'dependabot[bot]')
steps:
@@ -219,7 +219,7 @@ jobs:
timeout-minutes: 10
steps:
- name: Harden runner
- uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1
+ uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit
disable-telemetry: true
@@ -241,7 +241,7 @@ jobs:
security-events: write
steps:
- name: Harden runner
- uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1
+ uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit
disable-telemetry: true
@@ -260,7 +260,7 @@ jobs:
if: (github.actor != 'dependabot[bot]')
steps:
- name: Harden runner
- uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1
+ uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit
disable-telemetry: true
@@ -282,7 +282,7 @@ jobs:
if: (github.actor != 'dependabot[bot]')
steps:
- name: Harden runner
- uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1
+ uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit
disable-telemetry: true
diff --git a/.github/workflows/test-types.yml b/.github/workflows/test-types.yml
index 4e772a9..af6527c 100644
--- a/.github/workflows/test-types.yml
+++ b/.github/workflows/test-types.yml
@@ -21,7 +21,7 @@ jobs:
steps:
- name: Harden runner
- uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1
+ uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit
disable-telemetry: true
diff --git a/.github/workflows/test-unit.yml b/.github/workflows/test-unit.yml
index 7448113..03619ab 100644
--- a/.github/workflows/test-unit.yml
+++ b/.github/workflows/test-unit.yml
@@ -21,7 +21,7 @@ jobs:
steps:
- name: Harden runner
- uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1
+ uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit
disable-telemetry: true
diff --git a/.github/workflows/website-cloudflare-pages.yml b/.github/workflows/website-cloudflare-pages.yml
index a4cb7c6..bd27563 100644
--- a/.github/workflows/website-cloudflare-pages.yml
+++ b/.github/workflows/website-cloudflare-pages.yml
@@ -25,7 +25,7 @@ jobs:
steps:
- name: Harden runner
- uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1
+ uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit
disable-telemetry: true
diff --git a/.gitignore b/.gitignore
index 45fbb2c..8127047 100644
--- a/.gitignore
+++ b/.gitignore
@@ -116,5 +116,11 @@ dist
*.iml
.nova
+# Agents
+## /graphify hook install
+.husky/post-checkout
+.husky/post-commit
+graphify-out
+
# OS
.DS_Store
diff --git a/README.md b/README.md
index bf4669f..5ed6cf5 100644
--- a/README.md
+++ b/README.md
@@ -138,6 +138,7 @@
- arrowToArrayStream [Transform]
- arrowToObjectStream [Transform]
- [`@datastream/duckdb`](packages/duckdb)
+ - duckdbConnect (connection helper)
- duckdbAppenderStream [Writable]
- duckdbArrowInsertStream [Writable]
- [`@datastream/indexeddb`](packages/indexeddb)
@@ -157,6 +158,7 @@
- glueFrameStream [Transform]
- glueUnframeStream [Transform]
- [`@datastream/kafka`](packages/kafka)
+ - kafkaConnect (producer/consumer connection helper)
- kafkaConsumeStream [Readable]
- kafkaProduceStream [Writable]
- [`@datastream/aws/msk-iam`](packages/aws)
diff --git a/biome.json b/biome.json
index 433cc64..641ffc3 100644
--- a/biome.json
+++ b/biome.json
@@ -1,5 +1,5 @@
{
- "$schema": "https://biomejs.dev/schemas/2.4.15/schema.json",
+ "$schema": "https://biomejs.dev/schemas/2.4.16/schema.json",
"vcs": {
"enabled": true,
"clientKind": "git",
diff --git a/package-lock.json b/package-lock.json
index 215a890..0fefb3e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -42,6 +42,8 @@
},
"node_modules/@apidevtools/json-schema-ref-parser": {
"version": "15.3.5",
+ "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-15.3.5.tgz",
+ "integrity": "sha512-orNOYXw3hYXxxisXMldjzjBzqqTLBPbwOtHg7ovBPvfBHDue1qM9YJENZ3W2BQuS+7z4ThogMbEzEsov57Itkg==",
"license": "MIT",
"dependencies": {
"js-yaml": "^4.1.1"
@@ -55,6 +57,8 @@
},
"node_modules/@aws-crypto/crc32": {
"version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-5.2.0.tgz",
+ "integrity": "sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -68,6 +72,8 @@
},
"node_modules/@aws-crypto/crc32c": {
"version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@aws-crypto/crc32c/-/crc32c-5.2.0.tgz",
+ "integrity": "sha512-+iWb8qaHLYKrNvGRbiYRHSdKRWhto5XlZUEBwDjYNf+ly5SVYG6zEoYIdxvf5R3zyeP16w4PLBn3rH1xc74Rag==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -78,6 +84,8 @@
},
"node_modules/@aws-crypto/sha1-browser": {
"version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@aws-crypto/sha1-browser/-/sha1-browser-5.2.0.tgz",
+ "integrity": "sha512-OH6lveCFfcDjX4dbAvCFSYUjJZjDr/3XJ3xHtjn3Oj5b9RjojQo8npoLeA/bNwkOkrSQ0wgrHzXk4tDRxGKJeg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -91,6 +99,8 @@
},
"node_modules/@aws-crypto/sha256-browser": {
"version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz",
+ "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -105,6 +115,8 @@
},
"node_modules/@aws-crypto/sha256-js": {
"version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz",
+ "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -118,6 +130,8 @@
},
"node_modules/@aws-crypto/supports-web-crypto": {
"version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-5.2.0.tgz",
+ "integrity": "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -126,6 +140,8 @@
},
"node_modules/@aws-crypto/util": {
"version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz",
+ "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -135,18 +151,20 @@
}
},
"node_modules/@aws-sdk/client-cloudwatch-logs": {
- "version": "3.1052.0",
+ "version": "3.1057.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudwatch-logs/-/client-cloudwatch-logs-3.1057.0.tgz",
+ "integrity": "sha512-VzrpX93RMMGE8mG9EKm/TX9aZQsQvg0bYz276UOUuxAZlMBrYxKhiMyRDIHtFSUFI5SKaBWE3nY5xoI3SK74LQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.974.13",
- "@aws-sdk/credential-provider-node": "^3.972.44",
+ "@aws-sdk/core": "^3.974.15",
+ "@aws-sdk/credential-provider-node": "^3.972.47",
"@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.3",
- "@smithy/fetch-http-handler": "^5.4.3",
- "@smithy/node-http-handler": "^4.7.3",
+ "@smithy/core": "^3.24.5",
+ "@smithy/fetch-http-handler": "^5.4.5",
+ "@smithy/node-http-handler": "^4.7.5",
"@smithy/types": "^4.14.2",
"tslib": "^2.6.2"
},
@@ -155,18 +173,20 @@
}
},
"node_modules/@aws-sdk/client-cognito-identity": {
- "version": "3.1052.0",
+ "version": "3.1057.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.1057.0.tgz",
+ "integrity": "sha512-5MliYkp2u0+2arTp5fZIaxl+xmm90LEKv/VeSxhfNQW4t0fvWJrNO429/jchWQenNoDRrOGE59VfbuZUfwFujg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.974.13",
- "@aws-sdk/credential-provider-node": "^3.972.44",
+ "@aws-sdk/core": "^3.974.15",
+ "@aws-sdk/credential-provider-node": "^3.972.47",
"@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.3",
- "@smithy/fetch-http-handler": "^5.4.3",
- "@smithy/node-http-handler": "^4.7.3",
+ "@smithy/core": "^3.24.5",
+ "@smithy/fetch-http-handler": "^5.4.5",
+ "@smithy/node-http-handler": "^4.7.5",
"@smithy/types": "^4.14.2",
"tslib": "^2.6.2"
},
@@ -175,20 +195,22 @@
}
},
"node_modules/@aws-sdk/client-dynamodb": {
- "version": "3.1052.0",
+ "version": "3.1057.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-dynamodb/-/client-dynamodb-3.1057.0.tgz",
+ "integrity": "sha512-S0feh4mSWsqxQ8SGWIqAX5CQ9w+wBFxpNx4QVNy4rfQVMY6PvPuWT6kolfIHqMoIvuVGd9zD71BvzCK3CHip8Q==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.974.13",
- "@aws-sdk/credential-provider-node": "^3.972.44",
- "@aws-sdk/dynamodb-codec": "^3.973.13",
- "@aws-sdk/middleware-endpoint-discovery": "^3.972.14",
+ "@aws-sdk/core": "^3.974.15",
+ "@aws-sdk/credential-provider-node": "^3.972.47",
+ "@aws-sdk/dynamodb-codec": "^3.973.15",
+ "@aws-sdk/middleware-endpoint-discovery": "^3.972.15",
"@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.3",
- "@smithy/fetch-http-handler": "^5.4.3",
- "@smithy/node-http-handler": "^4.7.3",
+ "@smithy/core": "^3.24.5",
+ "@smithy/fetch-http-handler": "^5.4.5",
+ "@smithy/node-http-handler": "^4.7.5",
"@smithy/types": "^4.14.2",
"tslib": "^2.6.2"
},
@@ -197,18 +219,20 @@
}
},
"node_modules/@aws-sdk/client-dynamodb-streams": {
- "version": "3.1052.0",
+ "version": "3.1057.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-dynamodb-streams/-/client-dynamodb-streams-3.1057.0.tgz",
+ "integrity": "sha512-oVvf641Vo3mQBnytnOIGgleE+bSmTiqXmH1pCRBH10NBqSpSw6ll3KL6tgC0DErKt37aDGD7P0qC/FS8Cdjq9Q==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.974.13",
- "@aws-sdk/credential-provider-node": "^3.972.44",
+ "@aws-sdk/core": "^3.974.15",
+ "@aws-sdk/credential-provider-node": "^3.972.47",
"@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.3",
- "@smithy/fetch-http-handler": "^5.4.3",
- "@smithy/node-http-handler": "^4.7.3",
+ "@smithy/core": "^3.24.5",
+ "@smithy/fetch-http-handler": "^5.4.5",
+ "@smithy/node-http-handler": "^4.7.5",
"@smithy/types": "^4.14.2",
"tslib": "^2.6.2"
},
@@ -217,18 +241,20 @@
}
},
"node_modules/@aws-sdk/client-glue": {
- "version": "3.1052.0",
+ "version": "3.1057.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-glue/-/client-glue-3.1057.0.tgz",
+ "integrity": "sha512-pnsMbbnxR8wWr1qcyqkUUQVmHz5pmzW1cn9O/ANIhQ2rjyhF1/Wpgwvyv69ots1mbeOzGgsjfVvebpxisx01FQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.974.13",
- "@aws-sdk/credential-provider-node": "^3.972.44",
+ "@aws-sdk/core": "^3.974.15",
+ "@aws-sdk/credential-provider-node": "^3.972.47",
"@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.3",
- "@smithy/fetch-http-handler": "^5.4.3",
- "@smithy/node-http-handler": "^4.7.3",
+ "@smithy/core": "^3.24.5",
+ "@smithy/fetch-http-handler": "^5.4.5",
+ "@smithy/node-http-handler": "^4.7.5",
"@smithy/types": "^4.14.2",
"tslib": "^2.6.2"
},
@@ -237,18 +263,20 @@
}
},
"node_modules/@aws-sdk/client-kinesis": {
- "version": "3.1052.0",
+ "version": "3.1057.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-kinesis/-/client-kinesis-3.1057.0.tgz",
+ "integrity": "sha512-f1uYr9W5C+44UCT5r8Ca++Gn+NS4AQ/KPtjOsowQw8VQ/i2ZbOzU3cJB1RY0g2L1FpvQtM5bjGyrlOULzWKIWw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.974.13",
- "@aws-sdk/credential-provider-node": "^3.972.44",
+ "@aws-sdk/core": "^3.974.15",
+ "@aws-sdk/credential-provider-node": "^3.972.47",
"@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.3",
- "@smithy/fetch-http-handler": "^5.4.3",
- "@smithy/node-http-handler": "^4.7.3",
+ "@smithy/core": "^3.24.5",
+ "@smithy/fetch-http-handler": "^5.4.5",
+ "@smithy/node-http-handler": "^4.7.5",
"@smithy/types": "^4.14.2",
"tslib": "^2.6.2"
},
@@ -257,18 +285,20 @@
}
},
"node_modules/@aws-sdk/client-lambda": {
- "version": "3.1052.0",
+ "version": "3.1057.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-lambda/-/client-lambda-3.1057.0.tgz",
+ "integrity": "sha512-JoaE3QNvPqOSHJtcAFfza7BRoGUNerIKlSVhsKCBsa1i54Vto1YWUS7itkUELK2rpvS8kNZMPliPxDdi/oV5dw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.974.13",
- "@aws-sdk/credential-provider-node": "^3.972.44",
+ "@aws-sdk/core": "^3.974.15",
+ "@aws-sdk/credential-provider-node": "^3.972.47",
"@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.3",
- "@smithy/fetch-http-handler": "^5.4.3",
- "@smithy/node-http-handler": "^4.7.3",
+ "@smithy/core": "^3.24.5",
+ "@smithy/fetch-http-handler": "^5.4.5",
+ "@smithy/node-http-handler": "^4.7.5",
"@smithy/types": "^4.14.2",
"tslib": "^2.6.2"
},
@@ -277,26 +307,28 @@
}
},
"node_modules/@aws-sdk/client-s3": {
- "version": "3.1052.0",
+ "version": "3.1057.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.1057.0.tgz",
+ "integrity": "sha512-4MV5+ph7WSLEqStKYdWf2EIHIvLpPzV8xN98jWSVJfUpp5j7T8dyN3AROPPsKWvCme8hbx1ybCjtK76ALCZUYg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/sha1-browser": "5.2.0",
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.974.13",
- "@aws-sdk/credential-provider-node": "^3.972.44",
- "@aws-sdk/middleware-bucket-endpoint": "^3.972.15",
- "@aws-sdk/middleware-expect-continue": "^3.972.13",
- "@aws-sdk/middleware-flexible-checksums": "^3.974.21",
+ "@aws-sdk/core": "^3.974.15",
+ "@aws-sdk/credential-provider-node": "^3.972.47",
+ "@aws-sdk/middleware-bucket-endpoint": "^3.972.17",
+ "@aws-sdk/middleware-expect-continue": "^3.972.14",
+ "@aws-sdk/middleware-flexible-checksums": "^3.974.23",
"@aws-sdk/middleware-location-constraint": "^3.972.11",
- "@aws-sdk/middleware-sdk-s3": "^3.972.42",
+ "@aws-sdk/middleware-sdk-s3": "^3.972.44",
"@aws-sdk/middleware-ssec": "^3.972.11",
- "@aws-sdk/signature-v4-multi-region": "^3.996.28",
+ "@aws-sdk/signature-v4-multi-region": "^3.996.30",
"@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.3",
- "@smithy/fetch-http-handler": "^5.4.3",
- "@smithy/node-http-handler": "^4.7.3",
+ "@smithy/core": "^3.24.5",
+ "@smithy/fetch-http-handler": "^5.4.5",
+ "@smithy/node-http-handler": "^4.7.5",
"@smithy/types": "^4.14.2",
"tslib": "^2.6.2"
},
@@ -305,18 +337,20 @@
}
},
"node_modules/@aws-sdk/client-sns": {
- "version": "3.1052.0",
+ "version": "3.1057.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-sns/-/client-sns-3.1057.0.tgz",
+ "integrity": "sha512-zvHIX5pVCZPAehUbiaQURkJxZW1fUiCAdqhZVhKxzWlEGchiJqTjdNi9DG4wZdmKir+303fsq/HQaNB49vtavQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.974.13",
- "@aws-sdk/credential-provider-node": "^3.972.44",
+ "@aws-sdk/core": "^3.974.15",
+ "@aws-sdk/credential-provider-node": "^3.972.47",
"@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.3",
- "@smithy/fetch-http-handler": "^5.4.3",
- "@smithy/node-http-handler": "^4.7.3",
+ "@smithy/core": "^3.24.5",
+ "@smithy/fetch-http-handler": "^5.4.5",
+ "@smithy/node-http-handler": "^4.7.5",
"@smithy/types": "^4.14.2",
"tslib": "^2.6.2"
},
@@ -325,19 +359,21 @@
}
},
"node_modules/@aws-sdk/client-sqs": {
- "version": "3.1052.0",
+ "version": "3.1057.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-sqs/-/client-sqs-3.1057.0.tgz",
+ "integrity": "sha512-Qaxt1azI1PwClNkQzt/7N10rTdvC8oBleBxZ3yZWswXgMD/EcZ5sMim925uD75YXgzLwLnxKzF7c4mUxNuCqqw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.974.13",
- "@aws-sdk/credential-provider-node": "^3.972.44",
- "@aws-sdk/middleware-sdk-sqs": "^3.972.25",
+ "@aws-sdk/core": "^3.974.15",
+ "@aws-sdk/credential-provider-node": "^3.972.47",
+ "@aws-sdk/middleware-sdk-sqs": "^3.972.26",
"@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.3",
- "@smithy/fetch-http-handler": "^5.4.3",
- "@smithy/node-http-handler": "^4.7.3",
+ "@smithy/core": "^3.24.5",
+ "@smithy/fetch-http-handler": "^5.4.5",
+ "@smithy/node-http-handler": "^4.7.5",
"@smithy/types": "^4.14.2",
"tslib": "^2.6.2"
},
@@ -346,19 +382,21 @@
}
},
"node_modules/@aws-sdk/client-sts": {
- "version": "3.1052.0",
+ "version": "3.1057.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.1057.0.tgz",
+ "integrity": "sha512-67Qi3j1Np/y8QAiTQn3SlYIDg6j3gUbwbjYqPzL0S0pDTYoNtnHjABrvarg21txotlQn9ZkbgBawEL3+f3A/Qg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.974.13",
- "@aws-sdk/credential-provider-node": "^3.972.44",
- "@aws-sdk/signature-v4-multi-region": "^3.996.28",
+ "@aws-sdk/core": "^3.974.15",
+ "@aws-sdk/credential-provider-node": "^3.972.47",
+ "@aws-sdk/signature-v4-multi-region": "^3.996.30",
"@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.3",
- "@smithy/fetch-http-handler": "^5.4.3",
- "@smithy/node-http-handler": "^4.7.3",
+ "@smithy/core": "^3.24.5",
+ "@smithy/fetch-http-handler": "^5.4.5",
+ "@smithy/node-http-handler": "^4.7.5",
"@smithy/types": "^4.14.2",
"tslib": "^2.6.2"
},
@@ -367,15 +405,17 @@
}
},
"node_modules/@aws-sdk/core": {
- "version": "3.974.13",
+ "version": "3.974.15",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.974.15.tgz",
+ "integrity": "sha512-UpA0rTGW/tHGITcCqHisbuuEPraYg9GG+mWmXjY5+RxZBMLGe6aL9oe0ix50LztwAcPIkGZLH0yWdMIkCM10hw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-sdk/types": "^3.973.9",
- "@aws-sdk/xml-builder": "^3.972.25",
+ "@aws-sdk/xml-builder": "^3.972.26",
"@aws/lambda-invoke-store": "^0.2.2",
- "@smithy/core": "^3.24.3",
- "@smithy/signature-v4": "^5.4.2",
+ "@smithy/core": "^3.24.5",
+ "@smithy/signature-v4": "^5.4.5",
"@smithy/types": "^4.14.2",
"bowser": "^2.11.0",
"tslib": "^2.6.2"
@@ -386,6 +426,8 @@
},
"node_modules/@aws-sdk/crc64-nvme": {
"version": "3.972.9",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/crc64-nvme/-/crc64-nvme-3.972.9.tgz",
+ "integrity": "sha512-P+QGozmXn2mZZI7sDgk+aUm+RTI61MPSFB+Ir2vjEjEbEsE4e7hYtzrDvAUxZy9ko81h53e11+F/GYlvwDkaOQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -397,13 +439,15 @@
}
},
"node_modules/@aws-sdk/credential-provider-cognito-identity": {
- "version": "3.972.36",
+ "version": "3.972.38",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.972.38.tgz",
+ "integrity": "sha512-OHkK6xOx/IHkSbQdDWxnVCLU+j28EFl8wyWgBILQDFAPY8n240C/O4gjmFx+zFU12lL8njgJQ5GWAIWq88CnSQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/nested-clients": "^3.997.11",
+ "@aws-sdk/nested-clients": "^3.997.13",
"@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.3",
+ "@smithy/core": "^3.24.5",
"@smithy/types": "^4.14.2",
"tslib": "^2.6.2"
},
@@ -412,13 +456,15 @@
}
},
"node_modules/@aws-sdk/credential-provider-env": {
- "version": "3.972.39",
+ "version": "3.972.41",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.41.tgz",
+ "integrity": "sha512-n1EbJ98yvPWWdHZZv8bRBMqqDQJrtgtxyJ4xLy2Uqrh25BCOZQ7nnS1CsFXvuH8r0b0KVHDZEGEH5FxmEMP8jg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.974.13",
+ "@aws-sdk/core": "^3.974.15",
"@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.3",
+ "@smithy/core": "^3.24.5",
"@smithy/types": "^4.14.2",
"tslib": "^2.6.2"
},
@@ -427,15 +473,17 @@
}
},
"node_modules/@aws-sdk/credential-provider-http": {
- "version": "3.972.41",
+ "version": "3.972.43",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.43.tgz",
+ "integrity": "sha512-TT76RN1NkI9WoyZqCNxOw6/WBMF7pYOTJcXbMokNFU+euSG40Kaf/t/FhDACVZWP+43wEM6ZynIPIkzS1wR1iA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.974.13",
+ "@aws-sdk/core": "^3.974.15",
"@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.3",
- "@smithy/fetch-http-handler": "^5.4.3",
- "@smithy/node-http-handler": "^4.7.3",
+ "@smithy/core": "^3.24.5",
+ "@smithy/fetch-http-handler": "^5.4.5",
+ "@smithy/node-http-handler": "^4.7.5",
"@smithy/types": "^4.14.2",
"tslib": "^2.6.2"
},
@@ -444,21 +492,23 @@
}
},
"node_modules/@aws-sdk/credential-provider-ini": {
- "version": "3.972.43",
+ "version": "3.972.46",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.972.46.tgz",
+ "integrity": "sha512-hvcgcwOiS0nb2XFb5Op1Pz/vYaWz5K8kKullziGpdNRuG0NwzRXseuPt2CoBqknHGaSPVesu1aOn2OcctEYdCA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.974.13",
- "@aws-sdk/credential-provider-env": "^3.972.39",
- "@aws-sdk/credential-provider-http": "^3.972.41",
- "@aws-sdk/credential-provider-login": "^3.972.43",
- "@aws-sdk/credential-provider-process": "^3.972.39",
- "@aws-sdk/credential-provider-sso": "^3.972.43",
- "@aws-sdk/credential-provider-web-identity": "^3.972.43",
- "@aws-sdk/nested-clients": "^3.997.11",
+ "@aws-sdk/core": "^3.974.15",
+ "@aws-sdk/credential-provider-env": "^3.972.41",
+ "@aws-sdk/credential-provider-http": "^3.972.43",
+ "@aws-sdk/credential-provider-login": "^3.972.45",
+ "@aws-sdk/credential-provider-process": "^3.972.41",
+ "@aws-sdk/credential-provider-sso": "^3.972.45",
+ "@aws-sdk/credential-provider-web-identity": "^3.972.45",
+ "@aws-sdk/nested-clients": "^3.997.13",
"@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.3",
- "@smithy/credential-provider-imds": "^4.3.2",
+ "@smithy/core": "^3.24.5",
+ "@smithy/credential-provider-imds": "^4.3.6",
"@smithy/types": "^4.14.2",
"tslib": "^2.6.2"
},
@@ -467,14 +517,16 @@
}
},
"node_modules/@aws-sdk/credential-provider-login": {
- "version": "3.972.43",
+ "version": "3.972.45",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.45.tgz",
+ "integrity": "sha512-MZQv4SNjByk1iOKmrqmzcUF/uCB05wjvEHyXKxmGQTUANTIVayX6HPUF0bzkWLvtnkH7sAn9kUCfkXbSpj9sDA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.974.13",
- "@aws-sdk/nested-clients": "^3.997.11",
+ "@aws-sdk/core": "^3.974.15",
+ "@aws-sdk/nested-clients": "^3.997.13",
"@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.3",
+ "@smithy/core": "^3.24.5",
"@smithy/types": "^4.14.2",
"tslib": "^2.6.2"
},
@@ -483,19 +535,21 @@
}
},
"node_modules/@aws-sdk/credential-provider-node": {
- "version": "3.972.44",
+ "version": "3.972.47",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.47.tgz",
+ "integrity": "sha512-HrId+C0DWA5qDIyLG64/kjUB2RNtPypxmABnIctK+TA1P1kHlOYoE/Wf5T5tKOMKgb08P7k/zNyhvfJ3lh5Oag==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/credential-provider-env": "^3.972.39",
- "@aws-sdk/credential-provider-http": "^3.972.41",
- "@aws-sdk/credential-provider-ini": "^3.972.43",
- "@aws-sdk/credential-provider-process": "^3.972.39",
- "@aws-sdk/credential-provider-sso": "^3.972.43",
- "@aws-sdk/credential-provider-web-identity": "^3.972.43",
+ "@aws-sdk/credential-provider-env": "^3.972.41",
+ "@aws-sdk/credential-provider-http": "^3.972.43",
+ "@aws-sdk/credential-provider-ini": "^3.972.46",
+ "@aws-sdk/credential-provider-process": "^3.972.41",
+ "@aws-sdk/credential-provider-sso": "^3.972.45",
+ "@aws-sdk/credential-provider-web-identity": "^3.972.45",
"@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.3",
- "@smithy/credential-provider-imds": "^4.3.2",
+ "@smithy/core": "^3.24.5",
+ "@smithy/credential-provider-imds": "^4.3.6",
"@smithy/types": "^4.14.2",
"tslib": "^2.6.2"
},
@@ -504,13 +558,15 @@
}
},
"node_modules/@aws-sdk/credential-provider-process": {
- "version": "3.972.39",
+ "version": "3.972.41",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.41.tgz",
+ "integrity": "sha512-7I/n1zkysouLOWvkEhjNEP4vMnD2v4kzzr3/3QBdrripEpn7ap1/I5DF3Hou1SUqkKWo1f3oPGMyFAA1FAMvsQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.974.13",
+ "@aws-sdk/core": "^3.974.15",
"@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.3",
+ "@smithy/core": "^3.24.5",
"@smithy/types": "^4.14.2",
"tslib": "^2.6.2"
},
@@ -519,15 +575,17 @@
}
},
"node_modules/@aws-sdk/credential-provider-sso": {
- "version": "3.972.43",
+ "version": "3.972.45",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.972.45.tgz",
+ "integrity": "sha512-oHgbz/eFD8IKiksqDsz9ZMU4A59BpQq4QwJedBnGD80ZqYcHPPHZBwjBnxLVkB7iRVVHWpDclR8yWdD2PkQIUA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.974.13",
- "@aws-sdk/nested-clients": "^3.997.11",
- "@aws-sdk/token-providers": "3.1052.0",
+ "@aws-sdk/core": "^3.974.15",
+ "@aws-sdk/nested-clients": "^3.997.13",
+ "@aws-sdk/token-providers": "3.1056.0",
"@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.3",
+ "@smithy/core": "^3.24.5",
"@smithy/types": "^4.14.2",
"tslib": "^2.6.2"
},
@@ -536,14 +594,16 @@
}
},
"node_modules/@aws-sdk/credential-provider-web-identity": {
- "version": "3.972.43",
+ "version": "3.972.45",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.45.tgz",
+ "integrity": "sha512-CDhzKdb2onv5bpnjn/acgdNmJOQthPDLsPizU7rZflsEcgMMp8Mlri+U5hdxf8ldvZJpvM3vLU6D56vfJm5AMQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.974.13",
- "@aws-sdk/nested-clients": "^3.997.11",
+ "@aws-sdk/core": "^3.974.15",
+ "@aws-sdk/nested-clients": "^3.997.13",
"@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.3",
+ "@smithy/core": "^3.24.5",
"@smithy/types": "^4.14.2",
"tslib": "^2.6.2"
},
@@ -552,25 +612,27 @@
}
},
"node_modules/@aws-sdk/credential-providers": {
- "version": "3.1052.0",
+ "version": "3.1057.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.1057.0.tgz",
+ "integrity": "sha512-rbrEHtz11g0kxsSkYr3fx2HABNNblp4AhB2MgPvJHgYOWfJ2eBviU7Mvoaef0PW8QH6lbZDfJcnM7eKvtvz3sw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/client-cognito-identity": "3.1052.0",
- "@aws-sdk/core": "^3.974.13",
- "@aws-sdk/credential-provider-cognito-identity": "^3.972.36",
- "@aws-sdk/credential-provider-env": "^3.972.39",
- "@aws-sdk/credential-provider-http": "^3.972.41",
- "@aws-sdk/credential-provider-ini": "^3.972.43",
- "@aws-sdk/credential-provider-login": "^3.972.43",
- "@aws-sdk/credential-provider-node": "^3.972.44",
- "@aws-sdk/credential-provider-process": "^3.972.39",
- "@aws-sdk/credential-provider-sso": "^3.972.43",
- "@aws-sdk/credential-provider-web-identity": "^3.972.43",
- "@aws-sdk/nested-clients": "^3.997.11",
+ "@aws-sdk/client-cognito-identity": "3.1057.0",
+ "@aws-sdk/core": "^3.974.15",
+ "@aws-sdk/credential-provider-cognito-identity": "^3.972.38",
+ "@aws-sdk/credential-provider-env": "^3.972.41",
+ "@aws-sdk/credential-provider-http": "^3.972.43",
+ "@aws-sdk/credential-provider-ini": "^3.972.46",
+ "@aws-sdk/credential-provider-login": "^3.972.45",
+ "@aws-sdk/credential-provider-node": "^3.972.47",
+ "@aws-sdk/credential-provider-process": "^3.972.41",
+ "@aws-sdk/credential-provider-sso": "^3.972.45",
+ "@aws-sdk/credential-provider-web-identity": "^3.972.45",
+ "@aws-sdk/nested-clients": "^3.997.13",
"@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.3",
- "@smithy/credential-provider-imds": "^4.3.2",
+ "@smithy/core": "^3.24.5",
+ "@smithy/credential-provider-imds": "^4.3.6",
"@smithy/types": "^4.14.2",
"tslib": "^2.6.2"
},
@@ -579,12 +641,14 @@
}
},
"node_modules/@aws-sdk/dynamodb-codec": {
- "version": "3.973.13",
+ "version": "3.973.15",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/dynamodb-codec/-/dynamodb-codec-3.973.15.tgz",
+ "integrity": "sha512-R09IUytTrUKwsIiMVSHPZJz0zO9EsXHg/JZ+3AwQ+eSahRnHuPuZANMfeTb/j2+AKkZ7DhW2FcT6XuHLwC0cZw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.974.13",
- "@smithy/core": "^3.24.3",
+ "@aws-sdk/core": "^3.974.15",
+ "@smithy/core": "^3.24.5",
"@smithy/types": "^4.14.2",
"tslib": "^2.6.2"
},
@@ -594,6 +658,8 @@
},
"node_modules/@aws-sdk/endpoint-cache": {
"version": "3.972.5",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/endpoint-cache/-/endpoint-cache-3.972.5.tgz",
+ "integrity": "sha512-itVdge0NozgtgmtbZ25FVwWU3vGlE7x7feE/aOEJNkQfEpbkrF8Rj1QmnK+2blFfYE1xWt/iU+6/jUp/pv1+MA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -605,11 +671,13 @@
}
},
"node_modules/@aws-sdk/lib-storage": {
- "version": "3.1052.0",
+ "version": "3.1057.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/lib-storage/-/lib-storage-3.1057.0.tgz",
+ "integrity": "sha512-0LlXWaklL2LGBSJ6w3YwsJaFCR9yu57648aEyyIRLM5NT+rQ3Xbx0/pCsuM4fD+QJZhASMMAALAl/pdiN5B+FQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@smithy/core": "^3.24.3",
+ "@smithy/core": "^3.24.5",
"@smithy/types": "^4.14.2",
"buffer": "5.6.0",
"events": "3.3.0",
@@ -620,17 +688,19 @@
"node": ">=20.0.0"
},
"peerDependencies": {
- "@aws-sdk/client-s3": "^3.1052.0"
+ "@aws-sdk/client-s3": "^3.1057.0"
}
},
"node_modules/@aws-sdk/middleware-bucket-endpoint": {
- "version": "3.972.15",
+ "version": "3.972.17",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.972.17.tgz",
+ "integrity": "sha512-lbDmWuHenc+kiwCNrxz4MyN6nkxCWyTXPIWuspJN0ibziu+8CXci7vI1bK9MAkwy8cwJOEXNu0gBM5S0uTGRIg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.974.13",
+ "@aws-sdk/core": "^3.974.15",
"@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.3",
+ "@smithy/core": "^3.24.5",
"@smithy/types": "^4.14.2",
"tslib": "^2.6.2"
},
@@ -639,13 +709,15 @@
}
},
"node_modules/@aws-sdk/middleware-endpoint-discovery": {
- "version": "3.972.14",
+ "version": "3.972.15",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-endpoint-discovery/-/middleware-endpoint-discovery-3.972.15.tgz",
+ "integrity": "sha512-L1wbvrAb0hv7Vx6eTEyqQwXaNETSj/L30BVCkSxD0k6Ve5cZUM0SLUvBn8aA/B4YtIpMzCbzNaVytZY7uOzJSw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-sdk/endpoint-cache": "^3.972.5",
"@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.3",
+ "@smithy/core": "^3.24.5",
"@smithy/types": "^4.14.2",
"tslib": "^2.6.2"
},
@@ -654,12 +726,14 @@
}
},
"node_modules/@aws-sdk/middleware-expect-continue": {
- "version": "3.972.13",
+ "version": "3.972.14",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.972.14.tgz",
+ "integrity": "sha512-3TNFEVGO4sWZj9TEXOCZLzGEctXHnaO4fk2EQ8KVaboTbwHmEPEQrm17Xb9koImUIXEw0sgi2xtHjg7LuTS3rA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.3",
+ "@smithy/core": "^3.24.5",
"@smithy/types": "^4.14.2",
"tslib": "^2.6.2"
},
@@ -668,17 +742,19 @@
}
},
"node_modules/@aws-sdk/middleware-flexible-checksums": {
- "version": "3.974.21",
+ "version": "3.974.23",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.974.23.tgz",
+ "integrity": "sha512-4nPKARo2lfKvQGUt2fPA5NlS/mEohckdxpuC9ecbjVfj7B7NFFYHeTg+Bf5BEQwdn3yRfUIzFiEkPp8Yuaw3wA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/crc32": "5.2.0",
"@aws-crypto/crc32c": "5.2.0",
"@aws-crypto/util": "5.2.0",
- "@aws-sdk/core": "^3.974.13",
+ "@aws-sdk/core": "^3.974.15",
"@aws-sdk/crc64-nvme": "^3.972.9",
"@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.3",
+ "@smithy/core": "^3.24.5",
"@smithy/types": "^4.14.2",
"tslib": "^2.6.2"
},
@@ -688,6 +764,8 @@
},
"node_modules/@aws-sdk/middleware-location-constraint": {
"version": "3.972.11",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.972.11.tgz",
+ "integrity": "sha512-hkfspNUP4criAH6ton6BGKgnm5dZx+7bUOy1YqlTfejDeUPAM23D81q/IX+hdlS3KUsfwGz5ADTqZWKBEUpf4A==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -700,15 +778,16 @@
}
},
"node_modules/@aws-sdk/middleware-sdk-s3": {
- "version": "3.972.42",
+ "version": "3.972.44",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.972.44.tgz",
+ "integrity": "sha512-8HQsRg1NpX8vR4vNl1E8pyLnqZroq9VSL2vZQVSgBqp6wv6365LzYD08/c9FFh/9FTg7YRc7aTtEmXF0ir/pqg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.974.13",
- "@aws-sdk/signature-v4-multi-region": "^3.996.28",
+ "@aws-sdk/core": "^3.974.15",
+ "@aws-sdk/signature-v4-multi-region": "^3.996.30",
"@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.3",
- "@smithy/signature-v4": "^5.4.2",
+ "@smithy/core": "^3.24.5",
"@smithy/types": "^4.14.2",
"tslib": "^2.6.2"
},
@@ -717,12 +796,14 @@
}
},
"node_modules/@aws-sdk/middleware-sdk-sqs": {
- "version": "3.972.25",
+ "version": "3.972.26",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sqs/-/middleware-sdk-sqs-3.972.26.tgz",
+ "integrity": "sha512-9VjCszKNDgEvHZBcryWpjGY4vwbTZU6hWARsxJZ+SZSglalP/6g8QTIKmKxSKlLle0BvrWhbZ5wlRhktTTkXEQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.3",
+ "@smithy/core": "^3.24.5",
"@smithy/types": "^4.14.2",
"tslib": "^2.6.2"
},
@@ -732,6 +813,8 @@
},
"node_modules/@aws-sdk/middleware-ssec": {
"version": "3.972.11",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.972.11.tgz",
+ "integrity": "sha512-7PQvGNhtveKlvVqNahqWx5yrwxP7ecwAoB1dYBf8eKwfo2tzzCbNnW+q2nO3N066ktQaB4iBQbDRWtizm+amoQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -744,18 +827,20 @@
}
},
"node_modules/@aws-sdk/nested-clients": {
- "version": "3.997.11",
+ "version": "3.997.13",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.997.13.tgz",
+ "integrity": "sha512-2pA6eyb5nSo/ZD2cayhOTEMoGQYgspq0RI05GDLkzQ3ajZ6isS6waV6E92Am/hz4LIlLUTrbwPLurJ/fuiHvkg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.974.13",
- "@aws-sdk/signature-v4-multi-region": "^3.996.28",
+ "@aws-sdk/core": "^3.974.15",
+ "@aws-sdk/signature-v4-multi-region": "^3.996.30",
"@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.3",
- "@smithy/fetch-http-handler": "^5.4.3",
- "@smithy/node-http-handler": "^4.7.3",
+ "@smithy/core": "^3.24.5",
+ "@smithy/fetch-http-handler": "^5.4.5",
+ "@smithy/node-http-handler": "^4.7.5",
"@smithy/types": "^4.14.2",
"tslib": "^2.6.2"
},
@@ -764,13 +849,14 @@
}
},
"node_modules/@aws-sdk/signature-v4-multi-region": {
- "version": "3.996.28",
+ "version": "3.996.30",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.996.30.tgz",
+ "integrity": "sha512-HULDLMVzkmTSEv6//7kx2kRevp/VYUpm8hJNNFbmhxDn0fUiGTxVcM9yg31TukvTq8nyOBDUN2gH0o5IRbKjdw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.3",
- "@smithy/signature-v4": "^5.4.2",
+ "@smithy/signature-v4": "^5.4.5",
"@smithy/types": "^4.14.2",
"tslib": "^2.6.2"
},
@@ -779,14 +865,16 @@
}
},
"node_modules/@aws-sdk/token-providers": {
- "version": "3.1052.0",
+ "version": "3.1056.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.1056.0.tgz",
+ "integrity": "sha512-81duvlltQlsfn5K+o8zILcystBRdbT1G2JJYVCML5NZHBz4CL/zf+sAemCtBh/uh6RQUMyInGeZLQ7/8igZhbA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.974.13",
- "@aws-sdk/nested-clients": "^3.997.11",
+ "@aws-sdk/core": "^3.974.15",
+ "@aws-sdk/nested-clients": "^3.997.13",
"@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.3",
+ "@smithy/core": "^3.24.5",
"@smithy/types": "^4.14.2",
"tslib": "^2.6.2"
},
@@ -796,6 +884,8 @@
},
"node_modules/@aws-sdk/types": {
"version": "3.973.9",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.973.9.tgz",
+ "integrity": "sha512-kuBfgQVdcz5Bmapc4A13YbpVw/pXkesfhetcFYwbntqas8sF41OHyd4o28+/TG2ZQdHBsv90Lsu5y6oitvYCdg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -807,11 +897,13 @@
}
},
"node_modules/@aws-sdk/util-format-url": {
- "version": "3.972.15",
+ "version": "3.972.17",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/util-format-url/-/util-format-url-3.972.17.tgz",
+ "integrity": "sha512-Y/VVghC8yAz9fe2f47tqVoKZDfE5fvmnuIimifrRK04oy8PLezI7bgTB+KjDZaV1dnAq076DKaaQPxFgx6YN7A==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.974.13",
+ "@aws-sdk/core": "^3.974.15",
"tslib": "^2.6.2"
},
"engines": {
@@ -820,6 +912,8 @@
},
"node_modules/@aws-sdk/util-locate-window": {
"version": "3.965.5",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.965.5.tgz",
+ "integrity": "sha512-WhlJNNINQB+9qtLtZJcpQdgZw3SCDCpXdUJP7cToGwHbCWCnRckGlc6Bx/OhWwIYFNAn+FIydY8SZ0QmVu3xTQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -831,6 +925,8 @@
},
"node_modules/@aws-sdk/util-utf8-browser": {
"version": "3.259.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.259.0.tgz",
+ "integrity": "sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -838,11 +934,12 @@
}
},
"node_modules/@aws-sdk/xml-builder": {
- "version": "3.972.25",
+ "version": "3.972.26",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.26.tgz",
+ "integrity": "sha512-cDbrqvDS73whl6YAPSPq0U6whzG6UWI9PuWh0wrUuGoZexhWEqhdunbukV7iBoaWnFV1AODutM5hOD6rtn439g==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@nodable/entities": "2.1.0",
"@smithy/types": "^4.14.2",
"fast-xml-parser": "5.7.3",
"tslib": "^2.6.2"
@@ -853,6 +950,8 @@
},
"node_modules/@aws/lambda-invoke-store": {
"version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/@aws/lambda-invoke-store/-/lambda-invoke-store-0.2.4.tgz",
+ "integrity": "sha512-iY8yvjE0y651BixKNPgmv1WrQc+GZ142sb0z4gYnChDDY2YqI4P/jsSopBWrKfAt7LOJAkOXt7rC/hms+WclQQ==",
"dev": true,
"license": "Apache-2.0",
"engines": {
@@ -861,6 +960,8 @@
},
"node_modules/@babel/code-frame": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz",
+ "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -874,6 +975,8 @@
},
"node_modules/@babel/compat-data": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz",
+ "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -882,6 +985,8 @@
},
"node_modules/@babel/core": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz",
+ "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -911,6 +1016,8 @@
},
"node_modules/@babel/core/node_modules/semver": {
"version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true,
"license": "ISC",
"bin": {
@@ -919,6 +1026,8 @@
},
"node_modules/@babel/generator": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.7.tgz",
+ "integrity": "sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -934,6 +1043,8 @@
},
"node_modules/@babel/helper-annotate-as-pure": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.29.7.tgz",
+ "integrity": "sha512-OoK6239jHPuSQOoS0kfTVKn0b/rVTk0seKq4Gd2UMLtmOVLjDC0ki3e+c90Trqv2gMfvJFqkiljrr568+qddiw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -945,6 +1056,8 @@
},
"node_modules/@babel/helper-compilation-targets": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz",
+ "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -958,16 +1071,10 @@
"node": ">=6.9.0"
}
},
- "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": {
- "version": "5.1.1",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "yallist": "^3.0.2"
- }
- },
"node_modules/@babel/helper-compilation-targets/node_modules/semver": {
"version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true,
"license": "ISC",
"bin": {
@@ -976,6 +1083,8 @@
},
"node_modules/@babel/helper-create-class-features-plugin": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.29.7.tgz",
+ "integrity": "sha512-IY3ZD9Tmooqr3TUhc3DUWxiuo8xx1DWLhd5M7hQ+ZWJamqM2BbalrBJb2MisSLoYorOj75U03qULCxQTY9r3hg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -996,6 +1105,8 @@
},
"node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": {
"version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true,
"license": "ISC",
"bin": {
@@ -1004,6 +1115,8 @@
},
"node_modules/@babel/helper-globals": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz",
+ "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -1012,6 +1125,8 @@
},
"node_modules/@babel/helper-member-expression-to-functions": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.29.7.tgz",
+ "integrity": "sha512-j+7JYmk1JYDtACIGj0QJqqWZjoUpMoEikQGADMaHgCMCSDqd2+P32rfcibUNrGOMWrlzK1WJBdxrB3JJQZwWtg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1024,6 +1139,8 @@
},
"node_modules/@babel/helper-module-imports": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz",
+ "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1036,6 +1153,8 @@
},
"node_modules/@babel/helper-module-transforms": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz",
+ "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1052,6 +1171,8 @@
},
"node_modules/@babel/helper-optimise-call-expression": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.29.7.tgz",
+ "integrity": "sha512-+kmGVjcT9RGYzoDwdwEqEvGgKe3BYq+O1iGzjFubaNgZHwYHP6lsF2Yghf4kEuv9BV7tYDZ913aBW9am6YKong==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1063,6 +1184,8 @@
},
"node_modules/@babel/helper-plugin-utils": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz",
+ "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -1071,6 +1194,8 @@
},
"node_modules/@babel/helper-replace-supers": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.29.7.tgz",
+ "integrity": "sha512-atfGXWSeCiF4DnKZIfmJfQRkSw9b9gNNXR1kqKjbhG4pGYCOnkp8OcTB8E3NXjBu8NpheSnOeNKz8KT7UNFTmQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1087,6 +1212,8 @@
},
"node_modules/@babel/helper-skip-transparent-expression-wrappers": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.29.7.tgz",
+ "integrity": "sha512-brcMGQaVzIeUb+6/bs1Av0f8YuNNjKY2JyvfRCsFuFsdKccEQ5Ges2y74D74NZ1Rz8lKJ9ksJkfqwQFJ/iNEyQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1099,6 +1226,8 @@
},
"node_modules/@babel/helper-string-parser": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz",
+ "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -1107,6 +1236,8 @@
},
"node_modules/@babel/helper-validator-identifier": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz",
+ "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -1115,6 +1246,8 @@
},
"node_modules/@babel/helper-validator-option": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz",
+ "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -1123,6 +1256,8 @@
},
"node_modules/@babel/helpers": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz",
+ "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1135,6 +1270,8 @@
},
"node_modules/@babel/parser": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz",
+ "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1149,6 +1286,8 @@
},
"node_modules/@babel/plugin-proposal-decorators": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.29.7.tgz",
+ "integrity": "sha512-EtU0Hi3GvrTqD56xKmZvV/uCXK2ZbwVNPNLAquVItcAZpUhkXwWlo3Fmj0c2LxgSf2I8IDULeAepwNP1OefLXg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1165,6 +1304,8 @@
},
"node_modules/@babel/plugin-syntax-decorators": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.29.7.tgz",
+ "integrity": "sha512-9MTTLbF39X6sqM92JPEsoI7++26hjZvzkxKZy64aMhWLH2mPkJ/Q3AV4QLmls3R14FpSpkOwQQfUh962JGQxxg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1179,6 +1320,8 @@
},
"node_modules/@babel/plugin-syntax-jsx": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.29.7.tgz",
+ "integrity": "sha512-TSu8+mHCoEaaCDEZ0I3+6mvTBYR4PCxQwf2z9/r5Tbztv6NaLR3B9thGTTxX2WGuGHJqRiAbKPeGTJ5XWXVg6A==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1193,6 +1336,8 @@
},
"node_modules/@babel/plugin-syntax-typescript": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.29.7.tgz",
+ "integrity": "sha512-ngr+82Sh0xMz25TPCZi+nC2iTzjfCdWS2ONXTp/PtSCHCgaCNBpdMqgvJ2ccdLlClVZ7sisIgB914j/JFe+RZA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1207,6 +1352,8 @@
},
"node_modules/@babel/plugin-transform-destructuring": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.29.7.tgz",
+ "integrity": "sha512-iPX8aD6H9zV5s7ZsqTdNocPN/MGQ5sSMnElKrktxjJRMnB2jN/1p2+R7GkfD6CAYoVFqy5A4XnSIUeGgJzIWpg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1222,6 +1369,8 @@
},
"node_modules/@babel/plugin-transform-explicit-resource-management": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-explicit-resource-management/-/plugin-transform-explicit-resource-management-7.29.7.tgz",
+ "integrity": "sha512-Rstj7coNz8sE+7Ju7ihpHLI564lsK5pUpNNlvptCIC/16E/S5hbl6n3kESPKdNRmqEWlpn5xpS5Q2dvXBsySLw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1237,6 +1386,8 @@
},
"node_modules/@babel/plugin-transform-modules-commonjs": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.29.7.tgz",
+ "integrity": "sha512-j0vCldybPC5b5dwCQOJ21uKtHzt7hxLygJTg9eF1ScfaikEDNfzn94XoW5Fi+seBR0nCyL23xaBFFkq7dTM8XQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1252,6 +1403,8 @@
},
"node_modules/@babel/plugin-transform-typescript": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.29.7.tgz",
+ "integrity": "sha512-jK52h8LaLc7JarhQV2ofeFMts4H7vnOXnqZNA6fYglBTZewRBE51KWt3BUltW1P+KoPsYkHoJeXePuz4zo2LMw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1270,6 +1423,8 @@
},
"node_modules/@babel/preset-typescript": {
"version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.28.5.tgz",
+ "integrity": "sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1287,7 +1442,9 @@
}
},
"node_modules/@babel/runtime": {
- "version": "7.29.2",
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz",
+ "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -1296,6 +1453,8 @@
},
"node_modules/@babel/template": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz",
+ "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1309,6 +1468,8 @@
},
"node_modules/@babel/traverse": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.7.tgz",
+ "integrity": "sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1326,6 +1487,8 @@
},
"node_modules/@babel/types": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz",
+ "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1337,7 +1500,9 @@
}
},
"node_modules/@biomejs/biome": {
- "version": "2.4.15",
+ "version": "2.4.16",
+ "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.4.16.tgz",
+ "integrity": "sha512-x9ajFh1zChVybCiM3TN6OD4phAqLgtPZjFrZF+aTMYCPjwBO+k529TX7PPsAqtGNLeV4UgzwQnowEgS7bGmzcA==",
"dev": true,
"license": "MIT OR Apache-2.0",
"bin": {
@@ -1351,18 +1516,20 @@
"url": "https://opencollective.com/biome"
},
"optionalDependencies": {
- "@biomejs/cli-darwin-arm64": "2.4.15",
- "@biomejs/cli-darwin-x64": "2.4.15",
- "@biomejs/cli-linux-arm64": "2.4.15",
- "@biomejs/cli-linux-arm64-musl": "2.4.15",
- "@biomejs/cli-linux-x64": "2.4.15",
- "@biomejs/cli-linux-x64-musl": "2.4.15",
- "@biomejs/cli-win32-arm64": "2.4.15",
- "@biomejs/cli-win32-x64": "2.4.15"
+ "@biomejs/cli-darwin-arm64": "2.4.16",
+ "@biomejs/cli-darwin-x64": "2.4.16",
+ "@biomejs/cli-linux-arm64": "2.4.16",
+ "@biomejs/cli-linux-arm64-musl": "2.4.16",
+ "@biomejs/cli-linux-x64": "2.4.16",
+ "@biomejs/cli-linux-x64-musl": "2.4.16",
+ "@biomejs/cli-win32-arm64": "2.4.16",
+ "@biomejs/cli-win32-x64": "2.4.16"
}
},
"node_modules/@biomejs/cli-darwin-arm64": {
- "version": "2.4.15",
+ "version": "2.4.16",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.4.16.tgz",
+ "integrity": "sha512-wxPvu4XOA85YJk9ixSWUmq/QBHbid85BISbOAqqBM/5xQpPk9ayjk5375tOlSC0BeCwNSbPFafQBm+vBumXq0A==",
"cpu": [
"arm64"
],
@@ -1377,9 +1544,9 @@
}
},
"node_modules/@biomejs/cli-darwin-x64": {
- "version": "2.4.15",
- "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.4.15.tgz",
- "integrity": "sha512-/5KHXYMfSJs1fNXiX30xFtI8JcCFV6zaVVLxOa0M2sfqBKHkpQhRTv94yxQWxeTY2lzo2OuTlNvPC+hDQt2wcQ==",
+ "version": "2.4.16",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.4.16.tgz",
+ "integrity": "sha512-xFCqGPwYusQJp4N4NJLi1XJiZqjwFdjhT+KqtNy+Ug3qgfczqnTa6MSDvxJF6TkuDLoYJItMapz6tAf7kCekFw==",
"cpu": [
"x64"
],
@@ -1394,9 +1561,9 @@
}
},
"node_modules/@biomejs/cli-linux-arm64": {
- "version": "2.4.15",
- "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.4.15.tgz",
- "integrity": "sha512-owaAMZD/T4LrD0ELNCk0Km3qrRHuM0X6EAyVE1FSqGY0rbLoiDLrO4Us2tllm6cAeB2Ioa9C2C08NZPdr8+0Ug==",
+ "version": "2.4.16",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.4.16.tgz",
+ "integrity": "sha512-2kFb4//jxfZaP6D+Rj5VkHkxgyD9EoRAVBEQb8PKRv+s4NO2zYNJKXFaJmK1CmhufJOWEfpHKaRbOja7qjmdhQ==",
"cpu": [
"arm64"
],
@@ -1414,9 +1581,9 @@
}
},
"node_modules/@biomejs/cli-linux-arm64-musl": {
- "version": "2.4.15",
- "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.4.15.tgz",
- "integrity": "sha512-ZPcxznxm0pogHBLZhYntyR3sR+MrZjqJIKEr7ZqVen0Rl+P/4upVmfYXjftizi9RoqZntg33fv/1fbdhbYXpEQ==",
+ "version": "2.4.16",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.4.16.tgz",
+ "integrity": "sha512-oYxnW0ARfJkr72ezzF2OR8N/rtkgLUQeYtF8cFhVswbknHxtTcmzSsanVJP8yQKnGpGpc2ck6c5zLvHahL6Cbg==",
"cpu": [
"arm64"
],
@@ -1434,9 +1601,9 @@
}
},
"node_modules/@biomejs/cli-linux-x64": {
- "version": "2.4.15",
- "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.4.15.tgz",
- "integrity": "sha512-0jj7THz12GbUOLmMibktK6DZjqz2zV64KFxyBtcFTKPiiOIY0a7vns1elpO1dERvxpsZ5ik0oFfz0oGwFde1+g==",
+ "version": "2.4.16",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.4.16.tgz",
+ "integrity": "sha512-NbcBbi/nJqn5baae6wqRXdS7Gadf2uRpehSh6vMSYpG8OhkXl/Xg8aorWrJ+9VWqAT5ml90alLvorkpMW0nBwQ==",
"cpu": [
"x64"
],
@@ -1454,9 +1621,9 @@
}
},
"node_modules/@biomejs/cli-linux-x64-musl": {
- "version": "2.4.15",
- "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.4.15.tgz",
- "integrity": "sha512-CNq/9W38SYSH023lfcQ4KKU8K0YX8T//FZUhcgtMMRABDojx5XsMV7jlweAvGSl389wJQB29Qo6Zb/a+jdvt+w==",
+ "version": "2.4.16",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.4.16.tgz",
+ "integrity": "sha512-iHDS+MCM65DPqWGu+ECC3uoALyj2H7F4nVUPxIPjz/PIl94EUu+EDfGZDzFP+NY1EOPVt9NQvwFqq7HdMmowdg==",
"cpu": [
"x64"
],
@@ -1474,9 +1641,9 @@
}
},
"node_modules/@biomejs/cli-win32-arm64": {
- "version": "2.4.15",
- "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.4.15.tgz",
- "integrity": "sha512-ouhkYdlhp/1GghEJPdWwD/Vi3gQ1nFxuSpMolWsbq3Lsq3QUR4jl6UdhhscdCugKU5vOEuMiJhvKj66O0OCq+w==",
+ "version": "2.4.16",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.4.16.tgz",
+ "integrity": "sha512-0rgImMsNb5v/chhkIFe3wu7PEFClS6RBAYUijGL9UsYN3PanSaoK24HSSuSJb1pYbYYVjzAyZTl3gtjJ84BM8A==",
"cpu": [
"arm64"
],
@@ -1491,9 +1658,9 @@
}
},
"node_modules/@biomejs/cli-win32-x64": {
- "version": "2.4.15",
- "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.4.15.tgz",
- "integrity": "sha512-zBrGq5mx5wwpnow4+2BxUvleDM+GNd4sLbPaMapsSLQLD0NGRCquqPBTgN+7XkUteHvj7M+BstuI8tmnV7+HgQ==",
+ "version": "2.4.16",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.4.16.tgz",
+ "integrity": "sha512-Kp85jgoBHa05gix6UIRjfCDiUV3w/8VIdZ247VyyO2gEjaw12WEVhdIjlxp/AMzXxqxQwbxNTDVZ3Mwd2RG5rw==",
"cpu": [
"x64"
],
@@ -1509,6 +1676,8 @@
},
"node_modules/@cloudflare/kv-asset-handler": {
"version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/@cloudflare/kv-asset-handler/-/kv-asset-handler-0.5.0.tgz",
+ "integrity": "sha512-jxQYkj8dSIzc0cD6cMMNdOc1UVjqSqu8BZdor5s8cGjW2I8BjODt/kWPVdY+u9zj3ms75Q5qaZgnxUad83+eAg==",
"dev": true,
"license": "MIT OR Apache-2.0",
"engines": {
@@ -1517,6 +1686,8 @@
},
"node_modules/@cloudflare/unenv-preset": {
"version": "2.16.1",
+ "resolved": "https://registry.npmjs.org/@cloudflare/unenv-preset/-/unenv-preset-2.16.1.tgz",
+ "integrity": "sha512-ECxObrMfyTl5bhQf/lZCXwo5G6xX9IAUo+nDMKK4SZ8m4Jvvxp52vilxyySSWh2YTZz8+HQ07qGH/2rEom1vDw==",
"dev": true,
"license": "MIT OR Apache-2.0",
"peerDependencies": {
@@ -1529,8 +1700,27 @@
}
}
},
+ "node_modules/@cloudflare/workerd-darwin-64": {
+ "version": "1.20260526.1",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20260526.1.tgz",
+ "integrity": "sha512-/pR3GH3gfv0PUp7DjI8v0aAIDOqFwibq4bg5xT7TZgcVdBV/cJQWckdXCMqiRtHiawLwogUX00EIOINkYJ1Zqg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=16"
+ }
+ },
"node_modules/@cloudflare/workerd-darwin-arm64": {
- "version": "1.20260520.1",
+ "version": "1.20260526.1",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20260526.1.tgz",
+ "integrity": "sha512-rcyu0iANYfaiezKh3Mcao1O4IIgVfQldxduiL5TZT1sP0NIeRY4YReSTrzPxNnXxSYaIqaqRHMcHbUM/ic4knA==",
"cpu": [
"arm64"
],
@@ -1544,20 +1734,75 @@
"node": ">=16"
}
},
+ "node_modules/@cloudflare/workerd-linux-64": {
+ "version": "1.20260526.1",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20260526.1.tgz",
+ "integrity": "sha512-5EZAEnlLwa9oGJRo8Nd3iY5Wcd9ROGNNG90xNIGp8MEjj8v2jTn42NC47fCZKFdnLj3+S+vWEhu1x0GVJnALjA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@cloudflare/workerd-linux-arm64": {
+ "version": "1.20260526.1",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20260526.1.tgz",
+ "integrity": "sha512-X/YBQXeXFeCN7QTStoWrATEBc9WKl7PIqkw/dQkjyJ72gh3rkLe0+Xkzp3wO7gtxTDQMa7NPGy1W4+sdMf8q1g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@cloudflare/workerd-windows-64": {
+ "version": "1.20260526.1",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20260526.1.tgz",
+ "integrity": "sha512-R+tqpFFdcfZIljx8fIW9rj9fRTtDgfoA2yonsfAGa6e8snrmr+38mdFHtkRC0D3UyZpn/hOtmXiUBfdX2gMR7Q==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=16"
+ }
+ },
"node_modules/@cloudflare/workers-types": {
- "version": "4.20260522.1",
+ "version": "4.20260601.1",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20260601.1.tgz",
+ "integrity": "sha512-pYORr1EKlDu55HCHhln8XSXoOSvKAkrTkovJL66bX8xw6DAT2fhs39B6FLjCJD+x++hjBEE2bmKB1TcFKS+0Dw==",
"dev": true,
"license": "MIT OR Apache-2.0"
},
"node_modules/@commitlint/cli": {
- "version": "21.0.1",
+ "version": "21.0.2",
+ "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-21.0.2.tgz",
+ "integrity": "sha512-YMmfLbqBg+ZRvvmPhc+cilSQFrh/AgzVgCT1U/OifmUZEwPbvCtA8rN//YNaF9d5eoZphxVMGYtmwA2QgQORgg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@commitlint/format": "^21.0.1",
- "@commitlint/lint": "^21.0.1",
- "@commitlint/load": "^21.0.1",
- "@commitlint/read": "^21.0.1",
+ "@commitlint/lint": "^21.0.2",
+ "@commitlint/load": "^21.0.2",
+ "@commitlint/read": "^21.0.2",
"@commitlint/types": "^21.0.1",
"tinyexec": "^1.0.0",
"yargs": "^18.0.0"
@@ -1570,7 +1815,9 @@
}
},
"node_modules/@commitlint/config-conventional": {
- "version": "21.0.1",
+ "version": "21.0.2",
+ "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-21.0.2.tgz",
+ "integrity": "sha512-P/ZRhryQmkj0Z0dY9FOoRwe3xkwJyyAdtXwt01NT2kuZttcG2CNYp1q5Ci3u+nDT2jcbJRw2kt13Czl1qKNPfg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1583,6 +1830,8 @@
},
"node_modules/@commitlint/config-validator": {
"version": "21.0.1",
+ "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-21.0.1.tgz",
+ "integrity": "sha512-Zd2UFdndeMMaW2O96HK0tdfT4gOImUvidMpAd/pws2zZ4m1nrAZ/9b/v2JYuE8fs86GpXv9F7LNaIuCIWhY+pA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1595,6 +1844,8 @@
},
"node_modules/@commitlint/ensure": {
"version": "21.0.1",
+ "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-21.0.1.tgz",
+ "integrity": "sha512-jJ1037967wU7YN/xkv+iRlOBlmaOXPhPO5KQSqya6GyXzBlwuLzELBFao16DVg9dZyqmNrhewzwZ3SAibetHBQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1607,6 +1858,8 @@
},
"node_modules/@commitlint/execute-rule": {
"version": "21.0.1",
+ "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-21.0.1.tgz",
+ "integrity": "sha512-RifH+FmImozKBE6mozhF4K3r2RRKP7SMi/Q/zLCmExtp5e05lhHOUYqGBlFBAGNHaZxU/WYw1XuugYK9jQzqnA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -1615,6 +1868,8 @@
},
"node_modules/@commitlint/format": {
"version": "21.0.1",
+ "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-21.0.1.tgz",
+ "integrity": "sha512-ksmG2+cHGtuDPQQbhBbC4unwm444+6TiPw0d1bKf67hntgZqZ8E0g1MuYKUuyT5IH4IMmXZhKq22/Z3jBvtQIw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1626,7 +1881,9 @@
}
},
"node_modules/@commitlint/is-ignored": {
- "version": "21.0.1",
+ "version": "21.0.2",
+ "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-21.0.2.tgz",
+ "integrity": "sha512-H5z4t8PC9tUsmZ/o+EptM3Nq8sTFtskAShdcqxCoyzklW5eaVT5xbrDAET2uypzir9Vsj4ZZmBtyKjYe2XqgeQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1638,13 +1895,15 @@
}
},
"node_modules/@commitlint/lint": {
- "version": "21.0.1",
+ "version": "21.0.2",
+ "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-21.0.2.tgz",
+ "integrity": "sha512-PnUmLYGeGLfW8oVatR9KpNxSHYAnJOEWlMZzfdeFOUq6WUrFx1fGQaWCWJqMoIll/xPM+GdfJV+tKHZVHhl0Fg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@commitlint/is-ignored": "^21.0.1",
- "@commitlint/parse": "^21.0.1",
- "@commitlint/rules": "^21.0.1",
+ "@commitlint/is-ignored": "^21.0.2",
+ "@commitlint/parse": "^21.0.2",
+ "@commitlint/rules": "^21.0.2",
"@commitlint/types": "^21.0.1"
},
"engines": {
@@ -1652,7 +1911,9 @@
}
},
"node_modules/@commitlint/load": {
- "version": "21.0.1",
+ "version": "21.0.2",
+ "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-21.0.2.tgz",
+ "integrity": "sha512-lwUE70hN0/qE/ZRROhbaX65ly/FF12DrqfReLCESo37M0OQCFAf2jRS+2tSCSORq+bm4Kdju7qNDj46uc1QzTA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1671,7 +1932,9 @@
}
},
"node_modules/@commitlint/message": {
- "version": "21.0.1",
+ "version": "21.0.2",
+ "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-21.0.2.tgz",
+ "integrity": "sha512-5n4aqHGD/FNnom/D5L8i7cYtV+xjuXcBL832C3w9VglEsZzIsoHpJsvxzJ7cgiOsOdc/2jU4t5+7qMHh7GBX3g==",
"dev": true,
"license": "MIT",
"engines": {
@@ -1679,7 +1942,9 @@
}
},
"node_modules/@commitlint/parse": {
- "version": "21.0.1",
+ "version": "21.0.2",
+ "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-21.0.2.tgz",
+ "integrity": "sha512-QVZJhGHTm+oiuWyEKOCTQ0ZM3mfJ0eGWFeHuj7WzSKEth+UukcCHac9GD8pgdFlg/qGkFWOtyaNd1T8REgagaw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1692,11 +1957,13 @@
}
},
"node_modules/@commitlint/read": {
- "version": "21.0.1",
+ "version": "21.0.2",
+ "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-21.0.2.tgz",
+ "integrity": "sha512-BtsrnLVycSSKf4Q0gMch4giCj5NNlmcbhc8ra5vONgGtP2IjRDo33bEFtr5Pm+2N+5fXGWb2MksWPrspPfdhdw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@commitlint/top-level": "^21.0.1",
+ "@commitlint/top-level": "^21.0.2",
"@commitlint/types": "^21.0.1",
"git-raw-commits": "^5.0.0",
"tinyexec": "^1.0.0"
@@ -1707,6 +1974,8 @@
},
"node_modules/@commitlint/resolve-extends": {
"version": "21.0.1",
+ "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-21.0.1.tgz",
+ "integrity": "sha512-0DhjYWL6uYrY16Efa032fYk3woGJDU4AGWiG1XXltT9AMUNYKyb5cIZU2ivbaMZ3+kKFqUjikD2cjh66Sbh/Sg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1721,12 +1990,14 @@
}
},
"node_modules/@commitlint/rules": {
- "version": "21.0.1",
+ "version": "21.0.2",
+ "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-21.0.2.tgz",
+ "integrity": "sha512-k6tQ69Td7t2qUSIbik8D3TL1q3ZJpkEbV+yLogDzCRAdOxJm4ndhtBNREsLA1/puRfWvzS9eioF2w43WT+hHgQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@commitlint/ensure": "^21.0.1",
- "@commitlint/message": "^21.0.1",
+ "@commitlint/message": "^21.0.2",
"@commitlint/to-lines": "^21.0.1",
"@commitlint/types": "^21.0.1"
},
@@ -1736,6 +2007,8 @@
},
"node_modules/@commitlint/to-lines": {
"version": "21.0.1",
+ "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-21.0.1.tgz",
+ "integrity": "sha512-bd1BFII7p1EQZre9Kaj+kKaMFP3cFCdt21K7DItVux9XP5WjLgJ0/Uy1pJJh9aPwVJ6SKg62PxqlZaHI8hQAXw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -1743,7 +2016,9 @@
}
},
"node_modules/@commitlint/top-level": {
- "version": "21.0.1",
+ "version": "21.0.2",
+ "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-21.0.2.tgz",
+ "integrity": "sha512-s9KKM+e+mXgFeIh4n7KmOGAVT3mkJ3Fp1bBYHIK5pjeUwlEMzp/tZfb5u0Poa680AsQTXMEMRxZi1vQ9m2X5ug==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1755,6 +2030,8 @@
},
"node_modules/@commitlint/types": {
"version": "21.0.1",
+ "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-21.0.1.tgz",
+ "integrity": "sha512-4u7w8jcoCUFWhjWnASYzZHAP34OqOtuFBN87nQmFvqda03YU0T6z+yB4w0gSAMpekiRqqGk5rt+qSlW+a2vSEg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1767,6 +2044,8 @@
},
"node_modules/@conventional-changelog/git-client": {
"version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/@conventional-changelog/git-client/-/git-client-2.7.0.tgz",
+ "integrity": "sha512-j7A8/LBEQ+3rugMzPXoKYzyUPpw/0CBQCyvtTR7Lmu4olG4yRC/Tfkq79Mr3yuPs0SUitlO2HwGP3gitMJnRFw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1792,6 +2071,8 @@
},
"node_modules/@cspotcode/source-map-support": {
"version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
+ "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1803,6 +2084,8 @@
},
"node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": {
"version": "0.3.9",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
+ "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1900,6 +2183,8 @@
},
"node_modules/@duckdb/duckdb-wasm": {
"version": "1.33.1-dev45.0",
+ "resolved": "https://registry.npmjs.org/@duckdb/duckdb-wasm/-/duckdb-wasm-1.33.1-dev45.0.tgz",
+ "integrity": "sha512-ETlrjhiGQzNdaOhpro/Y9u/RCcK+iyuczLy7uOn0kG5Mqlj8C+gTuhBXjs4JpK9ocdUgr3oT8zYYIbUnFD9AYA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1909,6 +2194,8 @@
},
"node_modules/@duckdb/duckdb-wasm/node_modules/@types/node": {
"version": "20.19.41",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.41.tgz",
+ "integrity": "sha512-ECymXOukMnOoVkC2bb1Vc/w/836DXncOg5m8Xj1RH7xSHZJWNYY6Zh7EH477vcnD5egKNNfy2RpNOmuChhFPgQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1917,6 +2204,8 @@
},
"node_modules/@duckdb/duckdb-wasm/node_modules/apache-arrow": {
"version": "17.0.0",
+ "resolved": "https://registry.npmjs.org/apache-arrow/-/apache-arrow-17.0.0.tgz",
+ "integrity": "sha512-X0p7auzdnGuhYMVKYINdQssS4EcKec9TCXyez/qtJt32DrIMGbzqiaMiQ0X6fQlQpw8Fl0Qygcv4dfRAr5Gu9Q==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -1936,6 +2225,8 @@
},
"node_modules/@duckdb/duckdb-wasm/node_modules/array-back": {
"version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz",
+ "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==",
"dev": true,
"license": "MIT",
"engines": {
@@ -1944,6 +2235,8 @@
},
"node_modules/@duckdb/duckdb-wasm/node_modules/command-line-args": {
"version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.1.tgz",
+ "integrity": "sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1958,6 +2251,8 @@
},
"node_modules/@duckdb/duckdb-wasm/node_modules/find-replace": {
"version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz",
+ "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1969,11 +2264,15 @@
},
"node_modules/@duckdb/duckdb-wasm/node_modules/flatbuffers": {
"version": "24.12.23",
+ "resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-24.12.23.tgz",
+ "integrity": "sha512-dLVCAISd5mhls514keQzmEG6QHmUUsNuWsb4tFafIUwvvgDjXhtfAYSKOzt5SWOy+qByV5pbsDZ+Vb7HUOBEdA==",
"dev": true,
"license": "Apache-2.0"
},
"node_modules/@duckdb/duckdb-wasm/node_modules/typical": {
"version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz",
+ "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -1982,11 +2281,15 @@
},
"node_modules/@duckdb/duckdb-wasm/node_modules/undici-types": {
"version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
+ "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
"dev": true,
"license": "MIT"
},
"node_modules/@duckdb/node-api": {
"version": "1.5.3-r.1",
+ "resolved": "https://registry.npmjs.org/@duckdb/node-api/-/node-api-1.5.3-r.1.tgz",
+ "integrity": "sha512-Z68b/SfFoECdmVNis708kGoamabox1NezejKyU6bPucoTig8DNTAVKU9R9gT4wl5c5qZ3RUy+jpe6F5Xa6Z3Iw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1995,6 +2298,8 @@
},
"node_modules/@duckdb/node-bindings": {
"version": "1.5.3-r.1",
+ "resolved": "https://registry.npmjs.org/@duckdb/node-bindings/-/node-bindings-1.5.3-r.1.tgz",
+ "integrity": "sha512-vDMuaEFd0JnboKdDw8hSN47OS0u3hw++YCCApPM3uYCFFuIK0RKXTqKe0pTLEMo4IIv3qVJym/rpDhqPLMUEuA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -2013,6 +2318,8 @@
},
"node_modules/@duckdb/node-bindings-darwin-arm64": {
"version": "1.5.3-r.1",
+ "resolved": "https://registry.npmjs.org/@duckdb/node-bindings-darwin-arm64/-/node-bindings-darwin-arm64-1.5.3-r.1.tgz",
+ "integrity": "sha512-r87Cc/NB3cC6Jfxh4wv/j2N1XUxm/dMoPa6QwdvOsU/KyU3IwDRed5hpAVIxbp7SYXs8IEnws3E/m+toNVZt2A==",
"cpu": [
"arm64"
],
@@ -2023,6 +2330,150 @@
"darwin"
]
},
+ "node_modules/@duckdb/node-bindings-darwin-x64": {
+ "version": "1.5.3-r.1",
+ "resolved": "https://registry.npmjs.org/@duckdb/node-bindings-darwin-x64/-/node-bindings-darwin-x64-1.5.3-r.1.tgz",
+ "integrity": "sha512-S/8JXK2OR5fzSKvWdpdOuLCuzv+TUxnhLxA8twXYEC09GqimW6DIdvLquOVuykvfbBpoImz8UJpA+zOIpqlHEQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@duckdb/node-bindings-linux-arm64": {
+ "version": "1.5.3-r.1",
+ "resolved": "https://registry.npmjs.org/@duckdb/node-bindings-linux-arm64/-/node-bindings-linux-arm64-1.5.3-r.1.tgz",
+ "integrity": "sha512-bpa3d42iGTOZ2YOviUA/PGT/GGnnkmPR5W2hccAPEgfN2Doz1A7A5T899K9TIVCkdxwr7Xxoa7CiqMgzPgxdJg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@duckdb/node-bindings-linux-arm64-musl": {
+ "version": "1.5.3-r.1",
+ "resolved": "https://registry.npmjs.org/@duckdb/node-bindings-linux-arm64-musl/-/node-bindings-linux-arm64-musl-1.5.3-r.1.tgz",
+ "integrity": "sha512-gNcmx+ChrGW5Ykc446mV4P+IgaEDq8fO7Y8aYeGA+XRIdy2fpZCsjo99Vv5zUKlY0IuvGwM0WFUF03oA0KksBQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@duckdb/node-bindings-linux-x64": {
+ "version": "1.5.3-r.1",
+ "resolved": "https://registry.npmjs.org/@duckdb/node-bindings-linux-x64/-/node-bindings-linux-x64-1.5.3-r.1.tgz",
+ "integrity": "sha512-gCuxN9jabTJVJnYq59n0ba5AR1nix17v5OT3VXNzx/iZldX1MH5Gihp8of7OTaQILGuZ+APqCASL3s5fBgrqFg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@duckdb/node-bindings-linux-x64-musl": {
+ "version": "1.5.3-r.1",
+ "resolved": "https://registry.npmjs.org/@duckdb/node-bindings-linux-x64-musl/-/node-bindings-linux-x64-musl-1.5.3-r.1.tgz",
+ "integrity": "sha512-ZVEofh6i8RKbbnAYJvU+/BatDW2tR3ee4Uvcm5b7lz53FWXsCyqh5Kh8LBRuUBq5rurOoWmrVry/g1i7wBZgjg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@duckdb/node-bindings-win32-arm64": {
+ "version": "1.5.3-r.1",
+ "resolved": "https://registry.npmjs.org/@duckdb/node-bindings-win32-arm64/-/node-bindings-win32-arm64-1.5.3-r.1.tgz",
+ "integrity": "sha512-RHEfClLwLZo/aZrBKZn9ugZEnlB8ucnM61T+B9tYKCsz5RT29ueVVzyTLvuHemc5W3cZPki8xsohno8Txl6qeQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@duckdb/node-bindings-win32-x64": {
+ "version": "1.5.3-r.1",
+ "resolved": "https://registry.npmjs.org/@duckdb/node-bindings-win32-x64/-/node-bindings-win32-x64-1.5.3-r.1.tgz",
+ "integrity": "sha512-Ff6lenczCvN9g/3hjBKkn/bZe2DwxUOVrC+eNYZnqdSHcpGP6K4knV7eWIjEkOC5cZoki+Cwd822L3ivt22/5Q==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@emnapi/core": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz",
+ "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/wasi-threads": "1.2.1",
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@emnapi/runtime": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz",
+ "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@emnapi/wasi-threads": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz",
+ "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
"node_modules/@esbuild/aix-ppc64": {
"version": "0.28.0",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.0.tgz",
@@ -2089,6 +2540,8 @@
},
"node_modules/@esbuild/darwin-arm64": {
"version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.0.tgz",
+ "integrity": "sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q==",
"cpu": [
"arm64"
],
@@ -2439,6 +2892,8 @@
},
"node_modules/@fluent/syntax": {
"version": "0.19.0",
+ "resolved": "https://registry.npmjs.org/@fluent/syntax/-/syntax-0.19.0.tgz",
+ "integrity": "sha512-5D2qVpZrgpjtqU4eNOcWGp1gnUCgjfM+vKGE2y03kKN6z5EBhtx0qdRFbg8QuNNj8wXNoX93KJoYb+NqoxswmQ==",
"license": "Apache-2.0",
"engines": {
"node": ">=14.0.0",
@@ -2447,6 +2902,8 @@
},
"node_modules/@img/colour": {
"version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz",
+ "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -2455,6 +2912,8 @@
},
"node_modules/@img/sharp-darwin-arm64": {
"version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz",
+ "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==",
"cpu": [
"arm64"
],
@@ -2474,8 +2933,33 @@
"@img/sharp-libvips-darwin-arm64": "1.2.4"
}
},
+ "node_modules/@img/sharp-darwin-x64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz",
+ "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-darwin-x64": "1.2.4"
+ }
+ },
"node_modules/@img/sharp-libvips-darwin-arm64": {
"version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz",
+ "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==",
"cpu": [
"arm64"
],
@@ -2489,46 +2973,517 @@
"url": "https://opencollective.com/libvips"
}
},
- "node_modules/@inquirer/ansi": {
- "version": "2.0.6",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0"
- }
- },
- "node_modules/@inquirer/checkbox": {
- "version": "5.2.0",
+ "node_modules/@img/sharp-libvips-darwin-x64": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz",
+ "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==",
+ "cpu": [
+ "x64"
+ ],
"dev": true,
- "license": "MIT",
- "dependencies": {
- "@inquirer/ansi": "^2.0.6",
- "@inquirer/core": "^11.2.0",
- "@inquirer/figures": "^2.0.6",
- "@inquirer/type": "^4.0.6"
- },
- "engines": {
- "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0"
- },
- "peerDependencies": {
- "@types/node": ">=18"
- },
- "peerDependenciesMeta": {
- "@types/node": {
- "optional": true
- }
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
}
},
- "node_modules/@inquirer/confirm": {
- "version": "6.1.0",
+ "node_modules/@img/sharp-libvips-linux-arm": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz",
+ "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==",
+ "cpu": [
+ "arm"
+ ],
"dev": true,
- "license": "MIT",
- "dependencies": {
- "@inquirer/core": "^11.2.0",
- "@inquirer/type": "^4.0.6"
- },
- "engines": {
- "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0"
+ "libc": [
+ "glibc"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linux-arm64": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz",
+ "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linux-ppc64": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz",
+ "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linux-riscv64": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz",
+ "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linux-s390x": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz",
+ "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linux-x64": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz",
+ "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linuxmusl-arm64": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz",
+ "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linuxmusl-x64": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz",
+ "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-linux-arm": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz",
+ "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-arm": "1.2.4"
+ }
+ },
+ "node_modules/@img/sharp-linux-arm64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz",
+ "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-arm64": "1.2.4"
+ }
+ },
+ "node_modules/@img/sharp-linux-ppc64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz",
+ "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-ppc64": "1.2.4"
+ }
+ },
+ "node_modules/@img/sharp-linux-riscv64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz",
+ "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-riscv64": "1.2.4"
+ }
+ },
+ "node_modules/@img/sharp-linux-s390x": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz",
+ "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-s390x": "1.2.4"
+ }
+ },
+ "node_modules/@img/sharp-linux-x64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz",
+ "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-x64": "1.2.4"
+ }
+ },
+ "node_modules/@img/sharp-linuxmusl-arm64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz",
+ "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linuxmusl-arm64": "1.2.4"
+ }
+ },
+ "node_modules/@img/sharp-linuxmusl-x64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz",
+ "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linuxmusl-x64": "1.2.4"
+ }
+ },
+ "node_modules/@img/sharp-wasm32": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz",
+ "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==",
+ "cpu": [
+ "wasm32"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/runtime": "^1.7.0"
+ },
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-win32-arm64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz",
+ "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 AND LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-win32-ia32": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz",
+ "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 AND LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-win32-x64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz",
+ "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 AND LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@inquirer/ansi": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-2.0.7.tgz",
+ "integrity": "sha512-3eTuUO1vH2cZm2ZKHeQxnOqlTi9EfZDGgIe3BL3I4u+rJHocr9Fz86M4fjYABPvFnQG/gGK551HqDiIcETwU6Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
+ }
+ },
+ "node_modules/@inquirer/checkbox": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-5.2.1.tgz",
+ "integrity": "sha512-b6xmA/VlTe0ZgDQHDui+Nav470u7u49nRd8/iuhOcQPO9Ch7lGuogydhi2VOmNlZ+zXcM8IcPuNSwQcdJaF/kw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@inquirer/ansi": "^2.0.7",
+ "@inquirer/core": "^11.2.1",
+ "@inquirer/figures": "^2.0.7",
+ "@inquirer/type": "^4.0.7"
+ },
+ "engines": {
+ "node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
+ },
+ "peerDependencies": {
+ "@types/node": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@inquirer/confirm": {
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-6.1.1.tgz",
+ "integrity": "sha512-eb8DBZcz/2qHWQda4rk2JiQk5h9QV/cVHi1yjt0f69WFZMRFn0sJTye3EAP8icut8UDMjQPsaH5KbcOogefrFQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@inquirer/core": "^11.2.1",
+ "@inquirer/type": "^4.0.7"
+ },
+ "engines": {
+ "node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
},
"peerDependencies": {
"@types/node": ">=18"
@@ -2540,20 +3495,22 @@
}
},
"node_modules/@inquirer/core": {
- "version": "11.2.0",
+ "version": "11.2.1",
+ "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-11.2.1.tgz",
+ "integrity": "sha512-Qd6GJT1yVyrZZCfN8W2qKF5ApmqryXRhRKCuip8h01x2w/esJQ2XIYc6f9abMIHgKQdBfFTSOdbHRLAhuM09UA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@inquirer/ansi": "^2.0.6",
- "@inquirer/figures": "^2.0.6",
- "@inquirer/type": "^4.0.6",
+ "@inquirer/ansi": "^2.0.7",
+ "@inquirer/figures": "^2.0.7",
+ "@inquirer/type": "^4.0.7",
"cli-width": "^4.1.0",
"fast-wrap-ansi": "^0.2.0",
- "mute-stream": "^4.0.0",
+ "mute-stream": "^3.0.0",
"signal-exit": "^4.1.0"
},
"engines": {
- "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0"
+ "node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
},
"peerDependencies": {
"@types/node": ">=18"
@@ -2565,16 +3522,18 @@
}
},
"node_modules/@inquirer/editor": {
- "version": "5.2.0",
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-5.2.2.tgz",
+ "integrity": "sha512-ZRVd/oD+sYsUd5zVm0NflqEzlqfYCyHNsqkHl2oWXEUHs12tCbcSFi+wVFEvD8+LGRaMUsVrE7qeo6lSG/S1Vg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@inquirer/core": "^11.2.0",
- "@inquirer/external-editor": "^3.0.1",
- "@inquirer/type": "^4.0.6"
+ "@inquirer/core": "^11.2.1",
+ "@inquirer/external-editor": "^3.0.3",
+ "@inquirer/type": "^4.0.7"
},
"engines": {
- "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0"
+ "node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
},
"peerDependencies": {
"@types/node": ">=18"
@@ -2586,15 +3545,17 @@
}
},
"node_modules/@inquirer/expand": {
- "version": "5.1.0",
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-5.1.1.tgz",
+ "integrity": "sha512-YmQpenjbFSHAK3sOd44puHh3V1KXXr+JiNpUztoSQ4drLh2rTVzTap/YtlAVu/5xavifIlBfNEzJ/neZJ1a/1g==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@inquirer/core": "^11.2.0",
- "@inquirer/type": "^4.0.6"
+ "@inquirer/core": "^11.2.1",
+ "@inquirer/type": "^4.0.7"
},
"engines": {
- "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0"
+ "node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
},
"peerDependencies": {
"@types/node": ">=18"
@@ -2606,7 +3567,9 @@
}
},
"node_modules/@inquirer/external-editor": {
- "version": "3.0.1",
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-3.0.3.tgz",
+ "integrity": "sha512-6thf5I8q7lZwzGLAxPaaGEREEkZ3nyePPDQ1oyobblxmEE8mqTLguScP7pDjUTAibiyb4hfXl+qjUEJ+di/aNA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -2614,7 +3577,7 @@
"iconv-lite": "^0.7.2"
},
"engines": {
- "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0"
+ "node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
},
"peerDependencies": {
"@types/node": ">=18"
@@ -2626,23 +3589,27 @@
}
},
"node_modules/@inquirer/figures": {
- "version": "2.0.6",
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-2.0.7.tgz",
+ "integrity": "sha512-aJ8TBPOGB6f/2qziPfElISTCEd5XOYTFckA2SGjhNmiKzfK/u4ot3v0DUzGVdUnKjN10EqnnEPck36BkyfLnJw==",
"dev": true,
"license": "MIT",
"engines": {
- "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0"
+ "node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
}
},
"node_modules/@inquirer/input": {
- "version": "5.1.0",
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-5.1.2.tgz",
+ "integrity": "sha512-9K/DDBSQpOyZSkt6sOVP9Vo0TR7atX2kuILsUu0x3wVcVbe97lJwIJKMLdMw25tDYuXl/qp6erT0Xs1rfmcfZg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@inquirer/core": "^11.2.0",
- "@inquirer/type": "^4.0.6"
+ "@inquirer/core": "^11.2.1",
+ "@inquirer/type": "^4.0.7"
},
"engines": {
- "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0"
+ "node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
},
"peerDependencies": {
"@types/node": ">=18"
@@ -2654,15 +3621,17 @@
}
},
"node_modules/@inquirer/number": {
- "version": "4.1.0",
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-4.1.1.tgz",
+ "integrity": "sha512-XF4IXAbPnGPgw0wsbC/i2tPcyfdZgDpUlhsqU0SfT4IRIGWha6Xm9VRgN5yYxJq+jnyXlfXI/nQ3ulfk0iEICA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@inquirer/core": "^11.2.0",
- "@inquirer/type": "^4.0.6"
+ "@inquirer/core": "^11.2.1",
+ "@inquirer/type": "^4.0.7"
},
"engines": {
- "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0"
+ "node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
},
"peerDependencies": {
"@types/node": ">=18"
@@ -2674,16 +3643,18 @@
}
},
"node_modules/@inquirer/password": {
- "version": "5.1.0",
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-5.1.1.tgz",
+ "integrity": "sha512-3XBfF7DAsp5qeDsvN5Rd1HmbNokVvEQoUM0QLrRcybC9nX96w3Pbmu7qUsb3IT3J3jBvs2+mTXaKHOUsgHMLzg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@inquirer/ansi": "^2.0.6",
- "@inquirer/core": "^11.2.0",
- "@inquirer/type": "^4.0.6"
+ "@inquirer/ansi": "^2.0.7",
+ "@inquirer/core": "^11.2.1",
+ "@inquirer/type": "^4.0.7"
},
"engines": {
- "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0"
+ "node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
},
"peerDependencies": {
"@types/node": ">=18"
@@ -2695,23 +3666,25 @@
}
},
"node_modules/@inquirer/prompts": {
- "version": "8.5.0",
+ "version": "8.5.2",
+ "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-8.5.2.tgz",
+ "integrity": "sha512-IYR/3C/paEVVQYQvdDlFZVjRCJVYHHON0XXMH91KO9GSxs0TdKYWlUdvfQl2EfAHDxUaN3IBffkE/BDTh5nJ6g==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@inquirer/checkbox": "^5.2.0",
- "@inquirer/confirm": "^6.1.0",
- "@inquirer/editor": "^5.2.0",
- "@inquirer/expand": "^5.1.0",
- "@inquirer/input": "^5.1.0",
- "@inquirer/number": "^4.1.0",
- "@inquirer/password": "^5.1.0",
- "@inquirer/rawlist": "^5.3.0",
- "@inquirer/search": "^4.2.0",
- "@inquirer/select": "^5.2.0"
+ "@inquirer/checkbox": "^5.2.1",
+ "@inquirer/confirm": "^6.1.1",
+ "@inquirer/editor": "^5.2.2",
+ "@inquirer/expand": "^5.1.1",
+ "@inquirer/input": "^5.1.2",
+ "@inquirer/number": "^4.1.1",
+ "@inquirer/password": "^5.1.1",
+ "@inquirer/rawlist": "^5.3.1",
+ "@inquirer/search": "^4.2.1",
+ "@inquirer/select": "^5.2.1"
},
"engines": {
- "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0"
+ "node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
},
"peerDependencies": {
"@types/node": ">=18"
@@ -2723,15 +3696,17 @@
}
},
"node_modules/@inquirer/rawlist": {
- "version": "5.3.0",
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-5.3.1.tgz",
+ "integrity": "sha512-QqdTqQddL3qPX/PPrjobpsO25NZ4dWXgTLenrR445L2ptLEYE6Z+PD5c5CNDJNx4ugRgELAIpSIJxZaO2jJ2Og==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@inquirer/core": "^11.2.0",
- "@inquirer/type": "^4.0.6"
+ "@inquirer/core": "^11.2.1",
+ "@inquirer/type": "^4.0.7"
},
"engines": {
- "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0"
+ "node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
},
"peerDependencies": {
"@types/node": ">=18"
@@ -2743,16 +3718,18 @@
}
},
"node_modules/@inquirer/search": {
- "version": "4.2.0",
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-4.2.1.tgz",
+ "integrity": "sha512-xJj8QWKRSrfKoBIITLZK61dD3zwo0Rz11fgDImku30/Oe81zMdIdGgrLY2h6RkJ+KZ/GhNYIRMKnH/62qBTA5g==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@inquirer/core": "^11.2.0",
- "@inquirer/figures": "^2.0.6",
- "@inquirer/type": "^4.0.6"
+ "@inquirer/core": "^11.2.1",
+ "@inquirer/figures": "^2.0.7",
+ "@inquirer/type": "^4.0.7"
},
"engines": {
- "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0"
+ "node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
},
"peerDependencies": {
"@types/node": ">=18"
@@ -2764,17 +3741,19 @@
}
},
"node_modules/@inquirer/select": {
- "version": "5.2.0",
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-5.2.1.tgz",
+ "integrity": "sha512-FlDndEUww8m7BfukO2nJa25vhD+H5jxxCv4oGioKqzyWz3nPHhhw4LKdYRSlXuAx7DsdWia7iyaBPKKS95Evfw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@inquirer/ansi": "^2.0.6",
- "@inquirer/core": "^11.2.0",
- "@inquirer/figures": "^2.0.6",
- "@inquirer/type": "^4.0.6"
+ "@inquirer/ansi": "^2.0.7",
+ "@inquirer/core": "^11.2.1",
+ "@inquirer/figures": "^2.0.7",
+ "@inquirer/type": "^4.0.7"
},
"engines": {
- "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0"
+ "node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
},
"peerDependencies": {
"@types/node": ">=18"
@@ -2786,11 +3765,13 @@
}
},
"node_modules/@inquirer/type": {
- "version": "4.0.6",
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-4.0.7.tgz",
+ "integrity": "sha512-t28inv14nMQ1PhKpsJPY+kEs/c00qzeCOS2gTNRyTjG5d6qsVA2fItxW4hkvGZ5lvanGLdtCzVIx5dwdRpN1+g==",
"dev": true,
"license": "MIT",
"engines": {
- "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0"
+ "node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
},
"peerDependencies": {
"@types/node": ">=18"
@@ -2803,6 +3784,8 @@
},
"node_modules/@isaacs/cliui": {
"version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
+ "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
"license": "ISC",
"dependencies": {
"string-width": "^5.1.2",
@@ -2818,10 +3801,14 @@
},
"node_modules/@isaacs/cliui/node_modules/emoji-regex": {
"version": "9.2.2",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
+ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
"license": "MIT"
},
"node_modules/@isaacs/cliui/node_modules/string-width": {
"version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
+ "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
"license": "MIT",
"dependencies": {
"eastasianwidth": "^0.2.0",
@@ -2837,6 +3824,8 @@
},
"node_modules/@isaacs/cliui/node_modules/wrap-ansi": {
"version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
+ "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
"license": "MIT",
"dependencies": {
"ansi-styles": "^6.1.0",
@@ -2852,6 +3841,8 @@
},
"node_modules/@jridgewell/gen-mapping": {
"version": "0.3.13",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
+ "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
"license": "MIT",
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.5.0",
@@ -2860,6 +3851,8 @@
},
"node_modules/@jridgewell/remapping": {
"version": "2.3.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
+ "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
"license": "MIT",
"dependencies": {
"@jridgewell/gen-mapping": "^0.3.5",
@@ -2868,139 +3861,450 @@
},
"node_modules/@jridgewell/resolve-uri": {
"version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.5.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
+ "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
+ "license": "MIT"
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.31",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
+ "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
+ "node_modules/@napi-rs/wasm-runtime": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz",
+ "integrity": "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@tybys/wasm-util": "^0.10.1"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/Brooooooklyn"
+ },
+ "peerDependencies": {
+ "@emnapi/core": "^1.7.1",
+ "@emnapi/runtime": "^1.7.1"
+ }
+ },
+ "node_modules/@nodable/entities": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/@nodable/entities/-/entities-2.1.1.tgz",
+ "integrity": "sha512-Pig3HxDIoMgjdEH8OCf/dkcTmLFjJRjWuq8jSnklu284/TKOPibSRERmOykiwmyXTtv61mP+44f3GMx0tLAyjg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/nodable"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@one-ini/wasm": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/@one-ini/wasm/-/wasm-0.1.1.tgz",
+ "integrity": "sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==",
+ "license": "MIT"
+ },
+ "node_modules/@oxc-project/types": {
+ "version": "0.133.0",
+ "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.133.0.tgz",
+ "integrity": "sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/Boshen"
+ }
+ },
+ "node_modules/@pkgjs/parseargs": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
+ "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/@plausible-analytics/tracker": {
+ "version": "0.4.5",
+ "resolved": "https://registry.npmjs.org/@plausible-analytics/tracker/-/tracker-0.4.5.tgz",
+ "integrity": "sha512-6BfAGejXY+YA3Cw6LYT2Zpn4hTxDtPQAawFsYUsQCOg78wIS5C4deAGXTfJffa5VleMWITv5lpJ/EYuQBl1tPA==",
+ "license": "MIT"
+ },
+ "node_modules/@polka/url": {
+ "version": "1.0.0-next.29",
+ "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz",
+ "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@poppinss/colors": {
+ "version": "4.1.6",
+ "resolved": "https://registry.npmjs.org/@poppinss/colors/-/colors-4.1.6.tgz",
+ "integrity": "sha512-H9xkIdFswbS8n1d6vmRd8+c10t2Qe+rZITbbDHHkQixH5+2x1FDGmi/0K+WgWiqQFKPSlIYB7jlH6Kpfn6Fleg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "kleur": "^4.1.5"
+ }
+ },
+ "node_modules/@poppinss/dumper": {
+ "version": "0.6.5",
+ "resolved": "https://registry.npmjs.org/@poppinss/dumper/-/dumper-0.6.5.tgz",
+ "integrity": "sha512-NBdYIb90J7LfOI32dOewKI1r7wnkiH6m920puQ3qHUeZkxNkQiFnXVWoE6YtFSv6QOiPPf7ys6i+HWWecDz7sw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@poppinss/colors": "^4.1.5",
+ "@sindresorhus/is": "^7.0.2",
+ "supports-color": "^10.0.0"
+ }
+ },
+ "node_modules/@poppinss/dumper/node_modules/supports-color": {
+ "version": "10.2.2",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-10.2.2.tgz",
+ "integrity": "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
+ }
+ },
+ "node_modules/@poppinss/exception": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/@poppinss/exception/-/exception-1.2.3.tgz",
+ "integrity": "sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@rolldown/binding-android-arm64": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.3.tgz",
+ "integrity": "sha512-454rs7jHngixp/NMxd5srYD57OnzSlZ/eFTETjORQHLwJG1lRtmNOJcBerZlfu4GjKqeq8aCCIQrMdHyhI51Hw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-darwin-arm64": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.3.tgz",
+ "integrity": "sha512-PcAhP+ynjURNyy8SKGl5DQP94aGuB/7JrXJb/t7P+hanXvQVMWzUvRRhBAcg/lNRadBhoUPqSoP4xw5tR/KBEA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-darwin-x64": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.3.tgz",
+ "integrity": "sha512-9YpfeUvSE2RS7wysJ81uOZkXJz7f7Q55H2Gvp3VEw/EsahqDtrphrZ0EwDLK5vvKOzaCrBsjF8JmnMLcUt78Gg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-freebsd-x64": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.3.tgz",
+ "integrity": "sha512-yB1IlAsSNHncV6SCTL27/MVGR5htvQsoGxIv5KMGXALp+Ll1wYsn+x98M9MW7qa+NdSbvrrY7ANI4wLJ0n1e6g==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
"license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
"engines": {
- "node": ">=6.0.0"
+ "node": "^20.19.0 || >=22.12.0"
}
},
- "node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.5.5",
- "license": "MIT"
- },
- "node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.31",
+ "node_modules/@rolldown/binding-linux-arm-gnueabihf": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.3.tgz",
+ "integrity": "sha512-Yi30IVAAfLUCy2MseFjbB1jAMDl1VMCAas5StnYp8da9+CKvMd2H2cbEjWcw5NPaPqzvYkVIaF1nNUG+b7u/sw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@jridgewell/resolve-uri": "^3.1.0",
- "@jridgewell/sourcemap-codec": "^1.4.14"
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
}
},
- "node_modules/@nodable/entities": {
- "version": "2.1.0",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/nodable"
- }
+ "node_modules/@rolldown/binding-linux-arm64-gnu": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.3.tgz",
+ "integrity": "sha512-jsO7R8To+AdlYgUmN5sHSCZbfhtMBkO0WUx8iORQnPcMMdgr7qM2DQmMwgabs3GhNztdmoKkMKQFHD6DTMCIQw==",
+ "cpu": [
+ "arm64"
],
- "license": "MIT"
- },
- "node_modules/@nodelib/fs.scandir": {
- "version": "2.1.5",
"dev": true,
+ "libc": [
+ "glibc"
+ ],
"license": "MIT",
- "dependencies": {
- "@nodelib/fs.stat": "2.0.5",
- "run-parallel": "^1.1.9"
- },
+ "optional": true,
+ "os": [
+ "linux"
+ ],
"engines": {
- "node": ">= 8"
+ "node": "^20.19.0 || >=22.12.0"
}
},
- "node_modules/@nodelib/fs.stat": {
- "version": "2.0.5",
+ "node_modules/@rolldown/binding-linux-arm64-musl": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.3.tgz",
+ "integrity": "sha512-VWkUHwWriDciit80wleYwKILoR/KMvxh/IdwS/paX+ZgpuRpCrKLUdadJbc0NpBEiyhpYawsJ73j9aCvOH+f7Q==",
+ "cpu": [
+ "arm64"
+ ],
"dev": true,
+ "libc": [
+ "musl"
+ ],
"license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
"engines": {
- "node": ">= 8"
+ "node": "^20.19.0 || >=22.12.0"
}
},
- "node_modules/@nodelib/fs.walk": {
- "version": "1.2.8",
+ "node_modules/@rolldown/binding-linux-ppc64-gnu": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.3.tgz",
+ "integrity": "sha512-5f1laC0SlIR0yDbFCd8acUhvJIag6N3zC5P7oUPN6wX0aOma+uKJ0wBDH5aq7I1PVI2ttTlhJwzwRIBnLiSGEg==",
+ "cpu": [
+ "ppc64"
+ ],
"dev": true,
+ "libc": [
+ "glibc"
+ ],
"license": "MIT",
- "dependencies": {
- "@nodelib/fs.scandir": "2.1.5",
- "fastq": "^1.6.0"
- },
+ "optional": true,
+ "os": [
+ "linux"
+ ],
"engines": {
- "node": ">= 8"
+ "node": "^20.19.0 || >=22.12.0"
}
},
- "node_modules/@one-ini/wasm": {
- "version": "0.1.1",
- "license": "MIT"
- },
- "node_modules/@oxc-project/types": {
- "version": "0.132.0",
+ "node_modules/@rolldown/binding-linux-s390x-gnu": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.3.tgz",
+ "integrity": "sha512-Iq4ko0r4XsgbrF/LunNgHtAGLRRVE2kXonAXQ/MV0mC6jQpMOhW1SvtZja2EhC/kd05++bP78dsqBeIQyYJ6Yg==",
+ "cpu": [
+ "s390x"
+ ],
"dev": true,
+ "libc": [
+ "glibc"
+ ],
"license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/Boshen"
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
}
},
- "node_modules/@pkgjs/parseargs": {
- "version": "0.11.0",
+ "node_modules/@rolldown/binding-linux-x64-gnu": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.3.tgz",
+ "integrity": "sha512-B8m6tD5+/N5FeNQFbKlLA/2yVq9ycQP1SeedyEYYKWBNR3ZQbkvIUcNnDNM03lO1l5F2roiiFJGgvoLLyZXtSg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
"license": "MIT",
"optional": true,
+ "os": [
+ "linux"
+ ],
"engines": {
- "node": ">=14"
+ "node": "^20.19.0 || >=22.12.0"
}
},
- "node_modules/@plausible-analytics/tracker": {
- "version": "0.4.5",
- "license": "MIT"
- },
- "node_modules/@polka/url": {
- "version": "1.0.0-next.29",
+ "node_modules/@rolldown/binding-linux-x64-musl": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.3.tgz",
+ "integrity": "sha512-pSdpdUJHkuCxun9LE7jvgUB9qsRgaiyNNCX7m/AvHTcq67AiT/Yhoxvw5zPfhrM8k/BfP8ce/hMOpthKDpEUow==",
+ "cpu": [
+ "x64"
+ ],
"dev": true,
- "license": "MIT"
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
},
- "node_modules/@poppinss/colors": {
- "version": "4.1.6",
+ "node_modules/@rolldown/binding-openharmony-arm64": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.3.tgz",
+ "integrity": "sha512-OXXS3RKJgX2uLwM+gYyuH5omcH8fL1LJs96pZGgtetVCahON57+d4SJHzTgZiOjxgGkSnpXpOsWuPDGAKAigEg==",
+ "cpu": [
+ "arm64"
+ ],
"dev": true,
"license": "MIT",
- "dependencies": {
- "kleur": "^4.1.5"
+ "optional": true,
+ "os": [
+ "openharmony"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
}
},
- "node_modules/@poppinss/dumper": {
- "version": "0.6.5",
+ "node_modules/@rolldown/binding-wasm32-wasi": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.3.tgz",
+ "integrity": "sha512-JTtb8BWFynicNSoPrehsCzBtOKjZ6jhMiPFEmOiuXg1Fl8dn2KHQob+GuPSGR0dryQa1PQJbzjF3dqO/whhjLg==",
+ "cpu": [
+ "wasm32"
+ ],
"dev": true,
"license": "MIT",
+ "optional": true,
"dependencies": {
- "@poppinss/colors": "^4.1.5",
- "@sindresorhus/is": "^7.0.2",
- "supports-color": "^10.0.0"
+ "@emnapi/core": "1.10.0",
+ "@emnapi/runtime": "1.10.0",
+ "@napi-rs/wasm-runtime": "^1.1.4"
+ },
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
}
},
- "node_modules/@poppinss/dumper/node_modules/supports-color": {
- "version": "10.2.2",
+ "node_modules/@rolldown/binding-win32-arm64-msvc": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.3.tgz",
+ "integrity": "sha512-gEdFFEN70A/jxb2svrWsN3aDL7OUtmvlOy+6fa2jxG8K0wQ1ZbdeLGnidov6Yu5/733dI5ySfzFlQ/cb0bSz1g==",
+ "cpu": [
+ "arm64"
+ ],
"dev": true,
"license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
"engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/chalk/supports-color?sponsor=1"
+ "node": "^20.19.0 || >=22.12.0"
}
},
- "node_modules/@poppinss/exception": {
- "version": "1.2.3",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@rolldown/binding-darwin-arm64": {
- "version": "1.0.2",
+ "node_modules/@rolldown/binding-win32-x64-msvc": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.3.tgz",
+ "integrity": "sha512-eXB7CHuaQdqmJcc3koCNtNPmT/bj2gc999kUFgBxG8Ac0NdgXc4rkCHhqrgrhN3zddvvvrgzj1e90SuSfmyIXA==",
"cpu": [
- "arm64"
+ "x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
- "darwin"
+ "win32"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
@@ -3008,16 +4312,22 @@
},
"node_modules/@rolldown/pluginutils": {
"version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz",
+ "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==",
"dev": true,
"license": "MIT"
},
"node_modules/@sec-ant/readable-stream": {
"version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz",
+ "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==",
"dev": true,
"license": "MIT"
},
"node_modules/@silverbucket/ajv-formats-draft2019": {
"version": "1.6.5",
+ "resolved": "https://registry.npmjs.org/@silverbucket/ajv-formats-draft2019/-/ajv-formats-draft2019-1.6.5.tgz",
+ "integrity": "sha512-TUN/aSGMt3mZF45oy+kfCKtnKjBbSRVYFJxZKnGCPbKynPI2tsGyLgD9GEwFS0NLPbX0hUYHYeyFVoJ33HlMCw==",
"license": "MIT",
"dependencies": {
"@silverbucket/iana-schemes": "^1.4.4",
@@ -3030,10 +4340,14 @@
},
"node_modules/@silverbucket/iana-schemes": {
"version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/@silverbucket/iana-schemes/-/iana-schemes-1.4.4.tgz",
+ "integrity": "sha512-2iUk6DlqdpQQKs3qrCZDf4LQLH1GPtUXmYZFeq0NWw1WkGY2iJBP4aeYZ5v+3ITxtQA3M0t/Sua8AKu+o4O0KA==",
"license": "MIT"
},
"node_modules/@simple-libs/child-process-utils": {
"version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@simple-libs/child-process-utils/-/child-process-utils-1.0.2.tgz",
+ "integrity": "sha512-/4R8QKnd/8agJynkNdJmNw2MBxuFTRcNFnE5Sg/G+jkSsV8/UBgULMzhizWWW42p8L5H7flImV2ATi79Ove2Tw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3048,6 +4362,8 @@
},
"node_modules/@simple-libs/stream-utils": {
"version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@simple-libs/stream-utils/-/stream-utils-1.2.0.tgz",
+ "integrity": "sha512-KxXvfapcixpz6rVEB6HPjOUZT22yN6v0vI0urQSk1L8MlEWPDFCZkhw2xmkyoTGYeFw7tWTZd7e3lVzRZRN/EA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -3059,10 +4375,14 @@
},
"node_modules/@simplewebauthn/browser": {
"version": "13.3.0",
+ "resolved": "https://registry.npmjs.org/@simplewebauthn/browser/-/browser-13.3.0.tgz",
+ "integrity": "sha512-BE/UWv6FOToAdVk0EokzkqQQDOWtNydYlY6+OrmiZ5SCNmb41VehttboTetUM3T/fr6EAFYVXjz4My2wg230rQ==",
"license": "MIT"
},
"node_modules/@sindresorhus/is": {
"version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-7.2.0.tgz",
+ "integrity": "sha512-P1Cz1dWaFfR4IR+U13mqqiGsLFf1KbayybWwdd2vfctdV6hDpUkgCY0nKOLLTMSoRd/jJNjtbqzf13K8DCCXQw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -3074,6 +4394,8 @@
},
"node_modules/@sindresorhus/merge-streams": {
"version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz",
+ "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -3085,6 +4407,8 @@
},
"node_modules/@sinonjs/commons": {
"version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz",
+ "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
@@ -3093,6 +4417,8 @@
},
"node_modules/@sinonjs/fake-timers": {
"version": "11.2.2",
+ "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz",
+ "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
@@ -3101,6 +4427,8 @@
},
"node_modules/@sinonjs/samsam": {
"version": "8.0.3",
+ "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.3.tgz",
+ "integrity": "sha512-hw6HbX+GyVZzmaYNh82Ecj1vdGZrqVIn/keDTg63IgAwiQPO+xCz99uG6Woqgb4tM0mUiFENKZ4cqd7IX94AXQ==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
@@ -3110,6 +4438,8 @@
},
"node_modules/@sinonjs/samsam/node_modules/type-detect": {
"version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz",
+ "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -3117,7 +4447,9 @@
}
},
"node_modules/@smithy/core": {
- "version": "3.24.4",
+ "version": "3.24.5",
+ "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.24.5.tgz",
+ "integrity": "sha512-Kt8phUg45M15EjhYAbZ+fFikYneijLu9Liugz8ZsYz2i8j0hzGv27LWKpEHYRfvj+LyCOSijpcR/2i8RouV+cA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -3130,11 +4462,13 @@
}
},
"node_modules/@smithy/credential-provider-imds": {
- "version": "4.3.4",
+ "version": "4.3.6",
+ "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.3.6.tgz",
+ "integrity": "sha512-tHhdiWZfG1ZIh2YcRfPJmY2gHcBmqbAzqm3ER4TIDFYsSEqTD5tICT7cgQ/kI8LRakxp12myOYyK68XPn7MnHw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@smithy/core": "^3.24.4",
+ "@smithy/core": "^3.24.5",
"@smithy/types": "^4.14.2",
"tslib": "^2.6.2"
},
@@ -3143,11 +4477,13 @@
}
},
"node_modules/@smithy/fetch-http-handler": {
- "version": "5.4.4",
+ "version": "5.4.5",
+ "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.4.5.tgz",
+ "integrity": "sha512-SK3VMeH0fibgdTg2QeB+O4p7Yy/2E5HBOHJeC58FshkDdeuX8lOgO7PfjYfLyPLP1ch55j91cQqKBzDS0mRjSQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@smithy/core": "^3.24.4",
+ "@smithy/core": "^3.24.5",
"@smithy/types": "^4.14.2",
"tslib": "^2.6.2"
},
@@ -3157,6 +4493,8 @@
},
"node_modules/@smithy/is-array-buffer": {
"version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz",
+ "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -3167,11 +4505,13 @@
}
},
"node_modules/@smithy/node-http-handler": {
- "version": "4.7.4",
+ "version": "4.7.5",
+ "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.7.5.tgz",
+ "integrity": "sha512-3dA9TQ+ybRSZ/m0wnbZhiBy4Dezjgq1Ib/ZZrYTpJDBgpoLLU/SDzZc/g0x0MNAdOJe1wPcM+x2PBRmoOur+Sw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@smithy/core": "^3.24.4",
+ "@smithy/core": "^3.24.5",
"@smithy/types": "^4.14.2",
"tslib": "^2.6.2"
},
@@ -3180,11 +4520,13 @@
}
},
"node_modules/@smithy/signature-v4": {
- "version": "5.4.4",
+ "version": "5.4.5",
+ "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.4.5.tgz",
+ "integrity": "sha512-QBJKWGqIknH0dc9LWpfH1mkdokAx6iXYN3UcQ3eY6uIEyScuoQAhfl94ge7ozUy9WgFUdE8xsvwBjaYBbWmPNA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@smithy/core": "^3.24.4",
+ "@smithy/core": "^3.24.5",
"@smithy/types": "^4.14.2",
"tslib": "^2.6.2"
},
@@ -3194,6 +4536,8 @@
},
"node_modules/@smithy/types": {
"version": "4.14.2",
+ "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.14.2.tgz",
+ "integrity": "sha512-P+otAxbV4CqBybp7EkcJCrig63yE2E7PuNVOmilVMRcx/O+QDzGULTrKsq4DV13gSfak9ObPrWaHl/9bL5YcWw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -3205,6 +4549,8 @@
},
"node_modules/@smithy/util-buffer-from": {
"version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz",
+ "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -3217,6 +4563,8 @@
},
"node_modules/@smithy/util-hex-encoding": {
"version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-2.2.0.tgz",
+ "integrity": "sha512-7iKXR+/4TpLK194pVjKiasIyqMtTYJsgKgM242Y9uzt5dhHnUDvMNb+3xIhRJ9QhvqGii/5cRUt4fJn3dtXNHQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -3228,6 +4576,8 @@
},
"node_modules/@smithy/util-middleware": {
"version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-2.2.0.tgz",
+ "integrity": "sha512-L1qpleXf9QD6LwLCJ5jddGkgWyuSvWBkJwWAZ6kFkdifdso+sk3L3O1HdmPvCdnCK3IS4qWyPxev01QMnfHSBw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -3240,6 +4590,8 @@
},
"node_modules/@smithy/util-middleware/node_modules/@smithy/types": {
"version": "2.12.0",
+ "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.12.0.tgz",
+ "integrity": "sha512-QwYgloJ0sVNBeBuBs65cIkTbfzV/Q6ZNPCJ99EICFEdJYG50nGIY/uYXp+TbsdJReIuPr0a0kXmCvren3MbRRw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -3251,6 +4603,8 @@
},
"node_modules/@smithy/util-uri-escape": {
"version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-2.2.0.tgz",
+ "integrity": "sha512-jtmJMyt1xMD/d8OtbVJ2gFZOSKc+ueYJZPW20ULW1GOp/q/YIM0wNh+u8ZFao9UaIGz4WoPW8hC64qlWLIfoDA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -3262,6 +4616,8 @@
},
"node_modules/@smithy/util-utf8": {
"version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz",
+ "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -3274,16 +4630,22 @@
},
"node_modules/@speed-highlight/core": {
"version": "1.2.15",
+ "resolved": "https://registry.npmjs.org/@speed-highlight/core/-/core-1.2.15.tgz",
+ "integrity": "sha512-BMq1K3DsElxDWawkX6eLg9+CKJrTVGCBAWVuHXVUV2u0s2711qiChLSId6ikYPfxhdYocLNt3wWwSvDiTvFabw==",
"dev": true,
"license": "CC0-1.0"
},
"node_modules/@standard-schema/spec": {
"version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz",
+ "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==",
"dev": true,
"license": "MIT"
},
"node_modules/@stryker-mutator/api": {
"version": "9.6.1",
+ "resolved": "https://registry.npmjs.org/@stryker-mutator/api/-/api-9.6.1.tgz",
+ "integrity": "sha512-g8VNoFWQWbx0pdal3Vt8jVCZW+v3sc3gi94iI0GVtVgUGTqphAjJF6EAruPTx0lqvtonsaAxn5TD36hcG1d6Wg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -3298,6 +4660,8 @@
},
"node_modules/@stryker-mutator/core": {
"version": "9.6.1",
+ "resolved": "https://registry.npmjs.org/@stryker-mutator/core/-/core-9.6.1.tgz",
+ "integrity": "sha512-WMgnvf+Wyh/yiruhNZwc8w8DlzmmjXhPjSn5MR8RhAXzlnWji8TQrUYgBUkHk9bEgSaIlB3KZHm37iiU5Q2cLQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -3337,6 +4701,8 @@
},
"node_modules/@stryker-mutator/core/node_modules/ajv": {
"version": "8.18.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz",
+ "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3350,19 +4716,10 @@
"url": "https://github.com/sponsors/epoberezkin"
}
},
- "node_modules/@stryker-mutator/core/node_modules/chalk": {
- "version": "5.6.2",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "^12.17.0 || ^14.13 || >=16.0.0"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
"node_modules/@stryker-mutator/instrumenter": {
"version": "9.6.1",
+ "resolved": "https://registry.npmjs.org/@stryker-mutator/instrumenter/-/instrumenter-9.6.1.tgz",
+ "integrity": "sha512-5K8wH4Pthly25c2uKKik4Dfcoeou7sbJdFS6u3QIYHlulgFVDJwtEMWTZGkZfs7IiUEXIDNa0keRACq5jn5AvA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -3385,6 +4742,8 @@
},
"node_modules/@stryker-mutator/instrumenter/node_modules/semver": {
"version": "7.7.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
+ "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
"dev": true,
"license": "ISC",
"bin": {
@@ -3396,11 +4755,15 @@
},
"node_modules/@stryker-mutator/util": {
"version": "9.6.1",
+ "resolved": "https://registry.npmjs.org/@stryker-mutator/util/-/util-9.6.1.tgz",
+ "integrity": "sha512-Lk/ALVctJjFv1vvwR+CFoKzDCWvsBlq7flDUnmnpuwTrGbm156EdZD1Jjq4o8KdOap0ezUZqQNE9OAI1m2+pUQ==",
"dev": true,
"license": "Apache-2.0"
},
"node_modules/@sveltejs/acorn-typescript": {
"version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/@sveltejs/acorn-typescript/-/acorn-typescript-1.0.10.tgz",
+ "integrity": "sha512-4WfKk68eTih+MiJD4fSbxN7E8kVBmTMPWHUPYjvl2N0rMs53YLTT8/YjKU5Dtnz5LqDjl7LEw4U7lXR2W3J5WA==",
"license": "MIT",
"peerDependencies": {
"acorn": "^8.9.0"
@@ -3408,6 +4771,8 @@
},
"node_modules/@sveltejs/adapter-cloudflare": {
"version": "7.2.8",
+ "resolved": "https://registry.npmjs.org/@sveltejs/adapter-cloudflare/-/adapter-cloudflare-7.2.8.tgz",
+ "integrity": "sha512-bIdhY/Fi4AQmqiBdQVKnafH1h9Gw+xbCvHyUu4EouC8rJOU02zwhi14k/FDhQ0mJF1iblIu3m8UNQ8GpGIvIOQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3420,14 +4785,16 @@
}
},
"node_modules/@sveltejs/kit": {
- "version": "2.60.1",
+ "version": "2.61.1",
+ "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.61.1.tgz",
+ "integrity": "sha512-Ny8s1SR1TyQS2hD2Rvw0XKzU2Nw1eUF52dTb6T2bdcgz7wSC+Nyb5IwjWYlR4b2dvbbR5NJDiQwHg3rnNseghg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@standard-schema/spec": "^1.0.0",
- "@sveltejs/acorn-typescript": "^1.0.5",
+ "@sveltejs/acorn-typescript": "^1.0.9",
"@types/cookie": "^0.6.0",
- "acorn": "^8.14.1",
+ "acorn": "^8.16.0",
"cookie": "^0.6.0",
"devalue": "^5.8.1",
"esm-env": "^1.2.2",
@@ -3461,6 +4828,8 @@
},
"node_modules/@sveltejs/vite-plugin-svelte": {
"version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-7.1.2.tgz",
+ "integrity": "sha512-DrUBA2UXRfDmUX/ZTiEopd3X40yavsJF1FX2RygcuIScHL7o5YX1fMvoYnDhjeJQC4weCOklirpNWlcb2NiSeA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3478,14 +4847,29 @@
}
},
"node_modules/@swc/helpers": {
- "version": "0.5.21",
+ "version": "0.5.23",
+ "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.23.tgz",
+ "integrity": "sha512-5lSsMOTXURePglDfvuAQUqkGek9Hg2kksOYay2m0+XR++b2NWYL/4sWyuvVBIs8oKnJaxkdi9whaL/sqN13afw==",
"license": "Apache-2.0",
"dependencies": {
"tslib": "^2.8.0"
}
},
+ "node_modules/@tybys/wasm-util": {
+ "version": "0.10.2",
+ "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz",
+ "integrity": "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
"node_modules/@types/buffers": {
"version": "0.1.31",
+ "resolved": "https://registry.npmjs.org/@types/buffers/-/buffers-0.1.31.tgz",
+ "integrity": "sha512-wEZBb3o0Kh5RAj3V172vJCcxaCV8C2HJ7YLBBlG5Mwue0g4uRg5LWv8C6ap8MyFbXE6UbYEuvtHY7oTWAPeXEw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3494,23 +4878,33 @@
},
"node_modules/@types/command-line-args": {
"version": "5.2.3",
+ "resolved": "https://registry.npmjs.org/@types/command-line-args/-/command-line-args-5.2.3.tgz",
+ "integrity": "sha512-uv0aG6R0Y8WHZLTamZwtfsDLVRnOa+n+n5rEvFWL5Na5gZ8V2Teab/duDPFzIIIhs9qizDpcavCusCLJZu62Kw==",
"license": "MIT"
},
"node_modules/@types/command-line-usage": {
"version": "5.0.4",
+ "resolved": "https://registry.npmjs.org/@types/command-line-usage/-/command-line-usage-5.0.4.tgz",
+ "integrity": "sha512-BwR5KP3Es/CSht0xqBcUXS3qCAUVXwpRKsV2+arxeb65atasuXG9LykC9Ab10Cw3s2raH92ZqOeILaQbsB2ACg==",
"license": "MIT"
},
"node_modules/@types/cookie": {
"version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz",
+ "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/estree": {
"version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz",
+ "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==",
"license": "MIT"
},
"node_modules/@types/glob": {
"version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz",
+ "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3520,6 +4914,8 @@
},
"node_modules/@types/hast": {
"version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz",
+ "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==",
"license": "MIT",
"dependencies": {
"@types/unist": "*"
@@ -3527,11 +4923,15 @@
},
"node_modules/@types/json-schema": {
"version": "7.0.15",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
+ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
"license": "MIT",
"peer": true
},
"node_modules/@types/mdast": {
"version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz",
+ "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==",
"license": "MIT",
"dependencies": {
"@types/unist": "*"
@@ -3539,11 +4939,15 @@
},
"node_modules/@types/minimatch": {
"version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz",
+ "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/node": {
"version": "25.9.1",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-25.9.1.tgz",
+ "integrity": "sha512-xfrlY7UD5rMJk3ZVJP8BNzS28J36YJg+xp+LPXV1TdWxr8uMH5A860QNxYDGQe/ylDSgjxE52Q9VnO7p75tJxg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3552,6 +4956,8 @@
},
"node_modules/@types/sinon": {
"version": "17.0.4",
+ "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-17.0.4.tgz",
+ "integrity": "sha512-RHnIrhfPO3+tJT0s7cFaXGZvsL4bbR3/k7z3P312qMS4JaS2Tk+KiwiLx1S0rQ56ERj00u1/BtdyVd0FY+Pdew==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3560,23 +4966,33 @@
},
"node_modules/@types/sinonjs__fake-timers": {
"version": "15.0.1",
+ "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-15.0.1.tgz",
+ "integrity": "sha512-Ko2tjWJq8oozHzHV+reuvS5KYIRAokHnGbDwGh/J64LntgpbuylF74ipEL24HCyRjf9FOlBiBHWBR1RlVKsI1w==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/trusted-types": {
"version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
+ "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
"license": "MIT"
},
"node_modules/@types/unist": {
"version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz",
+ "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==",
"license": "MIT"
},
"node_modules/@ungap/custom-elements": {
"version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/@ungap/custom-elements/-/custom-elements-1.3.0.tgz",
+ "integrity": "sha512-f4q/s76+8nOy+fhrNHyetuoPDR01lmlZB5czfCG+OOnBw/Wf+x48DcCDPmMQY7oL8xYFL8qfenMoiS8DUkKBUw==",
"license": "ISC"
},
"node_modules/@willfarrell-ds/cli": {
"version": "0.0.0-alpha.6",
+ "resolved": "https://registry.npmjs.org/@willfarrell-ds/cli/-/cli-0.0.0-alpha.6.tgz",
+ "integrity": "sha512-CIEnRyopUAil0yPrAYqg8jEnSwc1dzIe5LQbi0/ghuWukSHrwcrWGoqBwTfuBOddg3087kIHj3YXHyJncOG1qw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3590,6 +5006,8 @@
},
"node_modules/@willfarrell-ds/svelte": {
"version": "0.0.0-alpha.6",
+ "resolved": "https://registry.npmjs.org/@willfarrell-ds/svelte/-/svelte-0.0.0-alpha.6.tgz",
+ "integrity": "sha512-6xnvXlOWj6h/kWIx6RG0J28XmmwMTIVp6zxqeZlmifymS8l28G8qsg2tCHyaN+09gw7hTvLoQ2P4wCF2FMr9HA==",
"license": "MIT",
"dependencies": {
"@willfarrell-ds/vanilla": "0.0.0-alpha.6",
@@ -3603,6 +5021,8 @@
},
"node_modules/@willfarrell-ds/vanilla": {
"version": "0.0.0-alpha.6",
+ "resolved": "https://registry.npmjs.org/@willfarrell-ds/vanilla/-/vanilla-0.0.0-alpha.6.tgz",
+ "integrity": "sha512-a7fWbPJZkDcMQ/OK1pLMSAk6DIBBVN52VaJrXu/lUur4VUrX3Sa0W3UVPAQgWaJ5gkFYfxBjTw3rVkm2PwWLGQ==",
"license": "MIT",
"dependencies": {
"@simplewebauthn/browser": "13.3.0",
@@ -3612,6 +5032,8 @@
},
"node_modules/@yarnpkg/parsers": {
"version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@yarnpkg/parsers/-/parsers-3.0.3.tgz",
+ "integrity": "sha512-mQZgUSgFurUtA07ceMjxrWkYz8QtDuYkvPlu0ZqncgjopQ0t6CNEo/OSealkmnagSUx8ZD5ewvezUwUuMqutQg==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
@@ -3624,6 +5046,8 @@
},
"node_modules/@yarnpkg/parsers/node_modules/argparse": {
"version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3632,6 +5056,8 @@
},
"node_modules/@yarnpkg/parsers/node_modules/js-yaml": {
"version": "3.14.2",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz",
+ "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3644,6 +5070,8 @@
},
"node_modules/abbrev": {
"version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz",
+ "integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==",
"license": "ISC",
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
@@ -3651,6 +5079,8 @@
},
"node_modules/accessible-autocomplete": {
"version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/accessible-autocomplete/-/accessible-autocomplete-3.0.1.tgz",
+ "integrity": "sha512-xMshgc2LT5addvvfCTGzIkRrvhbOFeylFSnSMfS/PdjvvvElZkakCwxO3/yJYBWyi1hi3tZloqOJQ5kqqJtH4g==",
"license": "MIT",
"peerDependencies": {
"preact": "^8.0.0"
@@ -3663,6 +5093,8 @@
},
"node_modules/acorn": {
"version": "8.16.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz",
+ "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==",
"license": "MIT",
"bin": {
"acorn": "bin/acorn"
@@ -3673,6 +5105,8 @@
},
"node_modules/ajv": {
"version": "8.20.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz",
+ "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==",
"license": "MIT",
"dependencies": {
"fast-deep-equal": "^3.1.3",
@@ -3687,6 +5121,8 @@
},
"node_modules/ajv-cmd": {
"version": "0.13.3",
+ "resolved": "https://registry.npmjs.org/ajv-cmd/-/ajv-cmd-0.13.3.tgz",
+ "integrity": "sha512-H1LArE4kclZ5JdWLKUZd1ji3UjO6FSpCW1MZ6J0X89BqwT+5W70KD4TpfvhcM7isSoQvo6sslA/rZiCH1HzM6g==",
"license": "MIT",
"workspaces": [
".github"
@@ -3717,6 +5153,8 @@
},
"node_modules/ajv-errors": {
"version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-3.0.0.tgz",
+ "integrity": "sha512-V3wD15YHfHz6y0KdhYFjyy9vWtEVALT9UrxfN3zqlI6dMioHnJrqOYfyPKol3oqrnCM9uwkcdCwkJ0WUcbLMTQ==",
"license": "MIT",
"peerDependencies": {
"ajv": "^8.0.1"
@@ -3724,6 +5162,8 @@
},
"node_modules/ajv-formats": {
"version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz",
+ "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==",
"license": "MIT",
"dependencies": {
"ajv": "^8.0.0"
@@ -3739,6 +5179,8 @@
},
"node_modules/ajv-ftl-i18n": {
"version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/ajv-ftl-i18n/-/ajv-ftl-i18n-0.2.1.tgz",
+ "integrity": "sha512-ThWHxPmLaJYKrl1mMWAYizGqZG1MrHcMgQ4MId2YFAjRn73GrZqSMX+sifQAHXAva0RZVeGHxVqkrWGizDFo6Q==",
"license": "MIT",
"workspaces": [
".github"
@@ -3760,6 +5202,8 @@
},
"node_modules/ajv-i18n": {
"version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/ajv-i18n/-/ajv-i18n-4.2.0.tgz",
+ "integrity": "sha512-v/ei2UkCEeuKNXh8RToiFsUclmU+G57LO1Oo22OagNMENIw+Yb8eMwvHu7Vn9fmkjJyv6XclhJ8TbuigSglPkg==",
"license": "MIT",
"peerDependencies": {
"ajv": "^8.0.0-beta.0"
@@ -3767,6 +5211,8 @@
},
"node_modules/ajv-keywords": {
"version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
+ "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
"license": "MIT",
"dependencies": {
"fast-deep-equal": "^3.1.3"
@@ -3777,6 +5223,8 @@
},
"node_modules/angular-html-parser": {
"version": "10.4.0",
+ "resolved": "https://registry.npmjs.org/angular-html-parser/-/angular-html-parser-10.4.0.tgz",
+ "integrity": "sha512-++nLNyZwRfHqFh7akH5Gw/JYizoFlMRz0KRigfwfsLqV8ZqlcVRb1LkPEWdYvEKDnbktknM2J4BXaYUGrQZPww==",
"dev": true,
"license": "MIT",
"engines": {
@@ -3785,6 +5233,8 @@
},
"node_modules/ansi-regex": {
"version": "6.2.2",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz",
+ "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
"license": "MIT",
"engines": {
"node": ">=12"
@@ -3795,6 +5245,8 @@
},
"node_modules/ansi-styles": {
"version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz",
+ "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==",
"license": "MIT",
"engines": {
"node": ">=12"
@@ -3805,6 +5257,8 @@
},
"node_modules/apache-arrow": {
"version": "21.1.0",
+ "resolved": "https://registry.npmjs.org/apache-arrow/-/apache-arrow-21.1.0.tgz",
+ "integrity": "sha512-kQrYLxhC+NTVVZ4CCzGF6L/uPVOzJmD1T3XgbiUnP7oTeVFOFgEUu6IKNwCDkpFoBVqDKQivlX4RUFqqnWFlEA==",
"license": "Apache-2.0",
"dependencies": {
"@swc/helpers": "^0.5.11",
@@ -3823,6 +5277,8 @@
},
"node_modules/apache-arrow/node_modules/@types/node": {
"version": "24.12.4",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-24.12.4.tgz",
+ "integrity": "sha512-GUUEShf+PBCGW2KaXwcIt3Yk+e3pkKwWKb9GSyM9WQVE+ep2jzmHdGsHzu4wgcZy5fN9FBdVzjpBQsYlpfpgLA==",
"license": "MIT",
"dependencies": {
"undici-types": "~7.16.0"
@@ -3830,14 +5286,20 @@
},
"node_modules/apache-arrow/node_modules/undici-types": {
"version": "7.16.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz",
+ "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==",
"license": "MIT"
},
"node_modules/argparse": {
"version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
"license": "Python-2.0"
},
"node_modules/aria-query": {
"version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.1.tgz",
+ "integrity": "sha512-Z/ZeOgVl7bcSYZ/u/rh0fOpvEpq//LZmdbkXyc7syVzjPAhfOa9ebsdTSjEBDU4vs5nC98Kfduj1uFo0qyET3g==",
"license": "Apache-2.0",
"engines": {
"node": ">= 0.4"
@@ -3845,6 +5307,8 @@
},
"node_modules/array-back": {
"version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.3.tgz",
+ "integrity": "sha512-SGDvmg6QTYiTxCBkYVmThcoa67uLl35pyzRHdpCGBOcqFy6BtwnphoFPk7LhJshD+Yk1Kt35WGWeZPTgwR4Fhw==",
"license": "MIT",
"engines": {
"node": ">=12.17"
@@ -3852,11 +5316,15 @@
},
"node_modules/array-ify": {
"version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz",
+ "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==",
"dev": true,
"license": "MIT"
},
"node_modules/array-union": {
"version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
+ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -3865,6 +5333,8 @@
},
"node_modules/aws-msk-iam-sasl-signer-js": {
"version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/aws-msk-iam-sasl-signer-js/-/aws-msk-iam-sasl-signer-js-1.0.3.tgz",
+ "integrity": "sha512-bFsI5p7HAUtVxXLNWLgbcLGFKiUuoTphCNq/UoSW5669LXomh2qI7gAvY0JP8l0UaLXjNKr+D+MeQY0Gqm8RKg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -3881,6 +5351,8 @@
},
"node_modules/aws-msk-iam-sasl-signer-js/node_modules/@aws-crypto/sha256-js": {
"version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-4.0.0.tgz",
+ "integrity": "sha512-MHGJyjE7TX9aaqXj7zk2ppnFUOhaDs5sP+HtNS0evOxn72c+5njUmyJmpGd7TfyoDznZlHMmdo/xGUdu2NIjNQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -3891,11 +5363,15 @@
},
"node_modules/aws-msk-iam-sasl-signer-js/node_modules/@aws-crypto/sha256-js/node_modules/tslib": {
"version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
"dev": true,
"license": "0BSD"
},
"node_modules/aws-msk-iam-sasl-signer-js/node_modules/@aws-crypto/util": {
"version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-4.0.0.tgz",
+ "integrity": "sha512-2EnmPy2gsFZ6m8bwUQN4jq+IyXV3quHAcwPOS6ZA3k+geujiqI8aRokO2kFJe+idJ/P3v4qWI186rVMo0+zLDQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -3906,11 +5382,15 @@
},
"node_modules/aws-msk-iam-sasl-signer-js/node_modules/@aws-crypto/util/node_modules/tslib": {
"version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
"dev": true,
"license": "0BSD"
},
"node_modules/aws-msk-iam-sasl-signer-js/node_modules/@smithy/signature-v4": {
"version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-2.3.0.tgz",
+ "integrity": "sha512-ui/NlpILU+6HAQBfJX8BBsDXuKSNrjTSuOYArRblcrErwKFutjrCNb/OExfVRyj9+26F9J+ZmfWT+fKWuDrH3Q==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -3928,6 +5408,8 @@
},
"node_modules/aws-msk-iam-sasl-signer-js/node_modules/@smithy/types": {
"version": "2.12.0",
+ "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.12.0.tgz",
+ "integrity": "sha512-QwYgloJ0sVNBeBuBs65cIkTbfzV/Q6ZNPCJ99EICFEdJYG50nGIY/uYXp+TbsdJReIuPr0a0kXmCvren3MbRRw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -3939,6 +5421,8 @@
},
"node_modules/aws-sdk-client-mock": {
"version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/aws-sdk-client-mock/-/aws-sdk-client-mock-4.1.0.tgz",
+ "integrity": "sha512-h/tOYTkXEsAcV3//6C1/7U4ifSpKyJvb6auveAepqqNJl6TdZaPFEtKjBQNf8UxQdDP850knB2i/whq4zlsxJw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3949,6 +5433,8 @@
},
"node_modules/axobject-query": {
"version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz",
+ "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==",
"license": "Apache-2.0",
"engines": {
"node": ">= 0.4"
@@ -3956,6 +5442,8 @@
},
"node_modules/balanced-match": {
"version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz",
+ "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -3964,6 +5452,8 @@
},
"node_modules/base64-js": {
"version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
"dev": true,
"funding": [
{
@@ -3982,7 +5472,9 @@
"license": "MIT"
},
"node_modules/baseline-browser-mapping": {
- "version": "2.10.32",
+ "version": "2.10.33",
+ "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.33.tgz",
+ "integrity": "sha512-bA6+tcSLpz2tIEdDXZPpPTIuxBcC4+w6SieaYyfigIa4h8GlFxbA17v22Vx3JUtuZQj9SgOsnbK+aTBzyDyEuw==",
"dev": true,
"license": "Apache-2.0",
"bin": {
@@ -3994,21 +5486,29 @@
},
"node_modules/blake3-wasm": {
"version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/blake3-wasm/-/blake3-wasm-2.1.5.tgz",
+ "integrity": "sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==",
"dev": true,
"license": "MIT"
},
"node_modules/boolbase": {
"version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+ "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
"dev": true,
"license": "ISC"
},
"node_modules/bowser": {
"version": "2.14.1",
+ "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.14.1.tgz",
+ "integrity": "sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==",
"dev": true,
"license": "MIT"
},
"node_modules/brace-expansion": {
"version": "5.0.6",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz",
+ "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4020,6 +5520,8 @@
},
"node_modules/braces": {
"version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4031,6 +5533,8 @@
},
"node_modules/brotli-wasm": {
"version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/brotli-wasm/-/brotli-wasm-3.0.1.tgz",
+ "integrity": "sha512-U3K72/JAi3jITpdhZBqzSUq+DUY697tLxOuFXB+FpAE/Ug+5C3VZrv4uA674EUZHxNAuQ9wETXNqQkxZD6oL4A==",
"dev": true,
"license": "Apache-2.0",
"engines": {
@@ -4039,6 +5543,8 @@
},
"node_modules/browserslist": {
"version": "4.28.2",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz",
+ "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==",
"dev": true,
"funding": [
{
@@ -4071,6 +5577,8 @@
},
"node_modules/buffer": {
"version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz",
+ "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4080,6 +5588,8 @@
},
"node_modules/call-bind-apply-helpers": {
"version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
+ "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4092,6 +5602,8 @@
},
"node_modules/call-bound": {
"version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
+ "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4107,6 +5619,8 @@
},
"node_modules/callsites": {
"version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -4115,6 +5629,8 @@
},
"node_modules/camelcase": {
"version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -4123,6 +5639,8 @@
},
"node_modules/caniuse-lite": {
"version": "1.0.30001793",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001793.tgz",
+ "integrity": "sha512-iwSsYWaCOoh26cV8NwNRViHlrfUvYsHDfRVcbtmw0Kg6PJIZZXwMkj1442FYLBGkeUf1juAsU3DTfxW579mrPA==",
"dev": true,
"funding": [
{
@@ -4141,14 +5659,13 @@
"license": "CC-BY-4.0"
},
"node_modules/chalk": {
- "version": "4.1.2",
+ "version": "5.6.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz",
+ "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==",
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
"engines": {
- "node": ">=10"
+ "node": "^12.17.0 || ^14.13 || >=16.0.0"
},
"funding": {
"url": "https://github.com/chalk/chalk?sponsor=1"
@@ -4156,6 +5673,8 @@
},
"node_modules/chalk-template": {
"version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/chalk-template/-/chalk-template-0.4.0.tgz",
+ "integrity": "sha512-/ghrgmhfY8RaSdeo43hNXxpoHAtxdbskUHjPpfqUWGttFgycUhYPGx3YZBCnUCvOa7Doivn1IZec3DEGFoMgLg==",
"license": "MIT",
"dependencies": {
"chalk": "^4.1.2"
@@ -4167,8 +5686,10 @@
"url": "https://github.com/chalk/chalk-template?sponsor=1"
}
},
- "node_modules/chalk/node_modules/ansi-styles": {
+ "node_modules/chalk-template/node_modules/ansi-styles": {
"version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"license": "MIT",
"dependencies": {
"color-convert": "^2.0.1"
@@ -4180,8 +5701,26 @@
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
- "node_modules/chalk/node_modules/color-convert": {
+ "node_modules/chalk-template/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/chalk-template/node_modules/color-convert": {
"version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"license": "MIT",
"dependencies": {
"color-name": "~1.1.4"
@@ -4190,20 +5729,28 @@
"node": ">=7.0.0"
}
},
- "node_modules/chalk/node_modules/color-name": {
+ "node_modules/chalk-template/node_modules/color-name": {
"version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"license": "MIT"
},
"node_modules/change-case": {
"version": "5.4.4",
+ "resolved": "https://registry.npmjs.org/change-case/-/change-case-5.4.4.tgz",
+ "integrity": "sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==",
"license": "MIT"
},
"node_modules/chardet": {
"version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.1.tgz",
+ "integrity": "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==",
"license": "MIT"
},
"node_modules/cheerio": {
"version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.2.0.tgz",
+ "integrity": "sha512-WDrybc/gKFpTYQutKIK6UvfcuxijIZfMfXaYm8NMsPQxSYvf+13fXUJ4rztGGbJcBQ/GF55gvrZ0Bc0bj/mqvg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4228,6 +5775,8 @@
},
"node_modules/cheerio-select": {
"version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz",
+ "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
@@ -4243,7 +5792,9 @@
}
},
"node_modules/cheerio/node_modules/undici": {
- "version": "7.25.0",
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/undici/-/undici-7.26.0.tgz",
+ "integrity": "sha512-3O9Tf67pGhgOv9jM35AbhkXAKi13f3oy3aE4CSgr+TckGeY+/iu97ZXN+J7DpHPzLbVApFd1IFhcnBjREYXYcg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -4252,6 +5803,8 @@
},
"node_modules/cli-width": {
"version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz",
+ "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==",
"dev": true,
"license": "ISC",
"engines": {
@@ -4260,6 +5813,8 @@
},
"node_modules/cliui": {
"version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz",
+ "integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==",
"dev": true,
"license": "ISC",
"dependencies": {
@@ -4273,6 +5828,8 @@
},
"node_modules/clsx": {
"version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
+ "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==",
"license": "MIT",
"engines": {
"node": ">=6"
@@ -4280,6 +5837,8 @@
},
"node_modules/color-convert": {
"version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-3.1.3.tgz",
+ "integrity": "sha512-fasDH2ont2GqF5HpyO4w0+BcewlhHEZOFn9c1ckZdHpJ56Qb7MHhH/IcJZbBGgvdtwdwNbLvxiBEdg336iA9Sg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4291,6 +5850,8 @@
},
"node_modules/color-name": {
"version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz",
+ "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -4299,6 +5860,8 @@
},
"node_modules/command-line-args": {
"version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-6.0.2.tgz",
+ "integrity": "sha512-AIjYVxrV9X752LmPDLbVYv8aMCuHPSLZJXEo2qo/xJfv+NYhaZ4sMSF01rM+gHPaMgvPM0l5D/F+Qx+i2WfSmQ==",
"license": "MIT",
"dependencies": {
"array-back": "^6.2.3",
@@ -4320,6 +5883,8 @@
},
"node_modules/command-line-usage": {
"version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-7.0.4.tgz",
+ "integrity": "sha512-85UdvzTNx/+s5CkSgBm/0hzP80RFHAa7PsfeADE5ezZF3uHz3/Tqj9gIKGT9PTtpycc3Ua64T0oVulGfKxzfqg==",
"license": "MIT",
"dependencies": {
"array-back": "^6.2.2",
@@ -4333,6 +5898,8 @@
},
"node_modules/commander": {
"version": "14.0.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz",
+ "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==",
"license": "MIT",
"engines": {
"node": ">=20"
@@ -4340,6 +5907,8 @@
},
"node_modules/compare-func": {
"version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz",
+ "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4349,6 +5918,8 @@
},
"node_modules/complex.js": {
"version": "2.4.3",
+ "resolved": "https://registry.npmjs.org/complex.js/-/complex.js-2.4.3.tgz",
+ "integrity": "sha512-UrQVSUur14tNX6tiP4y8T4w4FeJAX3bi2cIv0pu/DTLFNxoq7z2Yh83Vfzztj6Px3X/lubqQ9IrPp7Bpn6p4MQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -4361,6 +5932,8 @@
},
"node_modules/condense-newlines": {
"version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/condense-newlines/-/condense-newlines-0.2.1.tgz",
+ "integrity": "sha512-P7X+QL9Hb9B/c8HI5BFFKmjgBu2XpQuF98WZ9XkO+dBGgk5XgwiQz7o1SmpglNWId3581UcS0SFAWfoIhMHPfg==",
"license": "MIT",
"dependencies": {
"extend-shallow": "^2.0.1",
@@ -4373,6 +5946,8 @@
},
"node_modules/config-chain": {
"version": "1.1.13",
+ "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz",
+ "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==",
"license": "MIT",
"dependencies": {
"ini": "^1.3.4",
@@ -4381,10 +5956,14 @@
},
"node_modules/config-chain/node_modules/ini": {
"version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
+ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
"license": "ISC"
},
"node_modules/conventional-changelog-angular": {
"version": "8.3.1",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-8.3.1.tgz",
+ "integrity": "sha512-6gfI3otXK5Ph5DfCOI1dblr+kN3FAm5a97hYoQkqNZxOaYa5WKfXH+AnpsmS+iUH2mgVC2Cg2Qw9m5OKcmNrIg==",
"dev": true,
"license": "ISC",
"dependencies": {
@@ -4396,6 +5975,8 @@
},
"node_modules/conventional-changelog-conventionalcommits": {
"version": "9.3.1",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-9.3.1.tgz",
+ "integrity": "sha512-dTYtpIacRpcZgrvBYvBfArMmK2xvIpv2TaxM0/ZI5CBtNUzvF2x0t15HsbRABWprS6UPmvj+PzHVjSx4qAVKyw==",
"dev": true,
"license": "ISC",
"dependencies": {
@@ -4407,6 +5988,8 @@
},
"node_modules/conventional-commits-parser": {
"version": "6.4.0",
+ "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-6.4.0.tgz",
+ "integrity": "sha512-tvRg7FIBNlyPzjdG8wWRlPHQJJHI7DylhtRGeU9Lq+JuoPh5BKpPRX83ZdLrvXuOSu5Eo/e7SzOQhU4Hd2Miuw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4422,11 +6005,15 @@
},
"node_modules/convert-source-map": {
"version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
"dev": true,
"license": "MIT"
},
"node_modules/cookie": {
"version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
+ "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
"dev": true,
"license": "MIT",
"engines": {
@@ -4435,6 +6022,8 @@
},
"node_modules/cosmiconfig": {
"version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.1.tgz",
+ "integrity": "sha512-hr4ihw+DBqcvrsEDioRO31Z17x71pUYoNe/4h6Z0wB72p7MU7/9gH8Q3s12NFhHPfYBBOV3qyfUxmr/Yn3shnQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4460,6 +6049,8 @@
},
"node_modules/cosmiconfig-typescript-loader": {
"version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-6.3.0.tgz",
+ "integrity": "sha512-Akr82WH1Wfqatyiqpj8HDkO2o2KmJRu1FhKfSNJP3K4IdXwHfEyL7MOb62i1AGQVLtIQM+iCE9CGOtrfhR+mmA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4476,6 +6067,8 @@
},
"node_modules/cross-spawn": {
"version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
"license": "MIT",
"dependencies": {
"path-key": "^3.1.0",
@@ -4488,6 +6081,8 @@
},
"node_modules/css-select": {
"version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz",
+ "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
@@ -4503,6 +6098,8 @@
},
"node_modules/css-tree": {
"version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.2.1.tgz",
+ "integrity": "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4515,6 +6112,8 @@
},
"node_modules/css-what": {
"version": "6.2.2",
+ "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz",
+ "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==",
"dev": true,
"license": "BSD-2-Clause",
"engines": {
@@ -4526,6 +6125,8 @@
},
"node_modules/csso": {
"version": "5.0.5",
+ "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz",
+ "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4538,6 +6139,8 @@
},
"node_modules/csso/node_modules/css-tree": {
"version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz",
+ "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4551,6 +6154,8 @@
},
"node_modules/csso/node_modules/mdn-data": {
"version": "2.0.28",
+ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz",
+ "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==",
"dev": true,
"license": "CC0-1.0"
},
@@ -4560,6 +6165,8 @@
},
"node_modules/debug": {
"version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4576,6 +6183,8 @@
},
"node_modules/decamelize": {
"version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+ "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -4584,11 +6193,15 @@
},
"node_modules/decimal.js": {
"version": "10.6.0",
+ "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz",
+ "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==",
"dev": true,
"license": "MIT"
},
"node_modules/deepmerge": {
"version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
+ "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
"dev": true,
"license": "MIT",
"engines": {
@@ -4597,6 +6210,8 @@
},
"node_modules/des.js": {
"version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz",
+ "integrity": "sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4606,6 +6221,8 @@
},
"node_modules/detect-libc": {
"version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
+ "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
"dev": true,
"license": "Apache-2.0",
"engines": {
@@ -4614,10 +6231,14 @@
},
"node_modules/devalue": {
"version": "5.8.1",
+ "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.8.1.tgz",
+ "integrity": "sha512-4CXDYRBGqN+57wVJkuXBYmpAVUSg3L6JAQa/DFqm238G73E1wuyc/JhGQJzN7vUf/CMphYau2zXbfWzDR5aTEw==",
"license": "MIT"
},
"node_modules/diff": {
"version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.2.tgz",
+ "integrity": "sha512-vtcDfH3TOjP8UekytvnHH1o1P4FcUdt4eQ1Y+Abap1tk/OB2MWQvcwS2ClCd1zuIhc3JKOx6p3kod8Vfys3E+A==",
"dev": true,
"license": "BSD-3-Clause",
"engines": {
@@ -4626,11 +6247,15 @@
},
"node_modules/diff-match-patch": {
"version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.5.tgz",
+ "integrity": "sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==",
"dev": true,
"license": "Apache-2.0"
},
"node_modules/dir-glob": {
"version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
+ "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4642,10 +6267,14 @@
},
"node_modules/discontinuous-range": {
"version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/discontinuous-range/-/discontinuous-range-1.0.0.tgz",
+ "integrity": "sha512-c68LpLbO+7kP/b1Hr1qs8/BJ09F5khZGTxqxZuhzxpmwJKOgRFHJWIb9/KmqnqHhLdO55aOxFH/EGBvUQbL/RQ==",
"license": "MIT"
},
"node_modules/dom-serializer": {
"version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
+ "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4659,6 +6288,8 @@
},
"node_modules/domelementtype": {
"version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
+ "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
"dev": true,
"funding": [
{
@@ -4670,6 +6301,8 @@
},
"node_modules/domhandler": {
"version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
+ "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
@@ -4684,6 +6317,8 @@
},
"node_modules/domutils": {
"version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz",
+ "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
@@ -4697,6 +6332,8 @@
},
"node_modules/dot-prop": {
"version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz",
+ "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4708,6 +6345,8 @@
},
"node_modules/dunder-proto": {
"version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
+ "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4721,10 +6360,14 @@
},
"node_modules/eastasianwidth": {
"version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
+ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
"license": "MIT"
},
"node_modules/editorconfig": {
"version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-1.0.7.tgz",
+ "integrity": "sha512-e0GOtq/aTQhVdNyDU9e02+wz9oDDM+SIOQxWME2QRjzRX5yyLAuHDE+0aE8vHb9XRC8XD37eO2u57+F09JqFhw==",
"license": "MIT",
"dependencies": {
"@one-ini/wasm": "0.1.1",
@@ -4741,10 +6384,14 @@
},
"node_modules/editorconfig/node_modules/balanced-match": {
"version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"license": "MIT"
},
"node_modules/editorconfig/node_modules/brace-expansion": {
- "version": "2.1.0",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.1.tgz",
+ "integrity": "sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==",
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0"
@@ -4752,6 +6399,8 @@
},
"node_modules/editorconfig/node_modules/commander": {
"version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
+ "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==",
"license": "MIT",
"engines": {
"node": ">=14"
@@ -4759,6 +6408,8 @@
},
"node_modules/editorconfig/node_modules/minimatch": {
"version": "9.0.9",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
+ "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
"license": "ISC",
"dependencies": {
"brace-expansion": "^2.0.2"
@@ -4772,16 +6423,22 @@
},
"node_modules/electron-to-chromium": {
"version": "1.5.364",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.364.tgz",
+ "integrity": "sha512-G/dYE3+AYhyHwzTwg8UbnXf7zqMERYh7l2jJ3QujhFsH8agSYwtnGAR2aZ7f0AakIKJXd5En/Hre4igIUrdlYw==",
"dev": true,
"license": "ISC"
},
"node_modules/emoji-regex": {
"version": "10.6.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz",
+ "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==",
"dev": true,
"license": "MIT"
},
"node_modules/encoding-sniffer": {
"version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz",
+ "integrity": "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4794,6 +6451,8 @@
},
"node_modules/encoding-sniffer/node_modules/iconv-lite": {
"version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4805,6 +6464,8 @@
},
"node_modules/entities": {
"version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+ "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
"dev": true,
"license": "BSD-2-Clause",
"engines": {
@@ -4816,6 +6477,8 @@
},
"node_modules/env-paths": {
"version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
+ "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
"dev": true,
"license": "MIT",
"engines": {
@@ -4824,6 +6487,8 @@
},
"node_modules/error-ex": {
"version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz",
+ "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4832,6 +6497,8 @@
},
"node_modules/error-stack-parser-es": {
"version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/error-stack-parser-es/-/error-stack-parser-es-1.0.5.tgz",
+ "integrity": "sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==",
"dev": true,
"license": "MIT",
"funding": {
@@ -4840,6 +6507,8 @@
},
"node_modules/es-define-property": {
"version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
+ "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
"dev": true,
"license": "MIT",
"engines": {
@@ -4848,6 +6517,8 @@
},
"node_modules/es-errors": {
"version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
+ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -4856,6 +6527,8 @@
},
"node_modules/es-object-atoms": {
"version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz",
+ "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4866,7 +6539,9 @@
}
},
"node_modules/es-toolkit": {
- "version": "1.46.1",
+ "version": "1.47.0",
+ "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.47.0.tgz",
+ "integrity": "sha512-n1GuoD0WEQZMBk5tttoZSqwgyLx01oqa5XsBmCHwPyNe1S9jPBEmtR2pSgp2kJuWE3ciFZ6yRHmY4pM4C3OOkw==",
"dev": true,
"license": "MIT",
"workspaces": [
@@ -4876,6 +6551,8 @@
},
"node_modules/esbuild": {
"version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.0.tgz",
+ "integrity": "sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw==",
"hasInstallScript": true,
"license": "MIT",
"bin": {
@@ -4915,6 +6592,8 @@
},
"node_modules/escalade": {
"version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -4923,15 +6602,21 @@
},
"node_modules/escape-latex": {
"version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/escape-latex/-/escape-latex-1.2.0.tgz",
+ "integrity": "sha512-nV5aVWW1K0wEiUIEdZ4erkGGH8mDxGyxSeqPzRNtWP7ataw+/olFObw7hujFWlVjNsaDFw5VZ5NzVSIqRgfTiw==",
"dev": true,
"license": "MIT"
},
"node_modules/esm-env": {
"version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.2.2.tgz",
+ "integrity": "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==",
"license": "MIT"
},
"node_modules/esprima": {
"version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
"dev": true,
"license": "BSD-2-Clause",
"bin": {
@@ -4944,6 +6629,8 @@
},
"node_modules/esrap": {
"version": "2.2.9",
+ "resolved": "https://registry.npmjs.org/esrap/-/esrap-2.2.9.tgz",
+ "integrity": "sha512-4KijP+NxCWthMCUC3qHbE6n4vCjqgJS1uAYKhuT/GWfFTf1Qyive2TgOjep+gzbSzRfnNyaN/UU9YmdOt8Eg0A==",
"license": "MIT",
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.4.15"
@@ -4959,6 +6646,8 @@
},
"node_modules/events": {
"version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
+ "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
"dev": true,
"license": "MIT",
"engines": {
@@ -4967,6 +6656,8 @@
},
"node_modules/execa": {
"version": "9.6.1",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-9.6.1.tgz",
+ "integrity": "sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4992,6 +6683,8 @@
},
"node_modules/extend-shallow": {
"version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==",
"license": "MIT",
"dependencies": {
"is-extendable": "^0.1.0"
@@ -5002,6 +6695,8 @@
},
"node_modules/fast-check": {
"version": "4.8.0",
+ "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-4.8.0.tgz",
+ "integrity": "sha512-GOJ158CUMnN6cSahsv4+ExARvIDuzzinFjkp0E9WtiBa5zcVeLozVkWaE4IzFcc+Y48Wp1EDlUZsXRyAztQcSg==",
"dev": true,
"funding": [
{
@@ -5023,10 +6718,14 @@
},
"node_modules/fast-deep-equal": {
"version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
"license": "MIT"
},
"node_modules/fast-glob": {
"version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
+ "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5042,11 +6741,15 @@
},
"node_modules/fast-string-truncated-width": {
"version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/fast-string-truncated-width/-/fast-string-truncated-width-3.0.3.tgz",
+ "integrity": "sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g==",
"dev": true,
"license": "MIT"
},
"node_modules/fast-string-width": {
"version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/fast-string-width/-/fast-string-width-3.0.2.tgz",
+ "integrity": "sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5055,6 +6758,8 @@
},
"node_modules/fast-uri": {
"version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz",
+ "integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==",
"funding": [
{
"type": "github",
@@ -5069,6 +6774,8 @@
},
"node_modules/fast-wrap-ansi": {
"version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/fast-wrap-ansi/-/fast-wrap-ansi-0.2.2.tgz",
+ "integrity": "sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5077,6 +6784,8 @@
},
"node_modules/fast-xml-builder": {
"version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.2.0.tgz",
+ "integrity": "sha512-00aAWieqff+ZJhsXA4g1g7M8k+7AYoMUUHF+/zFb5U6Uv/P0Vl4QZo84/IcufzYalLuEj9928bXN9PbbFzMF0Q==",
"dev": true,
"funding": [
{
@@ -5092,6 +6801,8 @@
},
"node_modules/fast-xml-parser": {
"version": "5.7.3",
+ "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.7.3.tgz",
+ "integrity": "sha512-C0AaNuC+mscy6vrAQKAc/rMq+zAPHodfHGZu4sGVehvAQt/JLG1O5zEcYcXSY5zSqr4YVgxsB+pHXTq0i7eDlg==",
"dev": true,
"funding": [
{
@@ -5112,6 +6823,8 @@
},
"node_modules/fastq": {
"version": "1.20.1",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz",
+ "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==",
"dev": true,
"license": "ISC",
"dependencies": {
@@ -5120,6 +6833,8 @@
},
"node_modules/figures": {
"version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/figures/-/figures-6.1.0.tgz",
+ "integrity": "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5134,6 +6849,8 @@
},
"node_modules/fill-range": {
"version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5145,6 +6862,8 @@
},
"node_modules/find-replace": {
"version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-5.0.2.tgz",
+ "integrity": "sha512-Y45BAiE3mz2QsrN2fb5QEtO4qb44NcS7en/0y9PEVsg351HsLeVclP8QPMH79Le9sH3rs5RSwJu99W0WPZO43Q==",
"license": "MIT",
"engines": {
"node": ">=14"
@@ -5160,6 +6879,8 @@
},
"node_modules/find-up": {
"version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+ "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5171,10 +6892,14 @@
},
"node_modules/flatbuffers": {
"version": "25.9.23",
+ "resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-25.9.23.tgz",
+ "integrity": "sha512-MI1qs7Lo4Syw0EOzUl0xjs2lsoeqFku44KpngfIduHBYvzm8h2+7K8YMQh1JtVVVrUvhLpNwqVi4DERegUJhPQ==",
"license": "Apache-2.0"
},
"node_modules/fluent-transpiler": {
"version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/fluent-transpiler/-/fluent-transpiler-0.4.1.tgz",
+ "integrity": "sha512-9CNRxPbnMDTt1hdtD2YPdbyH/p5o3xRgkcsZm0dgER+Kg2k3mdvDb4BJ6lVeFx+cGKp6GWPxcZ2n8R4b45JqJw==",
"license": "MIT",
"workspaces": [
".github"
@@ -5197,6 +6922,8 @@
},
"node_modules/foreground-child": {
"version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
+ "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==",
"license": "ISC",
"dependencies": {
"cross-spawn": "^7.0.6",
@@ -5211,6 +6938,8 @@
},
"node_modules/fraction.js": {
"version": "5.3.4",
+ "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.3.4.tgz",
+ "integrity": "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -5223,6 +6952,8 @@
},
"node_modules/fs-extra": {
"version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
+ "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5236,12 +6967,17 @@
},
"node_modules/fs.realpath": {
"version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
"dev": true,
"license": "ISC"
},
"node_modules/fsevents": {
"version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
"dev": true,
+ "hasInstallScript": true,
"license": "MIT",
"optional": true,
"os": [
@@ -5253,6 +6989,8 @@
},
"node_modules/function-bind": {
"version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
"dev": true,
"license": "MIT",
"funding": {
@@ -5261,6 +6999,8 @@
},
"node_modules/gensync": {
"version": "1.0.0-beta.2",
+ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -5269,6 +7009,8 @@
},
"node_modules/get-caller-file": {
"version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
"dev": true,
"license": "ISC",
"engines": {
@@ -5277,6 +7019,8 @@
},
"node_modules/get-east-asian-width": {
"version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz",
+ "integrity": "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -5288,6 +7032,8 @@
},
"node_modules/get-intrinsic": {
"version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
+ "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5311,6 +7057,8 @@
},
"node_modules/get-proto": {
"version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
+ "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5323,6 +7071,8 @@
},
"node_modules/get-stream": {
"version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz",
+ "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5338,6 +7088,8 @@
},
"node_modules/git-raw-commits": {
"version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-5.0.1.tgz",
+ "integrity": "sha512-Y+csSm2GD/PCSh6Isd/WiMjNAydu0VBiG9J7EdQsNA5P9uXvLayqjmTsNlK5Gs9IhblFZqOU0yid5Il5JPoLiQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5353,6 +7105,8 @@
},
"node_modules/gitignore-to-glob": {
"version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/gitignore-to-glob/-/gitignore-to-glob-0.3.0.tgz",
+ "integrity": "sha512-mk74BdnK7lIwDHnotHddx1wsjMOFIThpLY3cPNniJ/2fA/tlLzHnFxIdR+4sLOu5KGgQJdij4kjJ2RoUNnCNMA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -5361,6 +7115,9 @@
},
"node_modules/glob": {
"version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me",
"dev": true,
"license": "ISC",
"dependencies": {
@@ -5380,6 +7137,8 @@
},
"node_modules/glob-parent": {
"version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
"dev": true,
"license": "ISC",
"dependencies": {
@@ -5391,6 +7150,8 @@
},
"node_modules/global-directory": {
"version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/global-directory/-/global-directory-5.0.0.tgz",
+ "integrity": "sha512-1pgFdhK3J2LeM+dVf2Pd424yHx2ou338lC0ErNP2hPx4j8eW1Sp0XqSjNxtk6Tc4Kr5wlWtSvz8cn2yb7/SG/w==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5405,6 +7166,8 @@
},
"node_modules/globby": {
"version": "10.0.2",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz",
+ "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5423,6 +7186,8 @@
},
"node_modules/gopd": {
"version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -5434,11 +7199,15 @@
},
"node_modules/graceful-fs": {
"version": "4.2.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
"dev": true,
"license": "ISC"
},
"node_modules/has-flag": {
"version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"license": "MIT",
"engines": {
"node": ">=8"
@@ -5446,6 +7215,8 @@
},
"node_modules/has-symbols": {
"version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
+ "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -5457,10 +7228,14 @@
},
"node_modules/hash-wasm": {
"version": "4.12.0",
+ "resolved": "https://registry.npmjs.org/hash-wasm/-/hash-wasm-4.12.0.tgz",
+ "integrity": "sha512-+/2B2rYLb48I/evdOIhP+K/DD2ca2fgBjp6O+GBEnCDk2e4rpeXIK8GvIyRPjTezgmWn9gmKwkQjjx6BtqDHVQ==",
"license": "MIT"
},
"node_modules/hasown": {
"version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz",
+ "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5472,6 +7247,8 @@
},
"node_modules/hast-util-to-string": {
"version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/hast-util-to-string/-/hast-util-to-string-3.0.1.tgz",
+ "integrity": "sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==",
"license": "MIT",
"dependencies": {
"@types/hast": "^3.0.0"
@@ -5483,6 +7260,8 @@
},
"node_modules/htmlparser2": {
"version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.1.0.tgz",
+ "integrity": "sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==",
"dev": true,
"funding": [
"https://github.com/fb55/htmlparser2?sponsor=1",
@@ -5501,6 +7280,8 @@
},
"node_modules/htmlparser2/node_modules/entities": {
"version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz",
+ "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==",
"dev": true,
"license": "BSD-2-Clause",
"engines": {
@@ -5512,6 +7293,8 @@
},
"node_modules/human-signals": {
"version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.1.tgz",
+ "integrity": "sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==",
"dev": true,
"license": "Apache-2.0",
"engines": {
@@ -5520,6 +7303,8 @@
},
"node_modules/husky": {
"version": "9.1.7",
+ "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz",
+ "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==",
"dev": true,
"license": "MIT",
"bin": {
@@ -5534,6 +7319,8 @@
},
"node_modules/iconv-lite": {
"version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz",
+ "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==",
"license": "MIT",
"dependencies": {
"safer-buffer": ">= 2.1.2 < 3.0.0"
@@ -5548,10 +7335,14 @@
},
"node_modules/idb": {
"version": "8.0.3",
+ "resolved": "https://registry.npmjs.org/idb/-/idb-8.0.3.tgz",
+ "integrity": "sha512-LtwtVyVYO5BqRvcsKuB2iUMnHwPVByPCXFXOpuU96IZPPoPN6xjOGxZQ74pgSVVLQWtUOYgyeL4GE98BY5D3wg==",
"license": "ISC"
},
"node_modules/ieee754": {
"version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
"dev": true,
"funding": [
{
@@ -5571,6 +7362,8 @@
},
"node_modules/ignore": {
"version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
"dev": true,
"license": "MIT",
"engines": {
@@ -5579,6 +7372,8 @@
},
"node_modules/import-fresh": {
"version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
+ "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5594,6 +7389,8 @@
},
"node_modules/import-fresh/node_modules/resolve-from": {
"version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
"dev": true,
"license": "MIT",
"engines": {
@@ -5602,6 +7399,9 @@
},
"node_modules/inflight": {
"version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
"dev": true,
"license": "ISC",
"dependencies": {
@@ -5611,11 +7411,15 @@
},
"node_modules/inherits": {
"version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
"dev": true,
"license": "ISC"
},
"node_modules/ini": {
"version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-6.0.0.tgz",
+ "integrity": "sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ==",
"dev": true,
"license": "ISC",
"engines": {
@@ -5624,15 +7428,21 @@
},
"node_modules/is-arrayish": {
"version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
"dev": true,
"license": "MIT"
},
"node_modules/is-buffer": {
"version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
"license": "MIT"
},
"node_modules/is-extendable": {
"version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+ "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
@@ -5640,6 +7450,8 @@
},
"node_modules/is-extglob": {
"version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -5648,6 +7460,8 @@
},
"node_modules/is-fullwidth-code-point": {
"version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
"license": "MIT",
"engines": {
"node": ">=8"
@@ -5655,6 +7469,8 @@
},
"node_modules/is-glob": {
"version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5666,6 +7482,8 @@
},
"node_modules/is-number": {
"version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
"dev": true,
"license": "MIT",
"engines": {
@@ -5674,6 +7492,8 @@
},
"node_modules/is-obj": {
"version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz",
+ "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==",
"dev": true,
"license": "MIT",
"engines": {
@@ -5682,6 +7502,8 @@
},
"node_modules/is-plain-obj": {
"version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz",
+ "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -5693,6 +7515,8 @@
},
"node_modules/is-reference": {
"version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.3.tgz",
+ "integrity": "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==",
"license": "MIT",
"dependencies": {
"@types/estree": "^1.0.6"
@@ -5700,6 +7524,8 @@
},
"node_modules/is-stream": {
"version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz",
+ "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==",
"dev": true,
"license": "MIT",
"engines": {
@@ -5711,6 +7537,8 @@
},
"node_modules/is-unicode-supported": {
"version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz",
+ "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -5722,6 +7550,8 @@
},
"node_modules/is-whitespace": {
"version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/is-whitespace/-/is-whitespace-0.3.0.tgz",
+ "integrity": "sha512-RydPhl4S6JwAyj0JJjshWJEFG6hNye3pZFBRZaTUfZFwGHxzppNaNOVgQuS/E/SlhrApuMXrpnK1EEIXfdo3Dg==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
@@ -5729,10 +7559,14 @@
},
"node_modules/isexe": {
"version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
"license": "ISC"
},
"node_modules/jackspeak": {
"version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
+ "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
"license": "BlueOak-1.0.0",
"dependencies": {
"@isaacs/cliui": "^8.0.2"
@@ -5746,11 +7580,15 @@
},
"node_modules/javascript-natural-sort": {
"version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz",
+ "integrity": "sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==",
"dev": true,
"license": "MIT"
},
"node_modules/jiti": {
"version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz",
+ "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==",
"dev": true,
"license": "MIT",
"bin": {
@@ -5759,6 +7597,8 @@
},
"node_modules/js-beautify": {
"version": "1.15.4",
+ "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.15.4.tgz",
+ "integrity": "sha512-9/KXeZUKKJwqCXUdBxFJ3vPh467OCckSBmYDwSK/EtV090K+iMJ7zx2S3HLVDIWFQdqMIsZWbnaGiba18aWhaA==",
"license": "MIT",
"dependencies": {
"config-chain": "^1.1.13",
@@ -5778,10 +7618,14 @@
},
"node_modules/js-beautify/node_modules/balanced-match": {
"version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"license": "MIT"
},
"node_modules/js-beautify/node_modules/brace-expansion": {
- "version": "2.1.0",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.1.tgz",
+ "integrity": "sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==",
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0"
@@ -5789,6 +7633,9 @@
},
"node_modules/js-beautify/node_modules/glob": {
"version": "10.5.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz",
+ "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==",
+ "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me",
"license": "ISC",
"dependencies": {
"foreground-child": "^3.1.0",
@@ -5807,6 +7654,8 @@
},
"node_modules/js-beautify/node_modules/minimatch": {
"version": "9.0.9",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
+ "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
"license": "ISC",
"dependencies": {
"brace-expansion": "^2.0.2"
@@ -5819,24 +7668,39 @@
}
},
"node_modules/js-cookie": {
- "version": "3.0.7",
- "license": "MIT",
- "engines": {
- "node": ">=20"
- }
+ "version": "3.0.8",
+ "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.8.tgz",
+ "integrity": "sha512-yeJd4aNAdYZQjaon2bpD/Gb0B/omw7HQOsynXXcOiWVCacbBcPlgn8S/d1X6blFSaHao7ozqtW7NZW19xpCtIw==",
+ "license": "MIT"
},
"node_modules/js-md4": {
"version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/js-md4/-/js-md4-0.3.2.tgz",
+ "integrity": "sha512-/GDnfQYsltsjRswQhN9fhv3EMw2sCpUdrdxyWDOUK7eyD++r3gRhzgiQgc/x4MAv2i1iuQ4lxO5mvqM3vj4bwA==",
"dev": true,
"license": "MIT"
},
"node_modules/js-tokens": {
"version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
"dev": true,
"license": "MIT"
},
"node_modules/js-yaml": {
- "version": "4.1.1",
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.2.0.tgz",
+ "integrity": "sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/puzrin"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/nodeca"
+ }
+ ],
"license": "MIT",
"dependencies": {
"argparse": "^2.0.1"
@@ -5847,6 +7711,8 @@
},
"node_modules/jsesc": {
"version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
+ "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
"license": "MIT",
"bin": {
"jsesc": "bin/jsesc"
@@ -5857,26 +7723,36 @@
},
"node_modules/json-bignum": {
"version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/json-bignum/-/json-bignum-0.0.3.tgz",
+ "integrity": "sha512-2WHyXj3OfHSgNyuzDbSxI1w2jgw5gkWSWhS7Qg4bWXx1nLk3jnbwfUeS0PSba3IzpTUWdHxBieELUzXRjQB2zg==",
"engines": {
"node": ">=0.8"
}
},
"node_modules/json-parse-even-better-errors": {
"version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
+ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
"dev": true,
"license": "MIT"
},
"node_modules/json-rpc-2.0": {
"version": "1.7.1",
+ "resolved": "https://registry.npmjs.org/json-rpc-2.0/-/json-rpc-2.0-1.7.1.tgz",
+ "integrity": "sha512-JqZjhjAanbpkXIzFE7u8mE/iFblawwlXtONaCvRqI+pyABVz7B4M1EUNpyVW+dZjqgQ2L5HFmZCmOCgUKm00hg==",
"dev": true,
"license": "MIT"
},
"node_modules/json-schema-traverse": {
"version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
"license": "MIT"
},
"node_modules/json5": {
"version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
"dev": true,
"license": "MIT",
"bin": {
@@ -5888,6 +7764,8 @@
},
"node_modules/jsonfile": {
"version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
+ "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==",
"dev": true,
"license": "MIT",
"optionalDependencies": {
@@ -5896,11 +7774,15 @@
},
"node_modules/just-extend": {
"version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-6.2.0.tgz",
+ "integrity": "sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==",
"dev": true,
"license": "MIT"
},
"node_modules/kafkajs": {
"version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/kafkajs/-/kafkajs-2.2.4.tgz",
+ "integrity": "sha512-j/YeapB1vfPT2iOIUn/vxdyKEuhuY2PxMBvf5JWux6iSaukAccrMtXEY/Lb7OvavDhOWME589bpLrEdnVHjfjA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -5909,6 +7791,8 @@
},
"node_modules/kind-of": {
"version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
"license": "MIT",
"dependencies": {
"is-buffer": "^1.1.5"
@@ -5919,6 +7803,8 @@
},
"node_modules/kleur": {
"version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz",
+ "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -5927,11 +7813,15 @@
},
"node_modules/libsodium": {
"version": "0.8.4",
+ "resolved": "https://registry.npmjs.org/libsodium/-/libsodium-0.8.4.tgz",
+ "integrity": "sha512-lMcYaRi0zcs7tarATsQUYC7rstliIXZuoq0c6zXSgNtSNtdvBgkSegjWhpMJAXzKX3SUSwIp7+zEsob+j3LuRw==",
"dev": true,
"license": "ISC"
},
"node_modules/libsodium-wrappers": {
"version": "0.8.4",
+ "resolved": "https://registry.npmjs.org/libsodium-wrappers/-/libsodium-wrappers-0.8.4.tgz",
+ "integrity": "sha512-mu8aAWucZjTB5O/BtGXtW4e1agy7uHxNYG7zPthmmD1jU43LCDmSWZLN4JhflbdPXj3yDO4lxM1O9hLDgIOXDw==",
"dev": true,
"license": "ISC",
"dependencies": {
@@ -5940,6 +7830,8 @@
},
"node_modules/license-check-and-add": {
"version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/license-check-and-add/-/license-check-and-add-4.0.5.tgz",
+ "integrity": "sha512-FySnMi3Kf/vO5jka8tcbVF1FhDFb8PWsQ8pg5Y7U/zkQgta+fIrJGcGHO58WFjfKlgvhneG1uQ00Fpxzhau3QA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -5955,6 +7847,8 @@
},
"node_modules/license-check-and-add/node_modules/ansi-regex": {
"version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz",
+ "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==",
"dev": true,
"license": "MIT",
"engines": {
@@ -5963,6 +7857,8 @@
},
"node_modules/license-check-and-add/node_modules/ansi-styles": {
"version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5974,6 +7870,8 @@
},
"node_modules/license-check-and-add/node_modules/cliui": {
"version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
+ "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
"dev": true,
"license": "ISC",
"dependencies": {
@@ -5984,6 +7882,8 @@
},
"node_modules/license-check-and-add/node_modules/color-convert": {
"version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5992,16 +7892,22 @@
},
"node_modules/license-check-and-add/node_modules/color-name": {
"version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
"dev": true,
"license": "MIT"
},
"node_modules/license-check-and-add/node_modules/emoji-regex": {
"version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
+ "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
"dev": true,
"license": "MIT"
},
"node_modules/license-check-and-add/node_modules/is-fullwidth-code-point": {
"version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==",
"dev": true,
"license": "MIT",
"engines": {
@@ -6010,6 +7916,8 @@
},
"node_modules/license-check-and-add/node_modules/string-width": {
"version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+ "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6023,6 +7931,8 @@
},
"node_modules/license-check-and-add/node_modules/strip-ansi": {
"version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6034,6 +7944,8 @@
},
"node_modules/license-check-and-add/node_modules/wrap-ansi": {
"version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
+ "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6047,11 +7959,15 @@
},
"node_modules/license-check-and-add/node_modules/y18n": {
"version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
+ "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==",
"dev": true,
"license": "ISC"
},
"node_modules/license-check-and-add/node_modules/yargs": {
"version": "13.3.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz",
+ "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6069,6 +7985,8 @@
},
"node_modules/license-check-and-add/node_modules/yargs-parser": {
"version": "13.1.2",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz",
+ "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==",
"dev": true,
"license": "ISC",
"dependencies": {
@@ -6078,6 +7996,8 @@
},
"node_modules/lightningcss": {
"version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz",
+ "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==",
"dev": true,
"license": "MPL-2.0",
"dependencies": {
@@ -6104,8 +8024,31 @@
"lightningcss-win32-x64-msvc": "1.32.0"
}
},
+ "node_modules/lightningcss-android-arm64": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz",
+ "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
"node_modules/lightningcss-darwin-arm64": {
"version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz",
+ "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==",
"cpu": [
"arm64"
],
@@ -6123,17 +8066,224 @@
"url": "https://opencollective.com/parcel"
}
},
+ "node_modules/lightningcss-darwin-x64": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz",
+ "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-freebsd-x64": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz",
+ "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm-gnueabihf": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz",
+ "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm64-gnu": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz",
+ "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm64-musl": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz",
+ "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-x64-gnu": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz",
+ "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-x64-musl": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz",
+ "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-win32-arm64-msvc": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz",
+ "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-win32-x64-msvc": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz",
+ "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
"node_modules/lines-and-columns": {
"version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
+ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
"dev": true,
"license": "MIT"
},
"node_modules/locate-character": {
"version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz",
+ "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==",
"license": "MIT"
},
"node_modules/locate-path": {
"version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+ "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6146,6 +8296,8 @@
},
"node_modules/lockfile-lint": {
"version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/lockfile-lint/-/lockfile-lint-5.0.0.tgz",
+ "integrity": "sha512-QcVIVITLZAhWYHU2wbNSOMgwc6EN4Y2sy6mjgS5aikYyRzgDIfotXUsCrm38En+3fZpc58Yu7DF9dNeT/goi1A==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -6164,6 +8316,8 @@
},
"node_modules/lockfile-lint-api": {
"version": "5.9.2",
+ "resolved": "https://registry.npmjs.org/lockfile-lint-api/-/lockfile-lint-api-5.9.2.tgz",
+ "integrity": "sha512-3QhxWxl3jT9GcMxuCnTsU8Tz5U6U1lKBlKBu2zOYOz/x3ONUoojEtky3uzoaaDgExcLqIX0Aqv2I7TZXE383CQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -6177,6 +8331,8 @@
},
"node_modules/lockfile-lint/node_modules/ansi-regex": {
"version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -6185,6 +8341,8 @@
},
"node_modules/lockfile-lint/node_modules/ansi-styles": {
"version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6199,6 +8357,8 @@
},
"node_modules/lockfile-lint/node_modules/cliui": {
"version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
+ "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
"dev": true,
"license": "ISC",
"dependencies": {
@@ -6212,6 +8372,8 @@
},
"node_modules/lockfile-lint/node_modules/color-convert": {
"version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6223,16 +8385,22 @@
},
"node_modules/lockfile-lint/node_modules/color-name": {
"version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true,
"license": "MIT"
},
"node_modules/lockfile-lint/node_modules/emoji-regex": {
"version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"dev": true,
"license": "MIT"
},
"node_modules/lockfile-lint/node_modules/string-width": {
"version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6246,6 +8414,8 @@
},
"node_modules/lockfile-lint/node_modules/strip-ansi": {
"version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6257,6 +8427,8 @@
},
"node_modules/lockfile-lint/node_modules/wrap-ansi": {
"version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6273,6 +8445,8 @@
},
"node_modules/lockfile-lint/node_modules/yargs": {
"version": "17.7.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
+ "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6290,6 +8464,8 @@
},
"node_modules/lockfile-lint/node_modules/yargs-parser": {
"version": "21.1.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+ "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
"dev": true,
"license": "ISC",
"engines": {
@@ -6298,24 +8474,38 @@
},
"node_modules/lodash.camelcase": {
"version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
+ "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==",
"license": "MIT"
},
"node_modules/lodash.groupby": {
"version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/lodash.groupby/-/lodash.groupby-4.6.0.tgz",
+ "integrity": "sha512-5dcWxm23+VAoz+awKmBaiBvzox8+RqMgFhi7UvX9DHZr2HdxHXM/Wrf8cfKpsW37RNrvtPn6hSwNqurSILbmJw==",
"dev": true,
"license": "MIT"
},
"node_modules/long": {
"version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz",
+ "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==",
"dev": true,
"license": "Apache-2.0"
},
"node_modules/lru-cache": {
- "version": "10.4.3",
- "license": "ISC"
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^3.0.2"
+ }
},
"node_modules/magic-string": {
"version": "0.30.21",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
+ "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
"license": "MIT",
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.5.5"
@@ -6323,6 +8513,8 @@
},
"node_modules/math-intrinsics": {
"version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
+ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
"dev": true,
"license": "MIT",
"engines": {
@@ -6331,6 +8523,8 @@
},
"node_modules/mathjs": {
"version": "15.2.0",
+ "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-15.2.0.tgz",
+ "integrity": "sha512-UAQzSVob9rNLdGpqcFMYmSu9dkuLYy7Lr2hBEQS5SHQdknA9VppJz3cy2KkpMzTODunad6V6cNv+5kOLsePLow==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -6353,6 +8547,8 @@
},
"node_modules/mdast-util-to-string": {
"version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz",
+ "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==",
"license": "MIT",
"dependencies": {
"@types/mdast": "^4.0.0"
@@ -6364,11 +8560,15 @@
},
"node_modules/mdn-data": {
"version": "2.27.1",
+ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.27.1.tgz",
+ "integrity": "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==",
"dev": true,
"license": "CC0-1.0"
},
"node_modules/mdsvex": {
"version": "0.12.7",
+ "resolved": "https://registry.npmjs.org/mdsvex/-/mdsvex-0.12.7.tgz",
+ "integrity": "sha512-gx4bReLCUvq+MPErHXYeyX+TEq1hsS2KfiZtEOMNTcbibSouFy8AHc5h04KbGCl+g5tLuo4/lbgRVYRnc7bJZw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6385,11 +8585,15 @@
},
"node_modules/mdsvex/node_modules/@types/unist": {
"version": "2.0.11",
+ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz",
+ "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==",
"dev": true,
"license": "MIT"
},
"node_modules/meow": {
"version": "13.2.0",
+ "resolved": "https://registry.npmjs.org/meow/-/meow-13.2.0.tgz",
+ "integrity": "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -6401,6 +8605,8 @@
},
"node_modules/merge2": {
"version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -6409,6 +8615,8 @@
},
"node_modules/micromatch": {
"version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6420,14 +8628,16 @@
}
},
"node_modules/miniflare": {
- "version": "4.20260520.0",
+ "version": "4.20260526.0",
+ "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-4.20260526.0.tgz",
+ "integrity": "sha512-JYQ7jPZZWoaaj9jWHb8Ucp6Cu2SbDVqIsAJhumqdzzLkkfq0pYkDeino/sZfW1ixJWPjv/C44zjm9gVJC2izCA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@cspotcode/source-map-support": "0.8.1",
"sharp": "^0.34.5",
"undici": "7.24.8",
- "workerd": "1.20260520.1",
+ "workerd": "1.20260526.1",
"ws": "8.20.1",
"youch": "4.1.0-beta.10"
},
@@ -6440,6 +8650,8 @@
},
"node_modules/miniflare/node_modules/undici": {
"version": "7.24.8",
+ "resolved": "https://registry.npmjs.org/undici/-/undici-7.24.8.tgz",
+ "integrity": "sha512-6KQ/+QxK49Z/p3HO6E5ZCZWNnCasyZLa5ExaVYyvPxUwKtbCPMKELJOqh7EqOle0t9cH/7d2TaaTRRa6Nhs4YQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -6448,11 +8660,15 @@
},
"node_modules/minimalistic-assert": {
"version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
+ "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==",
"dev": true,
"license": "ISC"
},
"node_modules/minimatch": {
"version": "10.2.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz",
+ "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
@@ -6467,6 +8683,8 @@
},
"node_modules/minipass": {
"version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz",
+ "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==",
"license": "BlueOak-1.0.0",
"engines": {
"node": ">=16 || 14 >=14.17"
@@ -6474,6 +8692,8 @@
},
"node_modules/mnemonist": {
"version": "0.38.3",
+ "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.3.tgz",
+ "integrity": "sha512-2K9QYubXx/NAjv4VLq1d1Ly8pWNC5L3BrixtdkyTegXWJIqY+zLNDhhX/A+ZwWt70tB1S8H4BE8FLYEFyNoOBw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6482,10 +8702,14 @@
},
"node_modules/moo": {
"version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/moo/-/moo-0.5.3.tgz",
+ "integrity": "sha512-m2fmM2dDm7GZQsY7KK2cme8agi+AAljILjQnof7p1ZMDe6dQ4bdnSMx0cPppudoeNv5hEFQirN6u+O4fDE0IWA==",
"license": "BSD-3-Clause"
},
"node_modules/mrmime": {
"version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz",
+ "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -6494,11 +8718,15 @@
},
"node_modules/ms": {
"version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"dev": true,
"license": "MIT"
},
"node_modules/mutation-server-protocol": {
"version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/mutation-server-protocol/-/mutation-server-protocol-0.4.1.tgz",
+ "integrity": "sha512-SBGK0j8hLDne7bktgThKI8kGvGTx3rY3LAeQTmOKZ5bVnL/7TorLMvcVF7dIPJCu5RNUWhkkuF53kurygYVt3g==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -6510,11 +8738,15 @@
},
"node_modules/mutation-testing-elements": {
"version": "3.7.3",
+ "resolved": "https://registry.npmjs.org/mutation-testing-elements/-/mutation-testing-elements-3.7.3.tgz",
+ "integrity": "sha512-SMeIPxngJpfjfNYctFpYQQtlBlZaVO0aoB3FKdwrI8Ee/2bkyUuCZzAOCLv1U9fnmfA37dPFq0Owduoxs2XgGQ==",
"dev": true,
"license": "Apache-2.0"
},
"node_modules/mutation-testing-metrics": {
"version": "3.7.3",
+ "resolved": "https://registry.npmjs.org/mutation-testing-metrics/-/mutation-testing-metrics-3.7.3.tgz",
+ "integrity": "sha512-B8QrP0ZomErzTPNlhrzKWPNBln+3afwBZPHv0Q7N8wZZTYxMptzb/Gdm3ExXVmioVYrtZAtsDs7W/T/b2AixOQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -6523,19 +8755,25 @@
},
"node_modules/mutation-testing-report-schema": {
"version": "3.7.3",
+ "resolved": "https://registry.npmjs.org/mutation-testing-report-schema/-/mutation-testing-report-schema-3.7.3.tgz",
+ "integrity": "sha512-BHm3MYq+ckO+t5CtlG8zpqxc75rdJCkxVlE+fGuGJM3F7tNCQ/OW2N+TQVHN3BHsYa84+BFc6g3AwDYkUsw2MA==",
"dev": true,
"license": "Apache-2.0"
},
"node_modules/mute-stream": {
- "version": "4.0.0",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-3.0.0.tgz",
+ "integrity": "sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw==",
"dev": true,
"license": "ISC",
"engines": {
- "node": "^22.22.2 || ^24.15.0 || >=26.0.0"
+ "node": "^20.17.0 || >=22.9.0"
}
},
"node_modules/nanoid": {
"version": "3.3.12",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz",
+ "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==",
"dev": true,
"funding": [
{
@@ -6553,6 +8791,8 @@
},
"node_modules/nearley": {
"version": "2.20.1",
+ "resolved": "https://registry.npmjs.org/nearley/-/nearley-2.20.1.tgz",
+ "integrity": "sha512-+Mc8UaAebFzgV+KpI5n7DasuuQCHA89dmwm7JXw3TV43ukfNQ9DnBH3Mdb2g/I4Fdxc26pwimBWvjIw0UAILSQ==",
"license": "MIT",
"dependencies": {
"commander": "^2.19.0",
@@ -6573,10 +8813,14 @@
},
"node_modules/nearley/node_modules/commander": {
"version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
"license": "MIT"
},
"node_modules/nise": {
"version": "6.1.5",
+ "resolved": "https://registry.npmjs.org/nise/-/nise-6.1.5.tgz",
+ "integrity": "sha512-SnRDPDBjxZZoU2n0+gzzLtSvo1OZo7j6jnbXsoh3AFxEGhaFU7ZF0TmefuKERq79wxR2U+MPn7ArW+Tl+clC3A==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
@@ -6588,6 +8832,8 @@
},
"node_modules/nise/node_modules/@sinonjs/fake-timers": {
"version": "15.4.0",
+ "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.4.0.tgz",
+ "integrity": "sha512-DsG+8/LscQIQg68J6Ef3dv10u6nVyetYn923s3/sus5eaGfTo1of5WMZSLf0UJc9KDuKPilPH0UDJCjvNbDNCA==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
@@ -6596,6 +8842,8 @@
},
"node_modules/node-fetch": {
"version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
+ "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6615,6 +8863,8 @@
},
"node_modules/node-releases": {
"version": "2.0.46",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.46.tgz",
+ "integrity": "sha512-GYVXHE2KnrzAfsAjl4uP++evGFCrAU1jta4ubEjIG7YWt/64Gqv66a30yKwWczVjA6j3bM4nBwH7Pk1JmDHaxQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -6623,6 +8873,8 @@
},
"node_modules/nopt": {
"version": "7.2.1",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.1.tgz",
+ "integrity": "sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==",
"license": "ISC",
"dependencies": {
"abbrev": "^2.0.0"
@@ -6636,6 +8888,8 @@
},
"node_modules/npm-run-path": {
"version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-6.0.0.tgz",
+ "integrity": "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6651,6 +8905,8 @@
},
"node_modules/npm-run-path/node_modules/path-key": {
"version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz",
+ "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -6662,6 +8918,8 @@
},
"node_modules/nth-check": {
"version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
+ "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
@@ -6673,6 +8931,8 @@
},
"node_modules/object-hash": {
"version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
+ "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -6681,6 +8941,8 @@
},
"node_modules/object-inspect": {
"version": "1.13.4",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
+ "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
"dev": true,
"license": "MIT",
"engines": {
@@ -6692,11 +8954,15 @@
},
"node_modules/obliterator": {
"version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-1.6.1.tgz",
+ "integrity": "sha512-9WXswnqINnnhOG/5SLimUlzuU1hFJUc8zkwyD59Sd+dPOMf05PmnYG/d6Q7HZ+KmgkZJa1PxRso6QdM3sTNHig==",
"dev": true,
"license": "MIT"
},
"node_modules/obug": {
"version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz",
+ "integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==",
"dev": true,
"funding": [
"https://github.com/sponsors/sxzz",
@@ -6706,6 +8972,8 @@
},
"node_modules/once": {
"version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
"dev": true,
"license": "ISC",
"dependencies": {
@@ -6714,6 +8982,8 @@
},
"node_modules/p-limit": {
"version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6728,6 +8998,8 @@
},
"node_modules/p-locate": {
"version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+ "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6739,6 +9011,8 @@
},
"node_modules/p-try": {
"version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -6747,10 +9021,14 @@
},
"node_modules/package-json-from-dist": {
"version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
+ "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
"license": "BlueOak-1.0.0"
},
"node_modules/parent-module": {
"version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6762,6 +9040,8 @@
},
"node_modules/parse-json": {
"version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
+ "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6779,6 +9059,8 @@
},
"node_modules/parse-ms": {
"version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-4.0.0.tgz",
+ "integrity": "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -6790,6 +9072,8 @@
},
"node_modules/parse5": {
"version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz",
+ "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6801,6 +9085,8 @@
},
"node_modules/parse5-htmlparser2-tree-adapter": {
"version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz",
+ "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6813,6 +9099,8 @@
},
"node_modules/parse5-parser-stream": {
"version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz",
+ "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6824,6 +9112,8 @@
},
"node_modules/parse5/node_modules/entities": {
"version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz",
+ "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==",
"dev": true,
"license": "BSD-2-Clause",
"engines": {
@@ -6835,6 +9125,8 @@
},
"node_modules/path-exists": {
"version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+ "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -6843,6 +9135,8 @@
},
"node_modules/path-expression-matcher": {
"version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.5.0.tgz",
+ "integrity": "sha512-cbrerZV+6rvdQrrD+iGMcZFEiiSrbv9Tfdkvnusy6y0x0GKBXREFg/Y65GhIfm0tnLntThhzCnfKwp1WRjeCyQ==",
"dev": true,
"funding": [
{
@@ -6857,6 +9151,8 @@
},
"node_modules/path-is-absolute": {
"version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -6865,6 +9161,8 @@
},
"node_modules/path-key": {
"version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
"license": "MIT",
"engines": {
"node": ">=8"
@@ -6872,6 +9170,8 @@
},
"node_modules/path-scurry": {
"version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
+ "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
"license": "BlueOak-1.0.0",
"dependencies": {
"lru-cache": "^10.2.0",
@@ -6884,8 +9184,16 @@
"url": "https://github.com/sponsors/isaacs"
}
},
+ "node_modules/path-scurry/node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
+ "license": "ISC"
+ },
"node_modules/path-to-regexp": {
"version": "8.4.2",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz",
+ "integrity": "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==",
"dev": true,
"license": "MIT",
"funding": {
@@ -6895,6 +9203,8 @@
},
"node_modules/path-type": {
"version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -6903,16 +9213,22 @@
},
"node_modules/pathe": {
"version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
+ "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
"dev": true,
"license": "MIT"
},
"node_modules/picocolors": {
"version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
"dev": true,
"license": "ISC"
},
"node_modules/picomatch": {
"version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz",
+ "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -6924,6 +9240,8 @@
},
"node_modules/postcss": {
"version": "8.5.15",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz",
+ "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==",
"dev": true,
"funding": [
{
@@ -6951,6 +9269,8 @@
},
"node_modules/pretty": {
"version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/pretty/-/pretty-2.0.0.tgz",
+ "integrity": "sha512-G9xUchgTEiNpormdYBl+Pha50gOUovT18IvAe7EYMZ1/f9W/WWMPRn+xI68yXNMUk3QXHDwo/1wV/4NejVNe1w==",
"license": "MIT",
"dependencies": {
"condense-newlines": "^0.2.1",
@@ -6963,6 +9283,8 @@
},
"node_modules/pretty-ms": {
"version": "9.3.0",
+ "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.3.0.tgz",
+ "integrity": "sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6977,11 +9299,15 @@
},
"node_modules/prism-svelte": {
"version": "0.4.7",
+ "resolved": "https://registry.npmjs.org/prism-svelte/-/prism-svelte-0.4.7.tgz",
+ "integrity": "sha512-yABh19CYbM24V7aS7TuPYRNMqthxwbvx6FF/Rw920YbyBWO3tnyPIqRMgHuSVsLmuHkkBS1Akyof463FVdkeDQ==",
"dev": true,
"license": "MIT"
},
"node_modules/prismjs": {
"version": "1.30.0",
+ "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz",
+ "integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==",
"license": "MIT",
"engines": {
"node": ">=6"
@@ -6989,6 +9315,8 @@
},
"node_modules/progress": {
"version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
+ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -6997,10 +9325,14 @@
},
"node_modules/proto-list": {
"version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
+ "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==",
"license": "ISC"
},
"node_modules/protobufjs": {
- "version": "8.4.1",
+ "version": "8.5.0",
+ "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-8.5.0.tgz",
+ "integrity": "sha512-df1jWDPA5VIBNRtuAHjqr09f2qN5D4Vke1wYqOQg1XJ7ZDpA7BD6L7E4tyChgGRLB5hqk2m79Zsy0WHwV9a84A==",
"dev": true,
"hasInstallScript": true,
"license": "BSD-3-Clause",
@@ -7013,6 +9345,8 @@
},
"node_modules/pure-rand": {
"version": "8.4.0",
+ "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-8.4.0.tgz",
+ "integrity": "sha512-IoM8YF/jY0hiugFo/wOWqfmarlE6J0wc6fDK1PhftMk7MGhVZl88sZimmqBBFomLOCSmcCCpsfj7wXASCpvK9A==",
"dev": true,
"funding": [
{
@@ -7028,6 +9362,8 @@
},
"node_modules/qs": {
"version": "6.15.2",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.2.tgz",
+ "integrity": "sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
@@ -7042,6 +9378,8 @@
},
"node_modules/queue-microtask": {
"version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
"dev": true,
"funding": [
{
@@ -7061,10 +9399,14 @@
},
"node_modules/railroad-diagrams": {
"version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz",
+ "integrity": "sha512-cz93DjNeLY0idrCNOH6PviZGRN9GJhsdm9hpn1YCS879fj4W+x5IFJhhkRZcwVgMmFF7R82UA/7Oh+R8lLZg6A==",
"license": "CC0-1.0"
},
"node_modules/randexp": {
"version": "0.4.6",
+ "resolved": "https://registry.npmjs.org/randexp/-/randexp-0.4.6.tgz",
+ "integrity": "sha512-80WNmd9DA0tmZrw9qQa62GPPWfuXJknrmVmLcxvq4uZBdYqb1wYoKTmnlGUchvVWe0XiLupYkBoXVOxz3C8DYQ==",
"license": "MIT",
"dependencies": {
"discontinuous-range": "1.0.0",
@@ -7076,6 +9418,8 @@
},
"node_modules/readable-stream": {
"version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -7089,6 +9433,8 @@
},
"node_modules/redos-detector": {
"version": "6.1.4",
+ "resolved": "https://registry.npmjs.org/redos-detector/-/redos-detector-6.1.4.tgz",
+ "integrity": "sha512-lPlka1rEH6kK42gtgokvvxMmpAvyc28DcRjQbGxeP5RJsJWgAduBOdGedVCDPdSyCr4ay/JDxq3nGYsJZyt8tA==",
"license": "MIT",
"dependencies": {
"regjsparser": "0.13.0"
@@ -7102,6 +9448,8 @@
},
"node_modules/regexparam": {
"version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/regexparam/-/regexparam-3.0.0.tgz",
+ "integrity": "sha512-RSYAtP31mvYLkAHrOlh25pCNQ5hWnT106VukGaaFfuJrZFkGRX5GhUAdPqpSDXxOhA2c4akmRuplv1mRqnBn6Q==",
"dev": true,
"license": "MIT",
"engines": {
@@ -7110,6 +9458,8 @@
},
"node_modules/regjsparser": {
"version": "0.13.0",
+ "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.13.0.tgz",
+ "integrity": "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q==",
"license": "BSD-2-Clause",
"dependencies": {
"jsesc": "~3.1.0"
@@ -7120,6 +9470,8 @@
},
"node_modules/require-directory": {
"version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
"dev": true,
"license": "MIT",
"engines": {
@@ -7128,6 +9480,8 @@
},
"node_modules/require-from-string": {
"version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
@@ -7135,11 +9489,15 @@
},
"node_modules/require-main-filename": {
"version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
+ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
"dev": true,
"license": "ISC"
},
"node_modules/resolve-from": {
"version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -7148,6 +9506,8 @@
},
"node_modules/ret": {
"version": "0.1.15",
+ "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
+ "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
"license": "MIT",
"engines": {
"node": ">=0.12"
@@ -7155,6 +9515,8 @@
},
"node_modules/reusify": {
"version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
+ "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -7163,11 +9525,13 @@
}
},
"node_modules/rolldown": {
- "version": "1.0.2",
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.3.tgz",
+ "integrity": "sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@oxc-project/types": "=0.132.0",
+ "@oxc-project/types": "=0.133.0",
"@rolldown/pluginutils": "^1.0.0"
},
"bin": {
@@ -7177,25 +9541,87 @@
"node": "^20.19.0 || >=22.12.0"
},
"optionalDependencies": {
- "@rolldown/binding-android-arm64": "1.0.2",
- "@rolldown/binding-darwin-arm64": "1.0.2",
- "@rolldown/binding-darwin-x64": "1.0.2",
- "@rolldown/binding-freebsd-x64": "1.0.2",
- "@rolldown/binding-linux-arm-gnueabihf": "1.0.2",
- "@rolldown/binding-linux-arm64-gnu": "1.0.2",
- "@rolldown/binding-linux-arm64-musl": "1.0.2",
- "@rolldown/binding-linux-ppc64-gnu": "1.0.2",
- "@rolldown/binding-linux-s390x-gnu": "1.0.2",
- "@rolldown/binding-linux-x64-gnu": "1.0.2",
- "@rolldown/binding-linux-x64-musl": "1.0.2",
- "@rolldown/binding-openharmony-arm64": "1.0.2",
- "@rolldown/binding-wasm32-wasi": "1.0.2",
- "@rolldown/binding-win32-arm64-msvc": "1.0.2",
- "@rolldown/binding-win32-x64-msvc": "1.0.2"
+ "@rolldown/binding-android-arm64": "1.0.3",
+ "@rolldown/binding-darwin-arm64": "1.0.3",
+ "@rolldown/binding-darwin-x64": "1.0.3",
+ "@rolldown/binding-freebsd-x64": "1.0.3",
+ "@rolldown/binding-linux-arm-gnueabihf": "1.0.3",
+ "@rolldown/binding-linux-arm64-gnu": "1.0.3",
+ "@rolldown/binding-linux-arm64-musl": "1.0.3",
+ "@rolldown/binding-linux-ppc64-gnu": "1.0.3",
+ "@rolldown/binding-linux-s390x-gnu": "1.0.3",
+ "@rolldown/binding-linux-x64-gnu": "1.0.3",
+ "@rolldown/binding-linux-x64-musl": "1.0.3",
+ "@rolldown/binding-openharmony-arm64": "1.0.3",
+ "@rolldown/binding-wasm32-wasi": "1.0.3",
+ "@rolldown/binding-win32-arm64-msvc": "1.0.3",
+ "@rolldown/binding-win32-x64-msvc": "1.0.3"
+ }
+ },
+ "node_modules/rosie-skills": {
+ "version": "0.6.4",
+ "resolved": "https://registry.npmjs.org/rosie-skills/-/rosie-skills-0.6.4.tgz",
+ "integrity": "sha512-ojfhSiQRdZ2QyWbmKAHOSAUbaLYrTc5zIH7mS1jKoP8KCFSQddwVhMyFqldckTeybTfW3zNcsZzyOTzGTN1SBA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "bin": {
+ "rosie-skills": "dist/bin.js"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "optionalDependencies": {
+ "rosie-skills-darwin-arm64": "0.6.4",
+ "rosie-skills-freebsd-x64": "0.6.4",
+ "rosie-skills-linux-x64": "0.6.4"
}
},
+ "node_modules/rosie-skills-darwin-arm64": {
+ "version": "0.6.4",
+ "resolved": "https://registry.npmjs.org/rosie-skills-darwin-arm64/-/rosie-skills-darwin-arm64-0.6.4.tgz",
+ "integrity": "sha512-rn1s5hqFKcxeiDEWWoFa1hdGPshR8TkwHLzy/cBavb9XJNAaUxbe3oQ78W9sQkRHAgRyzJYyk9tw68Qrdnizgg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/rosie-skills-freebsd-x64": {
+ "version": "0.6.4",
+ "resolved": "https://registry.npmjs.org/rosie-skills-freebsd-x64/-/rosie-skills-freebsd-x64-0.6.4.tgz",
+ "integrity": "sha512-SxCRduPBMtfjkQ+q56Yw9OLA3PyaqoALzt7kER7IDKuUVfM2O/1w8sa5xhTDiCvWkZJixnH5d5Ya6KT+/Mwcng==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/rosie-skills-linux-x64": {
+ "version": "0.6.4",
+ "resolved": "https://registry.npmjs.org/rosie-skills-linux-x64/-/rosie-skills-linux-x64-0.6.4.tgz",
+ "integrity": "sha512-D9Y9mfu7goB0s0X59uU3hcFeUTef3VbpCIDwFMzyvJrAq3XhRACWBDMHQsHlyWdHxTXPX/ILyW65RXyrJlgqng==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
"node_modules/run-parallel": {
"version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
"dev": true,
"funding": [
{
@@ -7218,6 +9644,8 @@
},
"node_modules/rxjs": {
"version": "7.8.2",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz",
+ "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -7226,6 +9654,8 @@
},
"node_modules/safe-buffer": {
"version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
"dev": true,
"funding": [
{
@@ -7245,10 +9675,14 @@
},
"node_modules/safer-buffer": {
"version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
"license": "MIT"
},
"node_modules/sast-json-schema": {
"version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/sast-json-schema/-/sast-json-schema-0.4.1.tgz",
+ "integrity": "sha512-GnOPf8rCTfysRtOzCJPoBZu8xKnY4LZ24jxCmcxsLUkmOTpK/DrbrJ97Xio4xkIH6USdzEZ5ZSdpTX8Gj03EuQ==",
"license": "MIT",
"workspaces": [
".github"
@@ -7270,6 +9704,8 @@
},
"node_modules/sax": {
"version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/sax/-/sax-1.6.0.tgz",
+ "integrity": "sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==",
"dev": true,
"license": "BlueOak-1.0.0",
"engines": {
@@ -7278,11 +9714,15 @@
},
"node_modules/seedrandom": {
"version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz",
+ "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==",
"dev": true,
"license": "MIT"
},
"node_modules/semver": {
"version": "7.8.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.1.tgz",
+ "integrity": "sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==",
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
@@ -7293,16 +9733,22 @@
},
"node_modules/set-blocking": {
"version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+ "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==",
"dev": true,
"license": "ISC"
},
"node_modules/set-cookie-parser": {
"version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-3.1.0.tgz",
+ "integrity": "sha512-kjnC1DXBHcxaOaOXBHBeRtltsDG2nUiUni+jP92M9gYdW12rsmx92UsfpH7o5tDRs7I1ZZPSQJQGv3UaRfCiuw==",
"dev": true,
"license": "MIT"
},
"node_modules/sharp": {
"version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz",
+ "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==",
"dev": true,
"hasInstallScript": true,
"license": "Apache-2.0",
@@ -7346,6 +9792,8 @@
},
"node_modules/shebang-command": {
"version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
"license": "MIT",
"dependencies": {
"shebang-regex": "^3.0.0"
@@ -7356,6 +9804,8 @@
},
"node_modules/shebang-regex": {
"version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
"license": "MIT",
"engines": {
"node": ">=8"
@@ -7363,6 +9813,8 @@
},
"node_modules/side-channel": {
"version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
+ "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -7381,6 +9833,8 @@
},
"node_modules/side-channel-list": {
"version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz",
+ "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -7396,6 +9850,8 @@
},
"node_modules/side-channel-map": {
"version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
+ "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -7413,6 +9869,8 @@
},
"node_modules/side-channel-weakmap": {
"version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
+ "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -7431,6 +9889,8 @@
},
"node_modules/signal-exit": {
"version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
+ "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
"license": "ISC",
"engines": {
"node": ">=14"
@@ -7441,6 +9901,8 @@
},
"node_modules/sinon": {
"version": "18.0.1",
+ "resolved": "https://registry.npmjs.org/sinon/-/sinon-18.0.1.tgz",
+ "integrity": "sha512-a2N2TDY1uGviajJ6r4D1CyRAkzE9NNVlYOV1wX5xQDuAk0ONgzgRl0EjCQuRCPxOwp13ghsMwt9Gdldujs39qw==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
@@ -7458,6 +9920,8 @@
},
"node_modules/sirv": {
"version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.2.tgz",
+ "integrity": "sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -7471,6 +9935,8 @@
},
"node_modules/slash": {
"version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
"dev": true,
"license": "MIT",
"engines": {
@@ -7479,6 +9945,8 @@
},
"node_modules/smtp-address-parser": {
"version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/smtp-address-parser/-/smtp-address-parser-1.1.0.tgz",
+ "integrity": "sha512-Gz11jbNU0plrReU9Sj7fmshSBxxJ9ShdD2q4ktHIHo/rpTH6lFyQoYHYKINPJtPe8aHFnsbtW46Ls0tCCBsIZg==",
"license": "MIT",
"dependencies": {
"nearley": "^2.20.1"
@@ -7489,6 +9957,8 @@
},
"node_modules/source-map": {
"version": "0.7.6",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz",
+ "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==",
"dev": true,
"license": "BSD-3-Clause",
"engines": {
@@ -7497,6 +9967,8 @@
},
"node_modules/source-map-js": {
"version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
"dev": true,
"license": "BSD-3-Clause",
"engines": {
@@ -7505,11 +9977,15 @@
},
"node_modules/sprintf-js": {
"version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
"dev": true,
"license": "BSD-3-Clause"
},
"node_modules/stream-browserify": {
"version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz",
+ "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -7519,6 +9995,8 @@
},
"node_modules/string_decoder": {
"version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -7527,6 +10005,8 @@
},
"node_modules/string-width": {
"version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz",
+ "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -7544,6 +10024,8 @@
"node_modules/string-width-cjs": {
"name": "string-width",
"version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"license": "MIT",
"dependencies": {
"emoji-regex": "^8.0.0",
@@ -7556,6 +10038,8 @@
},
"node_modules/string-width-cjs/node_modules/ansi-regex": {
"version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
"license": "MIT",
"engines": {
"node": ">=8"
@@ -7563,10 +10047,14 @@
},
"node_modules/string-width-cjs/node_modules/emoji-regex": {
"version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"license": "MIT"
},
"node_modules/string-width-cjs/node_modules/strip-ansi": {
"version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"license": "MIT",
"dependencies": {
"ansi-regex": "^5.0.1"
@@ -7577,6 +10065,8 @@
},
"node_modules/strip-ansi": {
"version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz",
+ "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==",
"license": "MIT",
"dependencies": {
"ansi-regex": "^6.2.2"
@@ -7591,6 +10081,8 @@
"node_modules/strip-ansi-cjs": {
"name": "strip-ansi",
"version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"license": "MIT",
"dependencies": {
"ansi-regex": "^5.0.1"
@@ -7601,6 +10093,8 @@
},
"node_modules/strip-ansi-cjs/node_modules/ansi-regex": {
"version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
"license": "MIT",
"engines": {
"node": ">=8"
@@ -7608,6 +10102,8 @@
},
"node_modules/strip-final-newline": {
"version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-4.0.0.tgz",
+ "integrity": "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -7619,6 +10115,8 @@
},
"node_modules/strnum": {
"version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.3.0.tgz",
+ "integrity": "sha512-ums3KNd42PGyx5xaoVTO1mjU1bH3NpY4vsrVlnv9PNGqQj8wd7rJ6nEypLrJ7z5vxK5RP0yMLo6J/Gsm62DI5Q==",
"dev": true,
"funding": [
{
@@ -7630,6 +10128,8 @@
},
"node_modules/supports-color": {
"version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"license": "MIT",
"dependencies": {
"has-flag": "^4.0.0"
@@ -7639,7 +10139,9 @@
}
},
"node_modules/svelte": {
- "version": "5.55.9",
+ "version": "5.56.0",
+ "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.56.0.tgz",
+ "integrity": "sha512-kTXr26t1bchFp28ROrb957LtbujpBmBDibmqMGziVpUs7awBi96TGgX6SovrA8BNoEUDVRK2Fb9FkeYlGspoVg==",
"license": "MIT",
"dependencies": {
"@jridgewell/remapping": "^2.3.4",
@@ -7665,6 +10167,8 @@
},
"node_modules/svgo": {
"version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/svgo/-/svgo-4.0.1.tgz",
+ "integrity": "sha512-XDpWUOPC6FEibaLzjfe0ucaV0YrOjYotGJO1WpF0Zd+n6ZGEQUsSugaoLq9QkEZtAfQIxT42UChcssDVPP3+/w==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -7689,6 +10193,8 @@
},
"node_modules/svgo/node_modules/commander": {
"version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz",
+ "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -7697,6 +10203,8 @@
},
"node_modules/table-layout": {
"version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-4.1.1.tgz",
+ "integrity": "sha512-iK5/YhZxq5GO5z8wb0bY1317uDF3Zjpha0QFFLA8/trAoiLbQD0HUbMesEaxyzUgDxi2QlcbM8IvqOlEjgoXBA==",
"license": "MIT",
"dependencies": {
"array-back": "^6.2.2",
@@ -7708,11 +10216,15 @@
},
"node_modules/tiny-emitter": {
"version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz",
+ "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==",
"dev": true,
"license": "MIT"
},
"node_modules/tinybench": {
"version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-6.0.2.tgz",
+ "integrity": "sha512-FlHoQpcFvCzeXK5kVPvV7IVgW/hs/B36QWTz876iSdeJguBDfdTSRQmYmaHX+fQNt4hp+gEFB2XXw+8hT4/y8A==",
"dev": true,
"license": "MIT",
"engines": {
@@ -7720,7 +10232,9 @@
}
},
"node_modules/tinyexec": {
- "version": "1.1.2",
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.2.4.tgz",
+ "integrity": "sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -7728,7 +10242,9 @@
}
},
"node_modules/tinyglobby": {
- "version": "0.2.16",
+ "version": "0.2.17",
+ "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz",
+ "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -7744,6 +10260,8 @@
},
"node_modules/tinyglobby/node_modules/fdir": {
"version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
+ "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -7760,6 +10278,8 @@
},
"node_modules/tinyglobby/node_modules/picomatch": {
"version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
+ "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
"dev": true,
"license": "MIT",
"engines": {
@@ -7771,10 +10291,14 @@
},
"node_modules/tinykeys": {
"version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/tinykeys/-/tinykeys-3.0.0.tgz",
+ "integrity": "sha512-nazawuGv5zx6MuDfDY0rmfXjuOGhD5XU2z0GLURQ1nzl0RUe9OuCJq+0u8xxJZINHe+mr7nw8PWYYZ9WhMFujw==",
"license": "MIT"
},
"node_modules/to-regex-range": {
"version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -7786,6 +10310,8 @@
},
"node_modules/totalist": {
"version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz",
+ "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -7794,11 +10320,15 @@
},
"node_modules/tr46": {
"version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
"dev": true,
"license": "MIT"
},
"node_modules/tree-kill": {
"version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz",
+ "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==",
"dev": true,
"license": "MIT",
"bin": {
@@ -7807,17 +10337,21 @@
},
"node_modules/tslib": {
"version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
"license": "0BSD"
},
"node_modules/tstyche": {
- "version": "7.1.0",
+ "version": "7.2.1",
+ "resolved": "https://registry.npmjs.org/tstyche/-/tstyche-7.2.1.tgz",
+ "integrity": "sha512-XMaaGk8Mrv+LMULdaK2H8jix1dLvKAi9lO/HTZZuK/tV0H3pD/9nCuCTIsHotpZ3VScOzv8ZGT2/6UvdSxzHgw==",
"dev": true,
"license": "MIT",
"bin": {
"tstyche": "dist/bin.js"
},
"engines": {
- "node": ">=22.12"
+ "node": ">=22"
},
"funding": {
"url": "https://github.com/tstyche/tstyche?sponsor=1"
@@ -7833,6 +10367,8 @@
},
"node_modules/tunnel": {
"version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
+ "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -7841,6 +10377,8 @@
},
"node_modules/type-detect": {
"version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
+ "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
"dev": true,
"license": "MIT",
"engines": {
@@ -7849,6 +10387,8 @@
},
"node_modules/typed-function": {
"version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/typed-function/-/typed-function-4.2.2.tgz",
+ "integrity": "sha512-VwaXim9Gp1bngi/q3do8hgttYn2uC3MoT/gfuMWylnj1IeZBUAyPddHZlo1K05BDoj8DYPpMdiHqH1dDYdJf2A==",
"dev": true,
"license": "MIT",
"engines": {
@@ -7857,6 +10397,8 @@
},
"node_modules/typed-inject": {
"version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/typed-inject/-/typed-inject-5.0.0.tgz",
+ "integrity": "sha512-0Ql2ORqBORLMdAW89TQKZsb1PQkFGImFfVmncXWe7a+AA3+7dh7Se9exxZowH4kbnlvKEFkMxUYdHUpjYWFJaA==",
"dev": true,
"license": "Apache-2.0",
"engines": {
@@ -7865,6 +10407,8 @@
},
"node_modules/typed-rest-client": {
"version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-2.3.1.tgz",
+ "integrity": "sha512-k4kX5Up6qA68D0Cby2AK+6+vM5k3qTxe+/3FqhnHRExjY5cfbOnzjQZbP/LXleF8hVoDvDqxlgk9KK83HoBZlQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -7880,6 +10424,8 @@
},
"node_modules/typescript": {
"version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz",
+ "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==",
"dev": true,
"license": "Apache-2.0",
"peer": true,
@@ -7893,6 +10439,8 @@
},
"node_modules/typical": {
"version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/typical/-/typical-7.3.0.tgz",
+ "integrity": "sha512-ya4mg/30vm+DOWfBg4YK3j2WD6TWtRkCbasOJr40CseYENzCUby/7rIvXA99JGsQHeNxLbnXdyLLxKSv3tauFw==",
"license": "MIT",
"engines": {
"node": ">=12.17"
@@ -7900,11 +10448,15 @@
},
"node_modules/underscore": {
"version": "1.13.8",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.8.tgz",
+ "integrity": "sha512-DXtD3ZtEQzc7M8m4cXotyHR+FAS18C64asBYY5vqZexfYryNNnDc02W4hKg3rdQuqOYas1jkseX0+nZXjTXnvQ==",
"dev": true,
"license": "MIT"
},
"node_modules/undici": {
"version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/undici/-/undici-8.3.0.tgz",
+ "integrity": "sha512-TkUDgb6tl7KOGZ+7e8E3d2FYgUQgF6z5YypqjWmixVQSQERFcVrVg0ySADm2LVLRh5ljAaHTCR5Fmz3Q34rB7Q==",
"dev": true,
"license": "MIT",
"engines": {
@@ -7913,11 +10465,15 @@
},
"node_modules/undici-types": {
"version": "7.24.6",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz",
+ "integrity": "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==",
"dev": true,
"license": "MIT"
},
"node_modules/unenv": {
"version": "2.0.0-rc.24",
+ "resolved": "https://registry.npmjs.org/unenv/-/unenv-2.0.0-rc.24.tgz",
+ "integrity": "sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -7926,6 +10482,8 @@
},
"node_modules/unicorn-magic": {
"version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz",
+ "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -7937,6 +10495,8 @@
},
"node_modules/unist-util-is": {
"version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz",
+ "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==",
"dev": true,
"license": "MIT",
"funding": {
@@ -7946,6 +10506,8 @@
},
"node_modules/unist-util-stringify-position": {
"version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz",
+ "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -7958,11 +10520,15 @@
},
"node_modules/unist-util-stringify-position/node_modules/@types/unist": {
"version": "2.0.11",
+ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz",
+ "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==",
"dev": true,
"license": "MIT"
},
"node_modules/unist-util-visit": {
"version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz",
+ "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -7977,6 +10543,8 @@
},
"node_modules/unist-util-visit-parents": {
"version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz",
+ "integrity": "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -7990,16 +10558,22 @@
},
"node_modules/unist-util-visit-parents/node_modules/@types/unist": {
"version": "2.0.11",
+ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz",
+ "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==",
"dev": true,
"license": "MIT"
},
"node_modules/unist-util-visit/node_modules/@types/unist": {
"version": "2.0.11",
+ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz",
+ "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==",
"dev": true,
"license": "MIT"
},
"node_modules/universalify": {
"version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
+ "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -8008,6 +10582,8 @@
},
"node_modules/update-browserslist-db": {
"version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz",
+ "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==",
"dev": true,
"funding": [
{
@@ -8037,15 +10613,21 @@
},
"node_modules/uri-js-replace": {
"version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/uri-js-replace/-/uri-js-replace-1.0.1.tgz",
+ "integrity": "sha512-W+C9NWNLFOoBI2QWDp4UT9pv65r2w5Cx+3sTYFvtMdDBxkKt1syCqsUdSFAChbEe1uK5TfS04wt/nGwmaeIQ0g==",
"license": "MIT"
},
"node_modules/util-deprecate": {
"version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
"dev": true,
"license": "MIT"
},
"node_modules/uuid": {
"version": "14.0.0",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-14.0.0.tgz",
+ "integrity": "sha512-Qo+uWgilfSmAhXCMav1uYFynlQO7fMFiMVZsQqZRMIXp0O7rR7qjkj+cPvBHLgBqi960QCoo/PH2/6ZtVqKvrg==",
"funding": [
"https://github.com/sponsors/broofa",
"https://github.com/sponsors/ctavan"
@@ -8057,6 +10639,8 @@
},
"node_modules/vfile-message": {
"version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz",
+ "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -8070,19 +10654,23 @@
},
"node_modules/vfile-message/node_modules/@types/unist": {
"version": "2.0.11",
+ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz",
+ "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==",
"dev": true,
"license": "MIT"
},
"node_modules/vite": {
- "version": "8.0.14",
+ "version": "8.0.16",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.16.tgz",
+ "integrity": "sha512-h9bXPmJichP5fLmVQo3PyaGSDE2n3aPuomeAlVRm0JLmt4rY6zmPKd59HYI4LNW8oTK7tlTsuC7l/m7awx9Jcw==",
"dev": true,
"license": "MIT",
"dependencies": {
"lightningcss": "^1.32.0",
"picomatch": "^4.0.4",
"postcss": "^8.5.15",
- "rolldown": "1.0.2",
- "tinyglobby": "^0.2.16"
+ "rolldown": "1.0.3",
+ "tinyglobby": "^0.2.17"
},
"bin": {
"vite": "bin/vite.js"
@@ -8151,6 +10739,8 @@
},
"node_modules/vite-plugin-llms": {
"version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/vite-plugin-llms/-/vite-plugin-llms-1.0.2.tgz",
+ "integrity": "sha512-MLO/9nUSpwCKkjip88cseLihIxhOpHc3GzOrNfbUPS+xp7hbBfPF0LgauyYfTJfPT/GcCPVEqrsy3MQ9JUv+MQ==",
"dev": true,
"license": "MIT",
"peerDependencies": {
@@ -8159,6 +10749,8 @@
},
"node_modules/vite-plugin-mkcert": {
"version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/vite-plugin-mkcert/-/vite-plugin-mkcert-2.0.0.tgz",
+ "integrity": "sha512-+5roXeOT91WRO3NKFRcDZKEHhze/1uahSSKOIq3vz2w19mJojBcyOo0JyLRHbME31Ym5qPRNJ8CwKO0mu4RJ2Q==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -8175,6 +10767,8 @@
},
"node_modules/vite-plugin-mkcert/node_modules/supports-color": {
"version": "10.2.2",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-10.2.2.tgz",
+ "integrity": "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==",
"dev": true,
"license": "MIT",
"engines": {
@@ -8186,10 +10780,14 @@
},
"node_modules/vite-plugin-sitemap": {
"version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/vite-plugin-sitemap/-/vite-plugin-sitemap-0.8.2.tgz",
+ "integrity": "sha512-bqIw6NVOXg6je81lzX8Lm0vjf8/QSAp8di8fYQzZ3ZdVicOm8+6idBGALJiy1R1FiXNIK8rgORO6HBqXyHW+iQ==",
"dev": true
},
"node_modules/vite-plugin-sri": {
"version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/vite-plugin-sri/-/vite-plugin-sri-0.0.2.tgz",
+ "integrity": "sha512-oTpYWvS9xmwee3kK39cr8p2KbQ+/HzOG0bxo0dzMogJ4lR11favOzrapwb2eASVt5rX3LEzG25bEqoSY4CUniA==",
"dev": true,
"license": "ISC",
"dependencies": {
@@ -8199,6 +10797,8 @@
},
"node_modules/vite/node_modules/picomatch": {
"version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
+ "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
"dev": true,
"license": "MIT",
"engines": {
@@ -8210,6 +10810,8 @@
},
"node_modules/vitefu": {
"version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-1.1.3.tgz",
+ "integrity": "sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg==",
"dev": true,
"license": "MIT",
"workspaces": [
@@ -8228,16 +10830,23 @@
},
"node_modules/weapon-regex": {
"version": "1.3.6",
+ "resolved": "https://registry.npmjs.org/weapon-regex/-/weapon-regex-1.3.6.tgz",
+ "integrity": "sha512-wsf1m1jmMrso5nhwVFJJHSubEBf3+pereGd7+nBKtYJ18KoB/PWJOHS3WRkwS04VrOU0iJr2bZU+l1QaTJ+9nA==",
"dev": true,
"license": "Apache-2.0"
},
"node_modules/webidl-conversions": {
"version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
"dev": true,
"license": "BSD-2-Clause"
},
"node_modules/whatwg-encoding": {
"version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz",
+ "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==",
+ "deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -8249,6 +10858,8 @@
},
"node_modules/whatwg-encoding/node_modules/iconv-lite": {
"version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -8260,6 +10871,8 @@
},
"node_modules/whatwg-mimetype": {
"version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz",
+ "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -8268,6 +10881,8 @@
},
"node_modules/whatwg-url": {
"version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+ "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -8277,6 +10892,8 @@
},
"node_modules/which": {
"version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"license": "ISC",
"dependencies": {
"isexe": "^2.0.0"
@@ -8290,18 +10907,24 @@
},
"node_modules/which-module": {
"version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz",
+ "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==",
"dev": true,
"license": "ISC"
},
"node_modules/wordwrapjs": {
"version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-5.1.1.tgz",
+ "integrity": "sha512-0yweIbkINJodk27gX9LBGMzyQdBDan3s/dEAiwBOj+Mf0PPyWL6/rikalkv8EeD0E8jm4o5RXEOrFTP3NXbhJg==",
"license": "MIT",
"engines": {
"node": ">=12.17"
}
},
"node_modules/workerd": {
- "version": "1.20260520.1",
+ "version": "1.20260526.1",
+ "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20260526.1.tgz",
+ "integrity": "sha512-IHzymht98p10JH1zzwdCpbViAqw97HrwKl7+KfZeASFMsYSrIsAULWdPn0LRC5FTUzBpamLNyKCCKxbgXHgRHQ==",
"dev": true,
"hasInstallScript": true,
"license": "Apache-2.0",
@@ -8312,15 +10935,17 @@
"node": ">=16"
},
"optionalDependencies": {
- "@cloudflare/workerd-darwin-64": "1.20260520.1",
- "@cloudflare/workerd-darwin-arm64": "1.20260520.1",
- "@cloudflare/workerd-linux-64": "1.20260520.1",
- "@cloudflare/workerd-linux-arm64": "1.20260520.1",
- "@cloudflare/workerd-windows-64": "1.20260520.1"
+ "@cloudflare/workerd-darwin-64": "1.20260526.1",
+ "@cloudflare/workerd-darwin-arm64": "1.20260526.1",
+ "@cloudflare/workerd-linux-64": "1.20260526.1",
+ "@cloudflare/workerd-linux-arm64": "1.20260526.1",
+ "@cloudflare/workerd-windows-64": "1.20260526.1"
}
},
"node_modules/worktop": {
"version": "0.8.0-next.18",
+ "resolved": "https://registry.npmjs.org/worktop/-/worktop-0.8.0-next.18.tgz",
+ "integrity": "sha512-+TvsA6VAVoMC3XDKR5MoC/qlLqDixEfOBysDEKnPIPou/NvoPWCAuXHXMsswwlvmEuvX56lQjvELLyLuzTKvRw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -8332,7 +10957,9 @@
}
},
"node_modules/wrangler": {
- "version": "4.93.1",
+ "version": "4.95.0",
+ "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-4.95.0.tgz",
+ "integrity": "sha512-vgXzFVSCdUbeCadgVXvu8fK5tzNm8T9W+7lriyGWZMx0B1+CAdr4d8JTlZszHfgjypRAHmAxb49etZGIRD9pgg==",
"dev": true,
"license": "MIT OR Apache-2.0",
"dependencies": {
@@ -8340,10 +10967,11 @@
"@cloudflare/unenv-preset": "2.16.1",
"blake3-wasm": "2.1.5",
"esbuild": "0.27.3",
- "miniflare": "4.20260520.0",
+ "miniflare": "4.20260526.0",
"path-to-regexp": "6.3.0",
+ "rosie-skills": "^0.6.3",
"unenv": "2.0.0-rc.24",
- "workerd": "1.20260520.1"
+ "workerd": "1.20260526.1"
},
"bin": {
"wrangler": "bin/wrangler.js",
@@ -8356,7 +10984,7 @@
"fsevents": "~2.3.2"
},
"peerDependencies": {
- "@cloudflare/workers-types": "^4.20260520.1"
+ "@cloudflare/workers-types": "^4.20260526.1"
},
"peerDependenciesMeta": {
"@cloudflare/workers-types": {
@@ -8434,6 +11062,8 @@
},
"node_modules/wrangler/node_modules/@esbuild/darwin-arm64": {
"version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz",
+ "integrity": "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==",
"cpu": [
"arm64"
],
@@ -8806,6 +11436,8 @@
},
"node_modules/wrangler/node_modules/esbuild": {
"version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz",
+ "integrity": "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
@@ -8846,11 +11478,15 @@
},
"node_modules/wrangler/node_modules/path-to-regexp": {
"version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz",
+ "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==",
"dev": true,
"license": "MIT"
},
"node_modules/wrap-ansi": {
"version": "9.0.2",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz",
+ "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -8868,6 +11504,8 @@
"node_modules/wrap-ansi-cjs": {
"name": "wrap-ansi",
"version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
"license": "MIT",
"dependencies": {
"ansi-styles": "^4.0.0",
@@ -8883,6 +11521,8 @@
},
"node_modules/wrap-ansi-cjs/node_modules/ansi-regex": {
"version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
"license": "MIT",
"engines": {
"node": ">=8"
@@ -8890,6 +11530,8 @@
},
"node_modules/wrap-ansi-cjs/node_modules/ansi-styles": {
"version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"license": "MIT",
"dependencies": {
"color-convert": "^2.0.1"
@@ -8903,6 +11545,8 @@
},
"node_modules/wrap-ansi-cjs/node_modules/color-convert": {
"version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"license": "MIT",
"dependencies": {
"color-name": "~1.1.4"
@@ -8913,14 +11557,20 @@
},
"node_modules/wrap-ansi-cjs/node_modules/color-name": {
"version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"license": "MIT"
},
"node_modules/wrap-ansi-cjs/node_modules/emoji-regex": {
"version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"license": "MIT"
},
"node_modules/wrap-ansi-cjs/node_modules/string-width": {
"version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"license": "MIT",
"dependencies": {
"emoji-regex": "^8.0.0",
@@ -8933,6 +11583,8 @@
},
"node_modules/wrap-ansi-cjs/node_modules/strip-ansi": {
"version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"license": "MIT",
"dependencies": {
"ansi-regex": "^5.0.1"
@@ -8943,11 +11595,15 @@
},
"node_modules/wrappy": {
"version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
"dev": true,
"license": "ISC"
},
"node_modules/ws": {
"version": "8.20.1",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.1.tgz",
+ "integrity": "sha512-It4dO0K5v//JtTXuPkfEOaI3uUN87iYPnqo/ZzqCoG3g8uhA66QUMs/SrM0YK7/NAu+r4LMh/9dq2A7k+rHs+w==",
"dev": true,
"license": "MIT",
"engines": {
@@ -8968,6 +11624,8 @@
},
"node_modules/xml-naming": {
"version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/xml-naming/-/xml-naming-0.1.0.tgz",
+ "integrity": "sha512-k8KO9hrMyNk6tUWqUfkTEZbezRRpONVOzUTnc97VnCvyj6Tf9lyUR9EDAIeiVLv56jsMcoXEwjW8Kv5yPY52lw==",
"dev": true,
"funding": [
{
@@ -8982,6 +11640,8 @@
},
"node_modules/y18n": {
"version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
"dev": true,
"license": "ISC",
"engines": {
@@ -8990,11 +11650,15 @@
},
"node_modules/yallist": {
"version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
"dev": true,
"license": "ISC"
},
"node_modules/yargs": {
"version": "18.0.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.0.0.tgz",
+ "integrity": "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -9011,6 +11675,8 @@
},
"node_modules/yargs-parser": {
"version": "22.0.0",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz",
+ "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==",
"dev": true,
"license": "ISC",
"engines": {
@@ -9019,6 +11685,8 @@
},
"node_modules/yoctocolors": {
"version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.2.tgz",
+ "integrity": "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==",
"dev": true,
"license": "MIT",
"engines": {
@@ -9030,6 +11698,8 @@
},
"node_modules/youch": {
"version": "4.1.0-beta.10",
+ "resolved": "https://registry.npmjs.org/youch/-/youch-4.1.0-beta.10.tgz",
+ "integrity": "sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -9042,6 +11712,8 @@
},
"node_modules/youch-core": {
"version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/youch-core/-/youch-core-0.3.3.tgz",
+ "integrity": "sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -9051,6 +11723,8 @@
},
"node_modules/youch/node_modules/cookie": {
"version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz",
+ "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -9063,10 +11737,14 @@
},
"node_modules/zimmerframe": {
"version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/zimmerframe/-/zimmerframe-1.1.4.tgz",
+ "integrity": "sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==",
"license": "MIT"
},
"node_modules/zod": {
"version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz",
+ "integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==",
"dev": true,
"license": "MIT",
"funding": {
diff --git a/package.json b/package.json
index cd78975..90aa530 100644
--- a/package.json
+++ b/package.json
@@ -44,7 +44,7 @@
"rm:macos": "find . -name '.DS_Store' -type f -delete",
"rm:lock": "find . -name 'package-lock.json' -type f -delete",
"rm:node_modules": "find . -name 'node_modules' -type d -prune -exec rm -rf '{}' +",
- "update": "npm update --workspaces && npm install --workspaces",
+ "update": "corepack up && npm run rm && npm install --workspaces",
"outdated": "npm outdated --workspaces",
"audit": "npm audit fix --workspaces",
"release:license:add": "license-check-and-add add -f .license.config.json",
diff --git a/packages/aws/package.json b/packages/aws/package.json
index a222990..40dfcb4 100644
--- a/packages/aws/package.json
+++ b/packages/aws/package.json
@@ -156,8 +156,8 @@
"scripts": {
"test": "npm run test:unit",
"test:unit": "node --test --conditions=node",
- "test:mutation": "cd ../.. && MUTATE_PACKAGE=\"$(basename \"$OLDPWD\")\" stryker run",
- "test:benchmark": "node __benchmarks__/index.js"
+ "test:perf": "node --test index.perf.js",
+ "test:mutation": "cd ../.. && MUTATE_PACKAGE=\"$(basename \"$OLDPWD\")\" stryker run"
},
"license": "MIT",
"keywords": [
diff --git a/packages/base64/package.json b/packages/base64/package.json
index d293021..cf2f23a 100644
--- a/packages/base64/package.json
+++ b/packages/base64/package.json
@@ -39,8 +39,8 @@
"scripts": {
"test": "npm run test:unit",
"test:unit": "node --test",
- "test:mutation": "cd ../.. && MUTATE_PACKAGE=\"$(basename \"$OLDPWD\")\" stryker run",
- "test:benchmark": "node __benchmarks__/index.js"
+ "test:perf": "node --test index.perf.js",
+ "test:mutation": "cd ../.. && MUTATE_PACKAGE=\"$(basename \"$OLDPWD\")\" stryker run"
},
"license": "MIT",
"keywords": [
diff --git a/packages/charset/package.json b/packages/charset/package.json
index d3c2b48..bda3669 100644
--- a/packages/charset/package.json
+++ b/packages/charset/package.json
@@ -87,8 +87,8 @@
"scripts": {
"test": "npm run test:unit",
"test:unit": "node --test",
- "test:mutation": "cd ../.. && MUTATE_PACKAGE=\"$(basename \"$OLDPWD\")\" stryker run",
- "test:benchmark": "node __benchmarks__/index.js"
+ "test:perf": "node --test index.perf.js",
+ "test:mutation": "cd ../.. && MUTATE_PACKAGE=\"$(basename \"$OLDPWD\")\" stryker run"
},
"license": "MIT",
"keywords": [
diff --git a/packages/compress/package.json b/packages/compress/package.json
index 6842ac0..4b0c567 100644
--- a/packages/compress/package.json
+++ b/packages/compress/package.json
@@ -103,8 +103,8 @@
"scripts": {
"test": "npm run test:unit",
"test:unit": "node --test",
- "test:mutation": "cd ../.. && MUTATE_PACKAGE=\"$(basename \"$OLDPWD\")\" stryker run",
- "test:benchmark": "node __benchmarks__/index.js"
+ "test:perf": "node --test index.perf.js",
+ "test:mutation": "cd ../.. && MUTATE_PACKAGE=\"$(basename \"$OLDPWD\")\" stryker run"
},
"license": "MIT",
"keywords": [
diff --git a/packages/core/package.json b/packages/core/package.json
index af06b60..094a4ac 100644
--- a/packages/core/package.json
+++ b/packages/core/package.json
@@ -39,8 +39,8 @@
"scripts": {
"test": "npm run test:unit",
"test:unit": "node --test",
- "test:mutation": "cd ../.. && MUTATE_PACKAGE=\"$(basename \"$OLDPWD\")\" stryker run",
- "test:benchmark": "node __benchmarks__/index.js"
+ "test:perf": "node --test index.perf.js",
+ "test:mutation": "cd ../.. && MUTATE_PACKAGE=\"$(basename \"$OLDPWD\")\" stryker run"
},
"license": "MIT",
"keywords": [
diff --git a/packages/csv/package.json b/packages/csv/package.json
index 3484b60..272fe94 100644
--- a/packages/csv/package.json
+++ b/packages/csv/package.json
@@ -39,8 +39,8 @@
"scripts": {
"test": "npm run test:unit",
"test:unit": "node --test",
- "test:mutation": "cd ../.. && MUTATE_PACKAGE=\"$(basename \"$OLDPWD\")\" stryker run",
- "test:benchmark": "node __benchmarks__/index.js"
+ "test:perf": "node --test index.perf.js",
+ "test:mutation": "cd ../.. && MUTATE_PACKAGE=\"$(basename \"$OLDPWD\")\" stryker run"
},
"license": "MIT",
"keywords": [
diff --git a/packages/digest/package.json b/packages/digest/package.json
index 9dfdb83..34b109e 100644
--- a/packages/digest/package.json
+++ b/packages/digest/package.json
@@ -39,8 +39,8 @@
"scripts": {
"test": "npm run test:unit",
"test:unit": "node --test",
- "test:mutation": "cd ../.. && MUTATE_PACKAGE=\"$(basename \"$OLDPWD\")\" stryker run",
- "test:benchmark": "node __benchmarks__/index.js"
+ "test:perf": "node --test index.perf.js",
+ "test:mutation": "cd ../.. && MUTATE_PACKAGE=\"$(basename \"$OLDPWD\")\" stryker run"
},
"license": "MIT",
"keywords": [
diff --git a/packages/encrypt/index.node.js b/packages/encrypt/index.node.js
index 841dd1a..2bf7593 100644
--- a/packages/encrypt/index.node.js
+++ b/packages/encrypt/index.node.js
@@ -42,7 +42,7 @@ const validateIv = (iv, expectedSize, algorithm) => {
};
const validateAuthTag = (authTag, algorithm) => {
- if (!authTag || authTag.length !== 16) {
+ if (authTag?.length !== 16) {
throw new Error(
`authTag for ${algorithm} must be 16 bytes, got ${authTag?.length ?? 0}`,
);
diff --git a/packages/encrypt/index.web.js b/packages/encrypt/index.web.js
index 7af530d..05c8669 100644
--- a/packages/encrypt/index.web.js
+++ b/packages/encrypt/index.web.js
@@ -39,7 +39,7 @@ const validateIv = (iv, algorithm) => {
};
const validateAuthTag = (authTag, algorithm) => {
- if (!authTag || authTag.byteLength !== 16) {
+ if (authTag?.byteLength !== 16) {
throw new Error(
`authTag for ${algorithm} must be 16 bytes, got ${authTag?.byteLength ?? 0}`,
);
diff --git a/packages/encrypt/package.json b/packages/encrypt/package.json
index 0c5344f..9924185 100644
--- a/packages/encrypt/package.json
+++ b/packages/encrypt/package.json
@@ -39,7 +39,7 @@
"scripts": {
"test": "npm run test:unit",
"test:unit": "node --test",
- "test:benchmark": "node __benchmarks__/index.js"
+ "test:perf": "node --test index.perf.js"
},
"license": "MIT",
"keywords": [
diff --git a/packages/fetch/package.json b/packages/fetch/package.json
index 9bca4e1..e9cde0c 100644
--- a/packages/fetch/package.json
+++ b/packages/fetch/package.json
@@ -39,8 +39,8 @@
"scripts": {
"test": "npm run test:unit",
"test:unit": "node --test",
- "test:mutation": "cd ../.. && MUTATE_PACKAGE=\"$(basename \"$OLDPWD\")\" stryker run",
- "test:benchmark": "node __benchmarks__/index.js"
+ "test:perf": "node --test index.perf.js",
+ "test:mutation": "cd ../.. && MUTATE_PACKAGE=\"$(basename \"$OLDPWD\")\" stryker run"
},
"license": "MIT",
"keywords": [
diff --git a/packages/file/package.json b/packages/file/package.json
index 7567b05..bc27772 100644
--- a/packages/file/package.json
+++ b/packages/file/package.json
@@ -39,8 +39,8 @@
"scripts": {
"test": "npm run test:unit",
"test:unit": "node --test",
- "test:mutation": "cd ../.. && MUTATE_PACKAGE=\"$(basename \"$OLDPWD\")\" stryker run",
- "test:benchmark": "node __benchmarks__/index.js"
+ "test:perf": "node --test index.perf.js",
+ "test:mutation": "cd ../.. && MUTATE_PACKAGE=\"$(basename \"$OLDPWD\")\" stryker run"
},
"license": "MIT",
"keywords": [
diff --git a/packages/indexeddb/package.json b/packages/indexeddb/package.json
index de9137a..c2be39d 100644
--- a/packages/indexeddb/package.json
+++ b/packages/indexeddb/package.json
@@ -39,8 +39,8 @@
"scripts": {
"test": "npm run test:unit",
"test:unit": "node --test",
- "test:mutation": "cd ../.. && MUTATE_PACKAGE=\"$(basename \"$OLDPWD\")\" stryker run",
- "test:benchmark": "node __benchmarks__/index.js"
+ "test:perf": "node --test index.perf.js",
+ "test:mutation": "cd ../.. && MUTATE_PACKAGE=\"$(basename \"$OLDPWD\")\" stryker run"
},
"license": "MIT",
"keywords": [
diff --git a/packages/ipfs/package.json b/packages/ipfs/package.json
index db40ec6..a3b1988 100644
--- a/packages/ipfs/package.json
+++ b/packages/ipfs/package.json
@@ -39,8 +39,8 @@
"scripts": {
"test": "npm run test:unit",
"test:unit": "node --test",
- "test:mutation": "cd ../.. && MUTATE_PACKAGE=\"$(basename \"$OLDPWD\")\" stryker run",
- "test:benchmark": "node __benchmarks__/index.js"
+ "test:perf": "node --test index.perf.js",
+ "test:mutation": "cd ../.. && MUTATE_PACKAGE=\"$(basename \"$OLDPWD\")\" stryker run"
},
"license": "MIT",
"keywords": [
diff --git a/packages/json/package.json b/packages/json/package.json
index 88a50a6..66d4cc8 100644
--- a/packages/json/package.json
+++ b/packages/json/package.json
@@ -39,8 +39,8 @@
"scripts": {
"test": "npm run test:unit",
"test:unit": "node --test",
- "test:mutation": "cd ../.. && MUTATE_PACKAGE=\"$(basename \"$OLDPWD\")\" stryker run",
- "test:benchmark": "node __benchmarks__/index.js"
+ "test:perf": "node --test index.perf.js",
+ "test:mutation": "cd ../.. && MUTATE_PACKAGE=\"$(basename \"$OLDPWD\")\" stryker run"
},
"license": "MIT",
"keywords": [
diff --git a/packages/object/package.json b/packages/object/package.json
index ba8331b..497c70e 100644
--- a/packages/object/package.json
+++ b/packages/object/package.json
@@ -39,8 +39,8 @@
"scripts": {
"test": "npm run test:unit",
"test:unit": "node --test",
- "test:mutation": "cd ../.. && MUTATE_PACKAGE=\"$(basename \"$OLDPWD\")\" stryker run",
- "test:benchmark": "node __benchmarks__/index.js"
+ "test:perf": "node --test index.perf.js",
+ "test:mutation": "cd ../.. && MUTATE_PACKAGE=\"$(basename \"$OLDPWD\")\" stryker run"
},
"license": "MIT",
"keywords": [
diff --git a/packages/string/package.json b/packages/string/package.json
index de7d029..f5c495c 100644
--- a/packages/string/package.json
+++ b/packages/string/package.json
@@ -39,8 +39,8 @@
"scripts": {
"test": "npm run test:unit",
"test:unit": "node --test",
- "test:mutation": "cd ../.. && MUTATE_PACKAGE=\"$(basename \"$OLDPWD\")\" stryker run",
- "test:benchmark": "node __benchmarks__/index.js"
+ "test:perf": "node --test index.perf.js",
+ "test:mutation": "cd ../.. && MUTATE_PACKAGE=\"$(basename \"$OLDPWD\")\" stryker run"
},
"license": "MIT",
"keywords": [
diff --git a/packages/validate/package.json b/packages/validate/package.json
index 9447742..849633f 100644
--- a/packages/validate/package.json
+++ b/packages/validate/package.json
@@ -39,8 +39,8 @@
"scripts": {
"test": "npm run test:unit",
"test:unit": "node --test",
- "test:mutation": "cd ../.. && MUTATE_PACKAGE=\"$(basename \"$OLDPWD\")\" stryker run",
- "test:benchmark": "node __benchmarks__/index.js"
+ "test:perf": "node --test index.perf.js",
+ "test:mutation": "cd ../.. && MUTATE_PACKAGE=\"$(basename \"$OLDPWD\")\" stryker run"
},
"license": "MIT",
"keywords": [
diff --git a/websites/datastream.js.org/src/components/docs/AsideNav.svelte b/websites/datastream.js.org/src/components/docs/AsideNav.svelte
index 3d46123..8d941de 100644
--- a/websites/datastream.js.org/src/components/docs/AsideNav.svelte
+++ b/websites/datastream.js.org/src/components/docs/AsideNav.svelte
@@ -17,6 +17,8 @@ const nav = {
aws: "/docs/packages/aws",
indexeddb: "/docs/packages/indexeddb",
ipfs: "/docs/packages/ipfs",
+ kafka: "/docs/packages/kafka",
+ duckdb: "/docs/packages/duckdb",
},
"Data Formats": {
csv: "/docs/packages/csv",
@@ -25,6 +27,9 @@ const nav = {
object: "/docs/packages/object",
base64: "/docs/packages/base64",
charset: "/docs/packages/charset",
+ arrow: "/docs/packages/arrow",
+ protobuf: "/docs/packages/protobuf",
+ "schema-registry": "/docs/packages/schema-registry",
},
Processing: {
validate: "/docs/packages/validate",
diff --git a/websites/datastream.js.org/src/routes/+page.svelte b/websites/datastream.js.org/src/routes/+page.svelte
index 51d4580..91872bf 100644
--- a/websites/datastream.js.org/src/routes/+page.svelte
+++ b/websites/datastream.js.org/src/routes/+page.svelte
@@ -190,6 +190,26 @@ await pipeline(streams)`;
string
String streams, splitting, replacing, and counting.
+
+ arrow
+ Apache Arrow record batch transform streams.
+
+
+ duckdb
+ DuckDB writable streams for rows and Arrow batches.
+
+
+ kafka
+ Kafka producer and consumer streams.
+
+
+ protobuf
+ Protobuf encode, decode, and length-prefix framing.
+
+
+ schema-registry
+ Confluent and Glue Schema Registry framing.
+
From d259b292d47ea592a1b523f26eec7a188d7f9f1e Mon Sep 17 00:00:00 2001
From: will Farrell
Date: Thu, 11 Jun 2026 21:04:17 -0600
Subject: [PATCH 13/27] fix: pipe leaking upstream on error
Signed-off-by: will Farrell
---
packages/core/index.node.js | 37 ++++++++++------
packages/core/index.test.js | 85 +++++++++++++++++++++++++++++++++++++
2 files changed, 110 insertions(+), 12 deletions(-)
diff --git a/packages/core/index.node.js b/packages/core/index.node.js
index b1bf5c7..aba48e0 100644
--- a/packages/core/index.node.js
+++ b/packages/core/index.node.js
@@ -46,20 +46,33 @@ export const pipeline = async (streams, streamOptions = {}) => {
return result(streams);
};
-export const pipejoin = (
- streams,
- onError = (e) => {
- process.nextTick(() => {
- throw e;
- });
- },
-) => {
- const pipeline = streams.reduce((pipeline, stream, idx) => {
- if (typeof stream.then === "function") {
+export const pipejoin = (streams, onError) => {
+ for (let idx = 0, l = streams.length; idx < l; idx++) {
+ if (typeof streams[idx].then === "function") {
throw new Error(`Promise instead of stream passed in at index ${idx}`);
}
- return pipeline.pipe(stream).on("error", onError);
- });
+ }
+ let settled = false;
+ const teardown = (error) => {
+ if (settled) return;
+ settled = true;
+ for (const stream of streams) {
+ if (!stream.destroyed) stream.destroy(error);
+ }
+ if (onError) {
+ onError(error);
+ } else {
+ process.nextTick(() => {
+ throw error;
+ });
+ }
+ };
+ let pipeline = streams[0];
+ pipeline.on("error", teardown);
+ for (let idx = 1, l = streams.length; idx < l; idx++) {
+ pipeline = pipeline.pipe(streams[idx]);
+ pipeline.on("error", teardown);
+ }
return pipeline;
};
diff --git a/packages/core/index.test.js b/packages/core/index.test.js
index 2de9f00..838e4c1 100644
--- a/packages/core/index.test.js
+++ b/packages/core/index.test.js
@@ -2276,3 +2276,88 @@ test(`${variant}: createWritableStream propagates a rejecting async final`, asyn
strictEqual(e.message, "final-rejected");
}
});
+
+// ===========================================================================
+// *** Stream-leak resilience ***
+// Legacy `.pipe()` only tears a chain down on `finish`; when a stream errors
+// or a consumer closes early it leaves the upstream source running, producing
+// into a dead pipeline (the classic Node.js stream leak). pipejoin must mirror
+// what pipeline()/pipelinePromise does internally: destroy EVERY stream on the
+// first error so nothing is left running. pipeline() (pipelinePromise) already
+// does this; these tests pin both behaviours so neither can regress.
+// ===========================================================================
+
+if (variant === "node") {
+ // A mid-chain error must destroy the upstream source AND the downstream sink,
+ // not just the stream that threw. With bare `.pipe()` the source survives and
+ // keeps producing — the leak this guards against.
+ test(`${variant}: pipejoin destroys every stream when one errors (no upstream leak)`, async (_t) => {
+ const source = createReadableStream(["a", "b", "c"]);
+ const failing = createTransformStream(() => {
+ throw new Error("mid-failure");
+ });
+ const sink = createWritableStream();
+ // Swallow the error; we are asserting on teardown, not propagation here.
+ pipejoin([source, failing, sink], () => {});
+ await timeout(50);
+ strictEqual(source.destroyed, true, "source must be destroyed");
+ strictEqual(failing.destroyed, true, "failing transform must be destroyed");
+ strictEqual(sink.destroyed, true, "downstream sink must be destroyed");
+ });
+
+ // The error must still reach a collector consuming the joined stream, and the
+ // upstream source must be torn down rather than left producing.
+ test(`${variant}: pipejoin surfaces the error to a collector and tears the source down`, async (_t) => {
+ const source = createReadableStream(["a", "b", "c"]);
+ const failing = createTransformStream((chunk, enqueue) => {
+ if (chunk === "b") throw new Error("collector-failure");
+ enqueue(chunk);
+ });
+ const joined = pipejoin([source, failing], () => {});
+ try {
+ await withTimeout(streamToArray(joined));
+ throw new Error("Should have thrown");
+ } catch (e) {
+ strictEqual(e.message, "collector-failure");
+ }
+ strictEqual(source.destroyed, true, "source must be destroyed on error");
+ });
+
+ // A consumer that stops reading early (break out of the async iterator) must
+ // not leave the source running: the iterator protocol destroys the readable,
+ // and pipejoin's teardown must propagate that to every upstream stream.
+ test(`${variant}: pipejoin tears the source down when the consumer stops early`, async (_t) => {
+ const source = createReadableStream(["a", "b", "c", "d", "e"]);
+ const passThrough = createPassThroughStream((c) => c);
+ const joined = pipejoin([source, passThrough], () => {});
+ for await (const chunk of joined) {
+ if (chunk === "b") break; // early exit -> iterator destroys `joined`
+ }
+ await timeout(50);
+ strictEqual(joined.destroyed, true, "joined stream must be destroyed");
+ strictEqual(
+ source.destroyed,
+ true,
+ "source must be destroyed on early exit",
+ );
+ });
+
+ // Characterization: pipeline() (pipelinePromise) already destroys the whole
+ // chain on a mid-stream error. Pin it so the resilient teardown can't regress.
+ test(`${variant}: pipeline destroys the source when a transform errors`, async (_t) => {
+ const source = createReadableStream(["a", "b", "c"]);
+ const streams = [
+ source,
+ createTransformStream(() => {
+ throw new Error("pipeline-mid-failure");
+ }),
+ ];
+ try {
+ await withTimeout(pipeline(streams));
+ throw new Error("Should have thrown");
+ } catch (e) {
+ strictEqual(e.message, "pipeline-mid-failure");
+ }
+ strictEqual(source.destroyed, true, "pipeline must destroy the source");
+ });
+}
From 0b0055a6682ecb17690e486ca4a00e9a380cb7cb Mon Sep 17 00:00:00 2001
From: will Farrell
Date: Fri, 12 Jun 2026 11:46:47 -0600
Subject: [PATCH 14/27] fix: perf improvements
Signed-off-by: will Farrell
---
packages/aws/s3.js | 46 ++++++++++++++++++++++++++++++++-----------
packages/csv/index.js | 27 ++++++++++++++++---------
2 files changed, 53 insertions(+), 20 deletions(-)
diff --git a/packages/aws/s3.js b/packages/aws/s3.js
index 58eaf79..b5698fe 100644
--- a/packages/aws/s3.js
+++ b/packages/aws/s3.js
@@ -93,26 +93,50 @@ export const awsS3ChecksumStream = (
if (!algorithm)
throw new Error(`Unsupported ChecksumAlgorithm: ${ChecksumAlgorithm}`);
let checksums = [];
- let bytes = new Uint8Array(0);
+ const pending = [];
+ let pendingLen = 0;
+ const takePart = () => {
+ const part = new Uint8Array(partSize);
+ let filled = 0;
+ while (filled < partSize) {
+ const head = pending[0];
+ const need = partSize - filled;
+ if (head.byteLength <= need) {
+ part.set(head, filled);
+ filled += head.byteLength;
+ pending.shift();
+ } else {
+ part.set(head.subarray(0, need), filled);
+ pending[0] = head.subarray(need);
+ filled += need;
+ }
+ }
+ pendingLen -= partSize;
+ return part;
+ };
const passThrough = async (chunk) => {
if (typeof chunk === "string") {
chunk = new TextEncoder().encode(chunk);
+ } else if (!(chunk instanceof Uint8Array)) {
+ // Match the old _concatBuffers handling of ArrayBuffer/Buffer inputs.
+ chunk = new Uint8Array(chunk);
}
- bytes = new Uint8Array(_concatBuffers([bytes, chunk]));
- // Peel off every whole part the accumulated buffer can supply. Math.floor
- // of the byte ratio gives the exact number of complete parts; any trailing
+ pending.push(chunk);
+ pendingLen += chunk.byteLength;
+ // Peel off every whole part the buffered bytes can supply; any trailing
// partial part stays buffered for the next chunk (or the final flush).
- const wholeParts = Math.floor(bytes.byteLength / partSize);
- for (let part = 0; part < wholeParts; part++) {
- const prefixChunk = bytes.slice(0, partSize);
- const checksum = await crypto.subtle.digest(algorithm, prefixChunk);
+ while (pendingLen >= partSize) {
+ const checksum = await crypto.subtle.digest(algorithm, takePart());
checksums.push(checksum);
- bytes = bytes.slice(partSize);
}
};
const flush = async () => {
- if (bytes.byteLength) {
- const checksum = await crypto.subtle.digest(algorithm, bytes);
+ if (pendingLen > 0) {
+ // Remainder is < partSize: a single concat of the leftover chunks.
+ const checksum = await crypto.subtle.digest(
+ algorithm,
+ _concatBuffers(pending),
+ );
checksums.push(checksum);
}
};
diff --git a/packages/csv/index.js b/packages/csv/index.js
index f17bbd9..132cf28 100644
--- a/packages/csv/index.js
+++ b/packages/csv/index.js
@@ -60,6 +60,7 @@ const findRowEnd = (
const escapeCode = escapeChar.charCodeAt(0);
const delimiterLength = delimiterChar.length;
let pos = 0;
+ let nextNl = text.indexOf(newlineChar, 0);
for (;;) {
// `pos` is always a field start here (it advances only past a closing quote
// or a delimiter), so a quote at `pos` always opens a quoted field.
@@ -82,7 +83,9 @@ const findRowEnd = (
pos = closeQ + 1;
continue;
}
- const nextNl = text.indexOf(newlineChar, pos);
+ if (nextNl !== -1 && nextNl < pos) {
+ nextNl = text.indexOf(newlineChar, pos);
+ }
const nextDelim = text.indexOf(delimiterChar, pos);
// Advance past a delimiter that falls at or before the row's newline (a
// delimiter that is a prefix of the newline wins the tie). When there is no
@@ -349,6 +352,8 @@ const csvParseInline = (text, ctx, isFlushing, enqueue) => {
let pos = 0;
let lastWasDelimiter = false;
+ let nextNl = text.indexOf(newlineChar, 0);
+
// Called at most once per invocation (each unterminated-quote branch returns
// immediately afterwards), so the error map and entry are created fresh here.
const trackError = (id, message) => {
@@ -367,10 +372,10 @@ const csvParseInline = (text, ctx, isFlushing, enqueue) => {
if (escapeIsQuote) {
// Find the closing quote with indexOf, skipping escaped "" pairs.
- // replaceAll collapses any doubled quotes; on a field without "" it
- // is a no-op, so it is applied unconditionally.
let closeQ = text.indexOf(quoteChar, pos);
+ let hadEscaped = false;
while (closeQ !== -1 && text.charCodeAt(closeQ + 1) === quoteCharCode) {
+ hadEscaped = true;
closeQ = text.indexOf(quoteChar, closeQ + 2);
}
@@ -379,7 +384,9 @@ const csvParseInline = (text, ctx, isFlushing, enqueue) => {
if (isFlushing) {
trackError("UnterminatedQuote", "Unterminated quoted field");
const raw = text.substring(contentStart);
- fields.push(raw.replaceAll(escapedQuote, quoteChar));
+ fields.push(
+ hadEscaped ? raw.replaceAll(escapedQuote, quoteChar) : raw,
+ );
if (numCols === 0) numCols = fields.length;
enqueue(fields);
idx++;
@@ -391,10 +398,10 @@ const csvParseInline = (text, ctx, isFlushing, enqueue) => {
return;
}
- // Extract field value: single slice + replaceAll (no-op without "")
- const field = text
- .substring(contentStart, closeQ)
- .replaceAll(escapedQuote, quoteChar);
+ const slice = text.substring(contentStart, closeQ);
+ const field = hadEscaped
+ ? slice.replaceAll(escapedQuote, quoteChar)
+ : slice;
if (field.length > fieldMaxSize) {
throw new Error(
`CSV field size (${field.length}) exceeds fieldMaxSize (${fieldMaxSize} bytes)`,
@@ -511,7 +518,9 @@ const csvParseInline = (text, ctx, isFlushing, enqueue) => {
// (handling a quote that opens the next field).
lastWasDelimiter = false;
{
- const nextNl = text.indexOf(newlineChar, pos);
+ if (nextNl !== -1 && nextNl < pos) {
+ nextNl = text.indexOf(newlineChar, pos);
+ }
const nextDelim = text.indexOf(delimiterChar, pos);
if (nextDelim !== -1 && (nextNl === -1 || nextDelim <= nextNl)) {
From c83b469467b4f728513be6451eba649c303d6e3a Mon Sep 17 00:00:00 2001
From: will Farrell
Date: Mon, 15 Jun 2026 06:41:21 -0600
Subject: [PATCH 15/27] chore: dep update
Signed-off-by: will Farrell
---
.github/dependabot.yml | 4 +-
.github/workflows/release.yml | 2 +-
biome.json | 2 +-
package-lock.json | 1382 +++++++++++++++------------------
package.json | 2 +-
packages/aws/s3.js | 7 +-
6 files changed, 643 insertions(+), 756 deletions(-)
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index be3a3f2..476febc 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -5,6 +5,8 @@ updates:
directory: "/"
schedule:
interval: "weekly"
+ cooldown:
+ default-days: 14
groups:
everything:
patterns:
@@ -15,7 +17,7 @@ updates:
schedule:
interval: "weekly"
cooldown:
- default-days: 15
+ default-days: 14
groups:
dev-dependencies:
dependency-type: "development"
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index db2a153..cc24a6e 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -14,7 +14,7 @@ permissions:
contents: read
concurrency:
- group: ${{ github.workflow }}
+ group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: false
jobs:
diff --git a/biome.json b/biome.json
index 641ffc3..5d77c5d 100644
--- a/biome.json
+++ b/biome.json
@@ -15,7 +15,7 @@
"linter": {
"enabled": true,
"rules": {
- "recommended": true,
+ "preset": "recommended",
"complexity": {
"noBannedTypes": "off"
},
diff --git a/package-lock.json b/package-lock.json
index 0fefb3e..c369b84 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -150,22 +150,42 @@
"tslib": "^2.6.2"
}
},
+ "node_modules/@aws-sdk/checksums": {
+ "version": "3.1000.5",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/checksums/-/checksums-3.1000.5.tgz",
+ "integrity": "sha512-zOXUUnilC6lgCsQtp77p/QNPmRlTES9Xi6tlDwbR6kfC/kz5PCzZckgHWm5z+8DskdwuMAbFDq61x3zr10GEEQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-crypto/crc32": "5.2.0",
+ "@aws-crypto/crc32c": "5.2.0",
+ "@aws-crypto/util": "5.2.0",
+ "@aws-sdk/core": "^3.974.20",
+ "@aws-sdk/types": "^3.973.12",
+ "@smithy/core": "^3.24.6",
+ "@smithy/types": "^4.14.3",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
"node_modules/@aws-sdk/client-cloudwatch-logs": {
- "version": "3.1057.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudwatch-logs/-/client-cloudwatch-logs-3.1057.0.tgz",
- "integrity": "sha512-VzrpX93RMMGE8mG9EKm/TX9aZQsQvg0bYz276UOUuxAZlMBrYxKhiMyRDIHtFSUFI5SKaBWE3nY5xoI3SK74LQ==",
+ "version": "3.1068.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudwatch-logs/-/client-cloudwatch-logs-3.1068.0.tgz",
+ "integrity": "sha512-3OlaC3Grl2fovhdEqkOTctcXIjrouwmY4a0Bkg7q7jgAwAP09/intv/RJ1RD/FDEq+xzV5tsWGKMFowN6idZhQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.974.15",
- "@aws-sdk/credential-provider-node": "^3.972.47",
- "@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.5",
- "@smithy/fetch-http-handler": "^5.4.5",
- "@smithy/node-http-handler": "^4.7.5",
- "@smithy/types": "^4.14.2",
+ "@aws-sdk/core": "^3.974.20",
+ "@aws-sdk/credential-provider-node": "^3.972.55",
+ "@aws-sdk/types": "^3.973.12",
+ "@smithy/core": "^3.24.6",
+ "@smithy/fetch-http-handler": "^5.4.6",
+ "@smithy/node-http-handler": "^4.7.6",
+ "@smithy/types": "^4.14.3",
"tslib": "^2.6.2"
},
"engines": {
@@ -173,21 +193,21 @@
}
},
"node_modules/@aws-sdk/client-cognito-identity": {
- "version": "3.1057.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.1057.0.tgz",
- "integrity": "sha512-5MliYkp2u0+2arTp5fZIaxl+xmm90LEKv/VeSxhfNQW4t0fvWJrNO429/jchWQenNoDRrOGE59VfbuZUfwFujg==",
+ "version": "3.1068.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.1068.0.tgz",
+ "integrity": "sha512-by2Qj3f9BI9X4cY0n160R3uzkMpI6k9PmGA8QLAuzr8HzkiNrYFygMEPhIEdqBFHQPD/8AXNUs45HYjEDsQ33g==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.974.15",
- "@aws-sdk/credential-provider-node": "^3.972.47",
- "@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.5",
- "@smithy/fetch-http-handler": "^5.4.5",
- "@smithy/node-http-handler": "^4.7.5",
- "@smithy/types": "^4.14.2",
+ "@aws-sdk/core": "^3.974.20",
+ "@aws-sdk/credential-provider-node": "^3.972.55",
+ "@aws-sdk/types": "^3.973.12",
+ "@smithy/core": "^3.24.6",
+ "@smithy/fetch-http-handler": "^5.4.6",
+ "@smithy/node-http-handler": "^4.7.6",
+ "@smithy/types": "^4.14.3",
"tslib": "^2.6.2"
},
"engines": {
@@ -195,23 +215,23 @@
}
},
"node_modules/@aws-sdk/client-dynamodb": {
- "version": "3.1057.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-dynamodb/-/client-dynamodb-3.1057.0.tgz",
- "integrity": "sha512-S0feh4mSWsqxQ8SGWIqAX5CQ9w+wBFxpNx4QVNy4rfQVMY6PvPuWT6kolfIHqMoIvuVGd9zD71BvzCK3CHip8Q==",
+ "version": "3.1068.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-dynamodb/-/client-dynamodb-3.1068.0.tgz",
+ "integrity": "sha512-DOMUWnLSFHaRC0EixpWMnrQcQaV08P5rzAUdRTEkx72NaDRF0Q6+3QdtqX8ocyHfySzwMwOE9/vHRmhNvWHl/g==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.974.15",
- "@aws-sdk/credential-provider-node": "^3.972.47",
- "@aws-sdk/dynamodb-codec": "^3.973.15",
- "@aws-sdk/middleware-endpoint-discovery": "^3.972.15",
- "@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.5",
- "@smithy/fetch-http-handler": "^5.4.5",
- "@smithy/node-http-handler": "^4.7.5",
- "@smithy/types": "^4.14.2",
+ "@aws-sdk/core": "^3.974.20",
+ "@aws-sdk/credential-provider-node": "^3.972.55",
+ "@aws-sdk/dynamodb-codec": "^3.973.20",
+ "@aws-sdk/middleware-endpoint-discovery": "^3.972.18",
+ "@aws-sdk/types": "^3.973.12",
+ "@smithy/core": "^3.24.6",
+ "@smithy/fetch-http-handler": "^5.4.6",
+ "@smithy/node-http-handler": "^4.7.6",
+ "@smithy/types": "^4.14.3",
"tslib": "^2.6.2"
},
"engines": {
@@ -219,21 +239,21 @@
}
},
"node_modules/@aws-sdk/client-dynamodb-streams": {
- "version": "3.1057.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-dynamodb-streams/-/client-dynamodb-streams-3.1057.0.tgz",
- "integrity": "sha512-oVvf641Vo3mQBnytnOIGgleE+bSmTiqXmH1pCRBH10NBqSpSw6ll3KL6tgC0DErKt37aDGD7P0qC/FS8Cdjq9Q==",
+ "version": "3.1068.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-dynamodb-streams/-/client-dynamodb-streams-3.1068.0.tgz",
+ "integrity": "sha512-8cbPgM++tpgsD+aj0azisy2Lyvb/9zu7iRd3SF2f64O8ea5mQP6wTRUWGNaPtuviBlogJZpCwJP5w0nrzFWtxQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.974.15",
- "@aws-sdk/credential-provider-node": "^3.972.47",
- "@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.5",
- "@smithy/fetch-http-handler": "^5.4.5",
- "@smithy/node-http-handler": "^4.7.5",
- "@smithy/types": "^4.14.2",
+ "@aws-sdk/core": "^3.974.20",
+ "@aws-sdk/credential-provider-node": "^3.972.55",
+ "@aws-sdk/types": "^3.973.12",
+ "@smithy/core": "^3.24.6",
+ "@smithy/fetch-http-handler": "^5.4.6",
+ "@smithy/node-http-handler": "^4.7.6",
+ "@smithy/types": "^4.14.3",
"tslib": "^2.6.2"
},
"engines": {
@@ -241,21 +261,21 @@
}
},
"node_modules/@aws-sdk/client-glue": {
- "version": "3.1057.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-glue/-/client-glue-3.1057.0.tgz",
- "integrity": "sha512-pnsMbbnxR8wWr1qcyqkUUQVmHz5pmzW1cn9O/ANIhQ2rjyhF1/Wpgwvyv69ots1mbeOzGgsjfVvebpxisx01FQ==",
+ "version": "3.1068.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-glue/-/client-glue-3.1068.0.tgz",
+ "integrity": "sha512-T/2aZGVaDDuSSQ3OWhWowBZ3P2hQGIV+16idxiA0Z8WevLWgbzztSGScDyYa7ohe/J/BY0XiYsBavLYtv+yGlg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.974.15",
- "@aws-sdk/credential-provider-node": "^3.972.47",
- "@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.5",
- "@smithy/fetch-http-handler": "^5.4.5",
- "@smithy/node-http-handler": "^4.7.5",
- "@smithy/types": "^4.14.2",
+ "@aws-sdk/core": "^3.974.20",
+ "@aws-sdk/credential-provider-node": "^3.972.55",
+ "@aws-sdk/types": "^3.973.12",
+ "@smithy/core": "^3.24.6",
+ "@smithy/fetch-http-handler": "^5.4.6",
+ "@smithy/node-http-handler": "^4.7.6",
+ "@smithy/types": "^4.14.3",
"tslib": "^2.6.2"
},
"engines": {
@@ -263,21 +283,21 @@
}
},
"node_modules/@aws-sdk/client-kinesis": {
- "version": "3.1057.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-kinesis/-/client-kinesis-3.1057.0.tgz",
- "integrity": "sha512-f1uYr9W5C+44UCT5r8Ca++Gn+NS4AQ/KPtjOsowQw8VQ/i2ZbOzU3cJB1RY0g2L1FpvQtM5bjGyrlOULzWKIWw==",
+ "version": "3.1068.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-kinesis/-/client-kinesis-3.1068.0.tgz",
+ "integrity": "sha512-0+5P4CJFf/K5/EBxzRR97OLeQqe3GazyCjV47/ksyTnfr+Bif2UhvZ2Kq6c+s/dqie6LPP4NFAB5Q8D/TZ3+og==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.974.15",
- "@aws-sdk/credential-provider-node": "^3.972.47",
- "@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.5",
- "@smithy/fetch-http-handler": "^5.4.5",
- "@smithy/node-http-handler": "^4.7.5",
- "@smithy/types": "^4.14.2",
+ "@aws-sdk/core": "^3.974.20",
+ "@aws-sdk/credential-provider-node": "^3.972.55",
+ "@aws-sdk/types": "^3.973.12",
+ "@smithy/core": "^3.24.6",
+ "@smithy/fetch-http-handler": "^5.4.6",
+ "@smithy/node-http-handler": "^4.7.6",
+ "@smithy/types": "^4.14.3",
"tslib": "^2.6.2"
},
"engines": {
@@ -285,21 +305,21 @@
}
},
"node_modules/@aws-sdk/client-lambda": {
- "version": "3.1057.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-lambda/-/client-lambda-3.1057.0.tgz",
- "integrity": "sha512-JoaE3QNvPqOSHJtcAFfza7BRoGUNerIKlSVhsKCBsa1i54Vto1YWUS7itkUELK2rpvS8kNZMPliPxDdi/oV5dw==",
+ "version": "3.1068.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-lambda/-/client-lambda-3.1068.0.tgz",
+ "integrity": "sha512-GitXCytcrvezkAQbyT+cYMrGPCM9zdh9sU8FrQr1vyniVijXk2X4ZBf2WZwDQcenNPMJyN5YdtUAbmUJCrfZDg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.974.15",
- "@aws-sdk/credential-provider-node": "^3.972.47",
- "@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.5",
- "@smithy/fetch-http-handler": "^5.4.5",
- "@smithy/node-http-handler": "^4.7.5",
- "@smithy/types": "^4.14.2",
+ "@aws-sdk/core": "^3.974.20",
+ "@aws-sdk/credential-provider-node": "^3.972.55",
+ "@aws-sdk/types": "^3.973.12",
+ "@smithy/core": "^3.24.6",
+ "@smithy/fetch-http-handler": "^5.4.6",
+ "@smithy/node-http-handler": "^4.7.6",
+ "@smithy/types": "^4.14.3",
"tslib": "^2.6.2"
},
"engines": {
@@ -307,29 +327,25 @@
}
},
"node_modules/@aws-sdk/client-s3": {
- "version": "3.1057.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.1057.0.tgz",
- "integrity": "sha512-4MV5+ph7WSLEqStKYdWf2EIHIvLpPzV8xN98jWSVJfUpp5j7T8dyN3AROPPsKWvCme8hbx1ybCjtK76ALCZUYg==",
+ "version": "3.1068.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.1068.0.tgz",
+ "integrity": "sha512-lFgaIpxZvloNbJvQ337YPdMXhzI2zJdDw13nATVGnkAGNoNPx4ksD84AQAcuW75hsaaMaIuNmXU9sSx6+FTirA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/sha1-browser": "5.2.0",
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.974.15",
- "@aws-sdk/credential-provider-node": "^3.972.47",
- "@aws-sdk/middleware-bucket-endpoint": "^3.972.17",
- "@aws-sdk/middleware-expect-continue": "^3.972.14",
- "@aws-sdk/middleware-flexible-checksums": "^3.974.23",
- "@aws-sdk/middleware-location-constraint": "^3.972.11",
- "@aws-sdk/middleware-sdk-s3": "^3.972.44",
- "@aws-sdk/middleware-ssec": "^3.972.11",
- "@aws-sdk/signature-v4-multi-region": "^3.996.30",
- "@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.5",
- "@smithy/fetch-http-handler": "^5.4.5",
- "@smithy/node-http-handler": "^4.7.5",
- "@smithy/types": "^4.14.2",
+ "@aws-sdk/core": "^3.974.20",
+ "@aws-sdk/credential-provider-node": "^3.972.55",
+ "@aws-sdk/middleware-flexible-checksums": "^3.974.30",
+ "@aws-sdk/middleware-sdk-s3": "^3.972.51",
+ "@aws-sdk/signature-v4-multi-region": "^3.996.34",
+ "@aws-sdk/types": "^3.973.12",
+ "@smithy/core": "^3.24.6",
+ "@smithy/fetch-http-handler": "^5.4.6",
+ "@smithy/node-http-handler": "^4.7.6",
+ "@smithy/types": "^4.14.3",
"tslib": "^2.6.2"
},
"engines": {
@@ -337,21 +353,21 @@
}
},
"node_modules/@aws-sdk/client-sns": {
- "version": "3.1057.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-sns/-/client-sns-3.1057.0.tgz",
- "integrity": "sha512-zvHIX5pVCZPAehUbiaQURkJxZW1fUiCAdqhZVhKxzWlEGchiJqTjdNi9DG4wZdmKir+303fsq/HQaNB49vtavQ==",
+ "version": "3.1068.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-sns/-/client-sns-3.1068.0.tgz",
+ "integrity": "sha512-xIjKGG2yzUhX+IHqq0B/8D6zKKr32+LmYUy/OnV5dDj+j+eUJD7J3Ca6kMVDPI6eWe/fCtdHCgsnZtxhf1LMqg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.974.15",
- "@aws-sdk/credential-provider-node": "^3.972.47",
- "@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.5",
- "@smithy/fetch-http-handler": "^5.4.5",
- "@smithy/node-http-handler": "^4.7.5",
- "@smithy/types": "^4.14.2",
+ "@aws-sdk/core": "^3.974.20",
+ "@aws-sdk/credential-provider-node": "^3.972.55",
+ "@aws-sdk/types": "^3.973.12",
+ "@smithy/core": "^3.24.6",
+ "@smithy/fetch-http-handler": "^5.4.6",
+ "@smithy/node-http-handler": "^4.7.6",
+ "@smithy/types": "^4.14.3",
"tslib": "^2.6.2"
},
"engines": {
@@ -359,22 +375,22 @@
}
},
"node_modules/@aws-sdk/client-sqs": {
- "version": "3.1057.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-sqs/-/client-sqs-3.1057.0.tgz",
- "integrity": "sha512-Qaxt1azI1PwClNkQzt/7N10rTdvC8oBleBxZ3yZWswXgMD/EcZ5sMim925uD75YXgzLwLnxKzF7c4mUxNuCqqw==",
+ "version": "3.1068.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-sqs/-/client-sqs-3.1068.0.tgz",
+ "integrity": "sha512-hatCfVf61RsSO5Qjrf7JKln4KiPDprXNJhpx9DNOmyeW1v+i7KNhbawk4d1wAnQ72YciOfhAhyRFec6UZqcnzQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.974.15",
- "@aws-sdk/credential-provider-node": "^3.972.47",
- "@aws-sdk/middleware-sdk-sqs": "^3.972.26",
- "@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.5",
- "@smithy/fetch-http-handler": "^5.4.5",
- "@smithy/node-http-handler": "^4.7.5",
- "@smithy/types": "^4.14.2",
+ "@aws-sdk/core": "^3.974.20",
+ "@aws-sdk/credential-provider-node": "^3.972.55",
+ "@aws-sdk/middleware-sdk-sqs": "^3.972.30",
+ "@aws-sdk/types": "^3.973.12",
+ "@smithy/core": "^3.24.6",
+ "@smithy/fetch-http-handler": "^5.4.6",
+ "@smithy/node-http-handler": "^4.7.6",
+ "@smithy/types": "^4.14.3",
"tslib": "^2.6.2"
},
"engines": {
@@ -382,22 +398,22 @@
}
},
"node_modules/@aws-sdk/client-sts": {
- "version": "3.1057.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.1057.0.tgz",
- "integrity": "sha512-67Qi3j1Np/y8QAiTQn3SlYIDg6j3gUbwbjYqPzL0S0pDTYoNtnHjABrvarg21txotlQn9ZkbgBawEL3+f3A/Qg==",
+ "version": "3.1068.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.1068.0.tgz",
+ "integrity": "sha512-WCUEpfdsSSO7zsXi7GUwHR+A5HZDQNsGktFJxOm73ZU+WLlBKRDzKdWZdYOpNkgBpXxy5KCeVMvXuaq2s1zn7w==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.974.15",
- "@aws-sdk/credential-provider-node": "^3.972.47",
- "@aws-sdk/signature-v4-multi-region": "^3.996.30",
- "@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.5",
- "@smithy/fetch-http-handler": "^5.4.5",
- "@smithy/node-http-handler": "^4.7.5",
- "@smithy/types": "^4.14.2",
+ "@aws-sdk/core": "^3.974.20",
+ "@aws-sdk/credential-provider-node": "^3.972.55",
+ "@aws-sdk/signature-v4-multi-region": "^3.996.34",
+ "@aws-sdk/types": "^3.973.12",
+ "@smithy/core": "^3.24.6",
+ "@smithy/fetch-http-handler": "^5.4.6",
+ "@smithy/node-http-handler": "^4.7.6",
+ "@smithy/types": "^4.14.3",
"tslib": "^2.6.2"
},
"engines": {
@@ -405,18 +421,18 @@
}
},
"node_modules/@aws-sdk/core": {
- "version": "3.974.15",
- "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.974.15.tgz",
- "integrity": "sha512-UpA0rTGW/tHGITcCqHisbuuEPraYg9GG+mWmXjY5+RxZBMLGe6aL9oe0ix50LztwAcPIkGZLH0yWdMIkCM10hw==",
+ "version": "3.974.20",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.974.20.tgz",
+ "integrity": "sha512-7sDi2B2N3mc3nf1nz6FyEx/FCrJ1N1QnBmraHHQNabFaeAh2IaOOLml48/rHOD1bICHgTRkbBgNTvUzEr5Z35g==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/types": "^3.973.9",
- "@aws-sdk/xml-builder": "^3.972.26",
+ "@aws-sdk/types": "^3.973.12",
+ "@aws-sdk/xml-builder": "^3.972.29",
"@aws/lambda-invoke-store": "^0.2.2",
- "@smithy/core": "^3.24.5",
- "@smithy/signature-v4": "^5.4.5",
- "@smithy/types": "^4.14.2",
+ "@smithy/core": "^3.24.6",
+ "@smithy/signature-v4": "^5.4.6",
+ "@smithy/types": "^4.14.3",
"bowser": "^2.11.0",
"tslib": "^2.6.2"
},
@@ -424,31 +440,17 @@
"node": ">=20.0.0"
}
},
- "node_modules/@aws-sdk/crc64-nvme": {
- "version": "3.972.9",
- "resolved": "https://registry.npmjs.org/@aws-sdk/crc64-nvme/-/crc64-nvme-3.972.9.tgz",
- "integrity": "sha512-P+QGozmXn2mZZI7sDgk+aUm+RTI61MPSFB+Ir2vjEjEbEsE4e7hYtzrDvAUxZy9ko81h53e11+F/GYlvwDkaOQ==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@smithy/types": "^4.14.2",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=20.0.0"
- }
- },
"node_modules/@aws-sdk/credential-provider-cognito-identity": {
- "version": "3.972.38",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.972.38.tgz",
- "integrity": "sha512-OHkK6xOx/IHkSbQdDWxnVCLU+j28EFl8wyWgBILQDFAPY8n240C/O4gjmFx+zFU12lL8njgJQ5GWAIWq88CnSQ==",
+ "version": "3.972.45",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.972.45.tgz",
+ "integrity": "sha512-4L/REssieLON1hVsTzZucP1p2u5jmPNejyh/9BCGZXr93IalBbhRPCrtKIKwMTu9yRGr/bcKzhrQocByKLSzLQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/nested-clients": "^3.997.13",
- "@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.5",
- "@smithy/types": "^4.14.2",
+ "@aws-sdk/nested-clients": "^3.997.20",
+ "@aws-sdk/types": "^3.973.12",
+ "@smithy/core": "^3.24.6",
+ "@smithy/types": "^4.14.3",
"tslib": "^2.6.2"
},
"engines": {
@@ -456,16 +458,16 @@
}
},
"node_modules/@aws-sdk/credential-provider-env": {
- "version": "3.972.41",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.41.tgz",
- "integrity": "sha512-n1EbJ98yvPWWdHZZv8bRBMqqDQJrtgtxyJ4xLy2Uqrh25BCOZQ7nnS1CsFXvuH8r0b0KVHDZEGEH5FxmEMP8jg==",
+ "version": "3.972.46",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.46.tgz",
+ "integrity": "sha512-+GPXVS2srMOlH74S+SmC1gVuP2TvUZ0siuC0onKO93q+udP+M72dmY8wJfVQ5CX9z/9X5A1HHwz5yRIGBtskvQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.974.15",
- "@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.5",
- "@smithy/types": "^4.14.2",
+ "@aws-sdk/core": "^3.974.20",
+ "@aws-sdk/types": "^3.973.12",
+ "@smithy/core": "^3.24.6",
+ "@smithy/types": "^4.14.3",
"tslib": "^2.6.2"
},
"engines": {
@@ -473,18 +475,18 @@
}
},
"node_modules/@aws-sdk/credential-provider-http": {
- "version": "3.972.43",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.43.tgz",
- "integrity": "sha512-TT76RN1NkI9WoyZqCNxOw6/WBMF7pYOTJcXbMokNFU+euSG40Kaf/t/FhDACVZWP+43wEM6ZynIPIkzS1wR1iA==",
+ "version": "3.972.48",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.48.tgz",
+ "integrity": "sha512-fA5loSdlocacRxyUXtpoHSMuk5rsIKRDzQYVMnMxjcmFeZshaJlJ8lymy/hYKji6sne/UmNGj5pxuEs6kq/Qcg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.974.15",
- "@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.5",
- "@smithy/fetch-http-handler": "^5.4.5",
- "@smithy/node-http-handler": "^4.7.5",
- "@smithy/types": "^4.14.2",
+ "@aws-sdk/core": "^3.974.20",
+ "@aws-sdk/types": "^3.973.12",
+ "@smithy/core": "^3.24.6",
+ "@smithy/fetch-http-handler": "^5.4.6",
+ "@smithy/node-http-handler": "^4.7.6",
+ "@smithy/types": "^4.14.3",
"tslib": "^2.6.2"
},
"engines": {
@@ -492,24 +494,24 @@
}
},
"node_modules/@aws-sdk/credential-provider-ini": {
- "version": "3.972.46",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.972.46.tgz",
- "integrity": "sha512-hvcgcwOiS0nb2XFb5Op1Pz/vYaWz5K8kKullziGpdNRuG0NwzRXseuPt2CoBqknHGaSPVesu1aOn2OcctEYdCA==",
+ "version": "3.972.53",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.972.53.tgz",
+ "integrity": "sha512-ZfdhIOR41q8TcWEnUac+gCOb+O2LBWdHLmjedXpXz4IEFW2ppNuFcm6p0sMTavpM+zD5TYfpH5Gp7guRyqSgsQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.974.15",
- "@aws-sdk/credential-provider-env": "^3.972.41",
- "@aws-sdk/credential-provider-http": "^3.972.43",
- "@aws-sdk/credential-provider-login": "^3.972.45",
- "@aws-sdk/credential-provider-process": "^3.972.41",
- "@aws-sdk/credential-provider-sso": "^3.972.45",
- "@aws-sdk/credential-provider-web-identity": "^3.972.45",
- "@aws-sdk/nested-clients": "^3.997.13",
- "@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.5",
- "@smithy/credential-provider-imds": "^4.3.6",
- "@smithy/types": "^4.14.2",
+ "@aws-sdk/core": "^3.974.20",
+ "@aws-sdk/credential-provider-env": "^3.972.46",
+ "@aws-sdk/credential-provider-http": "^3.972.48",
+ "@aws-sdk/credential-provider-login": "^3.972.52",
+ "@aws-sdk/credential-provider-process": "^3.972.46",
+ "@aws-sdk/credential-provider-sso": "^3.972.52",
+ "@aws-sdk/credential-provider-web-identity": "^3.972.52",
+ "@aws-sdk/nested-clients": "^3.997.20",
+ "@aws-sdk/types": "^3.973.12",
+ "@smithy/core": "^3.24.6",
+ "@smithy/credential-provider-imds": "^4.3.7",
+ "@smithy/types": "^4.14.3",
"tslib": "^2.6.2"
},
"engines": {
@@ -517,17 +519,17 @@
}
},
"node_modules/@aws-sdk/credential-provider-login": {
- "version": "3.972.45",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.45.tgz",
- "integrity": "sha512-MZQv4SNjByk1iOKmrqmzcUF/uCB05wjvEHyXKxmGQTUANTIVayX6HPUF0bzkWLvtnkH7sAn9kUCfkXbSpj9sDA==",
+ "version": "3.972.52",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.52.tgz",
+ "integrity": "sha512-9hu2oR0qH7Fst5Tzdx+UWxm+w5zCXtErTLtOOW5hwwQc170CLwOeniRxyFY6s9mHfGEfC5zFukNBdKBwJR8mhQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.974.15",
- "@aws-sdk/nested-clients": "^3.997.13",
- "@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.5",
- "@smithy/types": "^4.14.2",
+ "@aws-sdk/core": "^3.974.20",
+ "@aws-sdk/nested-clients": "^3.997.20",
+ "@aws-sdk/types": "^3.973.12",
+ "@smithy/core": "^3.24.6",
+ "@smithy/types": "^4.14.3",
"tslib": "^2.6.2"
},
"engines": {
@@ -535,22 +537,22 @@
}
},
"node_modules/@aws-sdk/credential-provider-node": {
- "version": "3.972.47",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.47.tgz",
- "integrity": "sha512-HrId+C0DWA5qDIyLG64/kjUB2RNtPypxmABnIctK+TA1P1kHlOYoE/Wf5T5tKOMKgb08P7k/zNyhvfJ3lh5Oag==",
+ "version": "3.972.55",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.55.tgz",
+ "integrity": "sha512-zMGLa/dhESVqmCD7mmIFFKSwSFrJGScvCXcjvBZEVOOMauFS5JRQvLTMukFpMEFWiV6dTAlsen2ATDBulLPtbg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/credential-provider-env": "^3.972.41",
- "@aws-sdk/credential-provider-http": "^3.972.43",
- "@aws-sdk/credential-provider-ini": "^3.972.46",
- "@aws-sdk/credential-provider-process": "^3.972.41",
- "@aws-sdk/credential-provider-sso": "^3.972.45",
- "@aws-sdk/credential-provider-web-identity": "^3.972.45",
- "@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.5",
- "@smithy/credential-provider-imds": "^4.3.6",
- "@smithy/types": "^4.14.2",
+ "@aws-sdk/credential-provider-env": "^3.972.46",
+ "@aws-sdk/credential-provider-http": "^3.972.48",
+ "@aws-sdk/credential-provider-ini": "^3.972.53",
+ "@aws-sdk/credential-provider-process": "^3.972.46",
+ "@aws-sdk/credential-provider-sso": "^3.972.52",
+ "@aws-sdk/credential-provider-web-identity": "^3.972.52",
+ "@aws-sdk/types": "^3.973.12",
+ "@smithy/core": "^3.24.6",
+ "@smithy/credential-provider-imds": "^4.3.7",
+ "@smithy/types": "^4.14.3",
"tslib": "^2.6.2"
},
"engines": {
@@ -558,16 +560,16 @@
}
},
"node_modules/@aws-sdk/credential-provider-process": {
- "version": "3.972.41",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.41.tgz",
- "integrity": "sha512-7I/n1zkysouLOWvkEhjNEP4vMnD2v4kzzr3/3QBdrripEpn7ap1/I5DF3Hou1SUqkKWo1f3oPGMyFAA1FAMvsQ==",
+ "version": "3.972.46",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.46.tgz",
+ "integrity": "sha512-VUoNFBIjWrUN8NbFiQiuxQEgFjvziAlBRPK+ddh27aj65gk0BYu6bLZnrdrNZwpW6vAihtSUtEMQ1PUJ32QRPA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.974.15",
- "@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.5",
- "@smithy/types": "^4.14.2",
+ "@aws-sdk/core": "^3.974.20",
+ "@aws-sdk/types": "^3.973.12",
+ "@smithy/core": "^3.24.6",
+ "@smithy/types": "^4.14.3",
"tslib": "^2.6.2"
},
"engines": {
@@ -575,18 +577,18 @@
}
},
"node_modules/@aws-sdk/credential-provider-sso": {
- "version": "3.972.45",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.972.45.tgz",
- "integrity": "sha512-oHgbz/eFD8IKiksqDsz9ZMU4A59BpQq4QwJedBnGD80ZqYcHPPHZBwjBnxLVkB7iRVVHWpDclR8yWdD2PkQIUA==",
+ "version": "3.972.52",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.972.52.tgz",
+ "integrity": "sha512-nb2/n4o/HQf+FVpVbZe9vCTFngmuDoIsltMgLAtjixaKzvzhB4J8WSDFyWgnErgLHk55ctWH+I4PU+LIHhyffg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.974.15",
- "@aws-sdk/nested-clients": "^3.997.13",
- "@aws-sdk/token-providers": "3.1056.0",
- "@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.5",
- "@smithy/types": "^4.14.2",
+ "@aws-sdk/core": "^3.974.20",
+ "@aws-sdk/nested-clients": "^3.997.20",
+ "@aws-sdk/token-providers": "3.1066.0",
+ "@aws-sdk/types": "^3.973.12",
+ "@smithy/core": "^3.24.6",
+ "@smithy/types": "^4.14.3",
"tslib": "^2.6.2"
},
"engines": {
@@ -594,17 +596,17 @@
}
},
"node_modules/@aws-sdk/credential-provider-web-identity": {
- "version": "3.972.45",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.45.tgz",
- "integrity": "sha512-CDhzKdb2onv5bpnjn/acgdNmJOQthPDLsPizU7rZflsEcgMMp8Mlri+U5hdxf8ldvZJpvM3vLU6D56vfJm5AMQ==",
+ "version": "3.972.52",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.52.tgz",
+ "integrity": "sha512-lKj6aRSGbqLmpYmM24bY7a1Xmfcq2vkE3hv8CSPYfc1yCu0BPu/XEJ1L4Fm61MsU6ULLNSG8UGsffNoFUBjESA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.974.15",
- "@aws-sdk/nested-clients": "^3.997.13",
- "@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.5",
- "@smithy/types": "^4.14.2",
+ "@aws-sdk/core": "^3.974.20",
+ "@aws-sdk/nested-clients": "^3.997.20",
+ "@aws-sdk/types": "^3.973.12",
+ "@smithy/core": "^3.24.6",
+ "@smithy/types": "^4.14.3",
"tslib": "^2.6.2"
},
"engines": {
@@ -612,28 +614,28 @@
}
},
"node_modules/@aws-sdk/credential-providers": {
- "version": "3.1057.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.1057.0.tgz",
- "integrity": "sha512-rbrEHtz11g0kxsSkYr3fx2HABNNblp4AhB2MgPvJHgYOWfJ2eBviU7Mvoaef0PW8QH6lbZDfJcnM7eKvtvz3sw==",
+ "version": "3.1068.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.1068.0.tgz",
+ "integrity": "sha512-DN7UewD/XKGfNGWXZsTECWRj3IsULkE7aG+fPwqPf13CnX4UmNvj80g1xieJ0lVdMQ2h0L3gZpn2ClIY06+/vQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/client-cognito-identity": "3.1057.0",
- "@aws-sdk/core": "^3.974.15",
- "@aws-sdk/credential-provider-cognito-identity": "^3.972.38",
- "@aws-sdk/credential-provider-env": "^3.972.41",
- "@aws-sdk/credential-provider-http": "^3.972.43",
- "@aws-sdk/credential-provider-ini": "^3.972.46",
- "@aws-sdk/credential-provider-login": "^3.972.45",
- "@aws-sdk/credential-provider-node": "^3.972.47",
- "@aws-sdk/credential-provider-process": "^3.972.41",
- "@aws-sdk/credential-provider-sso": "^3.972.45",
- "@aws-sdk/credential-provider-web-identity": "^3.972.45",
- "@aws-sdk/nested-clients": "^3.997.13",
- "@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.5",
- "@smithy/credential-provider-imds": "^4.3.6",
- "@smithy/types": "^4.14.2",
+ "@aws-sdk/client-cognito-identity": "3.1068.0",
+ "@aws-sdk/core": "^3.974.20",
+ "@aws-sdk/credential-provider-cognito-identity": "^3.972.45",
+ "@aws-sdk/credential-provider-env": "^3.972.46",
+ "@aws-sdk/credential-provider-http": "^3.972.48",
+ "@aws-sdk/credential-provider-ini": "^3.972.53",
+ "@aws-sdk/credential-provider-login": "^3.972.52",
+ "@aws-sdk/credential-provider-node": "^3.972.55",
+ "@aws-sdk/credential-provider-process": "^3.972.46",
+ "@aws-sdk/credential-provider-sso": "^3.972.52",
+ "@aws-sdk/credential-provider-web-identity": "^3.972.52",
+ "@aws-sdk/nested-clients": "^3.997.20",
+ "@aws-sdk/types": "^3.973.12",
+ "@smithy/core": "^3.24.6",
+ "@smithy/credential-provider-imds": "^4.3.7",
+ "@smithy/types": "^4.14.3",
"tslib": "^2.6.2"
},
"engines": {
@@ -641,15 +643,15 @@
}
},
"node_modules/@aws-sdk/dynamodb-codec": {
- "version": "3.973.15",
- "resolved": "https://registry.npmjs.org/@aws-sdk/dynamodb-codec/-/dynamodb-codec-3.973.15.tgz",
- "integrity": "sha512-R09IUytTrUKwsIiMVSHPZJz0zO9EsXHg/JZ+3AwQ+eSahRnHuPuZANMfeTb/j2+AKkZ7DhW2FcT6XuHLwC0cZw==",
+ "version": "3.973.20",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/dynamodb-codec/-/dynamodb-codec-3.973.20.tgz",
+ "integrity": "sha512-SFfxiqVgWeIe+RsJJNAMD//2IfehT4bLpGyNJRB0MgHmOIJtdcfMnR1k7KYyaHokSoQVdncVa9O9DIGa4eqcwg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.974.15",
- "@smithy/core": "^3.24.5",
- "@smithy/types": "^4.14.2",
+ "@aws-sdk/core": "^3.974.20",
+ "@smithy/core": "^3.24.6",
+ "@smithy/types": "^4.14.3",
"tslib": "^2.6.2"
},
"engines": {
@@ -657,9 +659,9 @@
}
},
"node_modules/@aws-sdk/endpoint-cache": {
- "version": "3.972.5",
- "resolved": "https://registry.npmjs.org/@aws-sdk/endpoint-cache/-/endpoint-cache-3.972.5.tgz",
- "integrity": "sha512-itVdge0NozgtgmtbZ25FVwWU3vGlE7x7feE/aOEJNkQfEpbkrF8Rj1QmnK+2blFfYE1xWt/iU+6/jUp/pv1+MA==",
+ "version": "3.972.7",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/endpoint-cache/-/endpoint-cache-3.972.7.tgz",
+ "integrity": "sha512-LkwS3ZOUNL5kHzmz3dDx8lE3HOhZmf2VGjbJ/tMUZJYWWl3J0RJTZM7RFz1MLt06WDVvlShcAjY/RzhYlqLL7g==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -671,14 +673,14 @@
}
},
"node_modules/@aws-sdk/lib-storage": {
- "version": "3.1057.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/lib-storage/-/lib-storage-3.1057.0.tgz",
- "integrity": "sha512-0LlXWaklL2LGBSJ6w3YwsJaFCR9yu57648aEyyIRLM5NT+rQ3Xbx0/pCsuM4fD+QJZhASMMAALAl/pdiN5B+FQ==",
+ "version": "3.1068.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/lib-storage/-/lib-storage-3.1068.0.tgz",
+ "integrity": "sha512-BGUS3EXFe+y87odXsC5enyBv4z/QT3EDydv+iTe9hCUr57ndAXCfJbvcm3f+s3aHS5FUDL3WozaBAcrsNeVhyQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@smithy/core": "^3.24.5",
- "@smithy/types": "^4.14.2",
+ "@smithy/core": "^3.24.6",
+ "@smithy/types": "^4.14.3",
"buffer": "5.6.0",
"events": "3.3.0",
"stream-browserify": "3.0.0",
@@ -688,53 +690,20 @@
"node": ">=20.0.0"
},
"peerDependencies": {
- "@aws-sdk/client-s3": "^3.1057.0"
- }
- },
- "node_modules/@aws-sdk/middleware-bucket-endpoint": {
- "version": "3.972.17",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.972.17.tgz",
- "integrity": "sha512-lbDmWuHenc+kiwCNrxz4MyN6nkxCWyTXPIWuspJN0ibziu+8CXci7vI1bK9MAkwy8cwJOEXNu0gBM5S0uTGRIg==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@aws-sdk/core": "^3.974.15",
- "@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.5",
- "@smithy/types": "^4.14.2",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=20.0.0"
+ "@aws-sdk/client-s3": "^3.1068.0"
}
},
"node_modules/@aws-sdk/middleware-endpoint-discovery": {
- "version": "3.972.15",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-endpoint-discovery/-/middleware-endpoint-discovery-3.972.15.tgz",
- "integrity": "sha512-L1wbvrAb0hv7Vx6eTEyqQwXaNETSj/L30BVCkSxD0k6Ve5cZUM0SLUvBn8aA/B4YtIpMzCbzNaVytZY7uOzJSw==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@aws-sdk/endpoint-cache": "^3.972.5",
- "@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.5",
- "@smithy/types": "^4.14.2",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=20.0.0"
- }
- },
- "node_modules/@aws-sdk/middleware-expect-continue": {
- "version": "3.972.14",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.972.14.tgz",
- "integrity": "sha512-3TNFEVGO4sWZj9TEXOCZLzGEctXHnaO4fk2EQ8KVaboTbwHmEPEQrm17Xb9koImUIXEw0sgi2xtHjg7LuTS3rA==",
+ "version": "3.972.18",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-endpoint-discovery/-/middleware-endpoint-discovery-3.972.18.tgz",
+ "integrity": "sha512-1vKJt/6MBB/MBMRM3qzCMdW70syJY8u2DH+dq7yCnPn7wVJmyeAzAa/sK1lIbbYh8BVLbM5FspsT4zbe885gOw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.5",
- "@smithy/types": "^4.14.2",
+ "@aws-sdk/endpoint-cache": "^3.972.7",
+ "@aws-sdk/types": "^3.973.12",
+ "@smithy/core": "^3.24.6",
+ "@smithy/types": "^4.14.3",
"tslib": "^2.6.2"
},
"engines": {
@@ -742,35 +711,13 @@
}
},
"node_modules/@aws-sdk/middleware-flexible-checksums": {
- "version": "3.974.23",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.974.23.tgz",
- "integrity": "sha512-4nPKARo2lfKvQGUt2fPA5NlS/mEohckdxpuC9ecbjVfj7B7NFFYHeTg+Bf5BEQwdn3yRfUIzFiEkPp8Yuaw3wA==",
+ "version": "3.974.30",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.974.30.tgz",
+ "integrity": "sha512-OaIhub+3yTgfFWPzKO8OzOZFIMUoJaiS5v67y3spQg7SoULGoMx4jKVBbE+uhnzkiZXQ+rEDS0RqrK4/aD1yJw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-crypto/crc32": "5.2.0",
- "@aws-crypto/crc32c": "5.2.0",
- "@aws-crypto/util": "5.2.0",
- "@aws-sdk/core": "^3.974.15",
- "@aws-sdk/crc64-nvme": "^3.972.9",
- "@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.5",
- "@smithy/types": "^4.14.2",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=20.0.0"
- }
- },
- "node_modules/@aws-sdk/middleware-location-constraint": {
- "version": "3.972.11",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.972.11.tgz",
- "integrity": "sha512-hkfspNUP4criAH6ton6BGKgnm5dZx+7bUOy1YqlTfejDeUPAM23D81q/IX+hdlS3KUsfwGz5ADTqZWKBEUpf4A==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@aws-sdk/types": "^3.973.9",
- "@smithy/types": "^4.14.2",
+ "@aws-sdk/checksums": "^3.1000.5",
"tslib": "^2.6.2"
},
"engines": {
@@ -778,17 +725,17 @@
}
},
"node_modules/@aws-sdk/middleware-sdk-s3": {
- "version": "3.972.44",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.972.44.tgz",
- "integrity": "sha512-8HQsRg1NpX8vR4vNl1E8pyLnqZroq9VSL2vZQVSgBqp6wv6365LzYD08/c9FFh/9FTg7YRc7aTtEmXF0ir/pqg==",
+ "version": "3.972.51",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.972.51.tgz",
+ "integrity": "sha512-keQgcIUTcHL0Qn7guhsuLaxQU36r9norCrxgaPH4DNCwon4TPtXdI/UdYuycl9vj3Dlwc3YR1dfL3U+6iIwJ6w==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.974.15",
- "@aws-sdk/signature-v4-multi-region": "^3.996.30",
- "@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.5",
- "@smithy/types": "^4.14.2",
+ "@aws-sdk/core": "^3.974.20",
+ "@aws-sdk/signature-v4-multi-region": "^3.996.34",
+ "@aws-sdk/types": "^3.973.12",
+ "@smithy/core": "^3.24.6",
+ "@smithy/types": "^4.14.3",
"tslib": "^2.6.2"
},
"engines": {
@@ -796,30 +743,15 @@
}
},
"node_modules/@aws-sdk/middleware-sdk-sqs": {
- "version": "3.972.26",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sqs/-/middleware-sdk-sqs-3.972.26.tgz",
- "integrity": "sha512-9VjCszKNDgEvHZBcryWpjGY4vwbTZU6hWARsxJZ+SZSglalP/6g8QTIKmKxSKlLle0BvrWhbZ5wlRhktTTkXEQ==",
+ "version": "3.972.30",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sqs/-/middleware-sdk-sqs-3.972.30.tgz",
+ "integrity": "sha512-PVAj7VgWK/ZxCXnkgC4B7cdJyUN99Nsr7IEduHt4A1GieuB+ZnU5bSifHwapbr17wrFkmdxfSh+aA0Lj+Ads6w==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.5",
- "@smithy/types": "^4.14.2",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=20.0.0"
- }
- },
- "node_modules/@aws-sdk/middleware-ssec": {
- "version": "3.972.11",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.972.11.tgz",
- "integrity": "sha512-7PQvGNhtveKlvVqNahqWx5yrwxP7ecwAoB1dYBf8eKwfo2tzzCbNnW+q2nO3N066ktQaB4iBQbDRWtizm+amoQ==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@aws-sdk/types": "^3.973.9",
- "@smithy/types": "^4.14.2",
+ "@aws-sdk/types": "^3.973.12",
+ "@smithy/core": "^3.24.6",
+ "@smithy/types": "^4.14.3",
"tslib": "^2.6.2"
},
"engines": {
@@ -827,21 +759,21 @@
}
},
"node_modules/@aws-sdk/nested-clients": {
- "version": "3.997.13",
- "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.997.13.tgz",
- "integrity": "sha512-2pA6eyb5nSo/ZD2cayhOTEMoGQYgspq0RI05GDLkzQ3ajZ6isS6waV6E92Am/hz4LIlLUTrbwPLurJ/fuiHvkg==",
+ "version": "3.997.20",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.997.20.tgz",
+ "integrity": "sha512-IYJuLpXp2DEILVQpQOy0PMpkftv0AHEOCn52o0atyOaumA0CdWQ3klPyXdViGYLbNpESsVFMVybvHUeZAuiGxA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.974.15",
- "@aws-sdk/signature-v4-multi-region": "^3.996.30",
- "@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.5",
- "@smithy/fetch-http-handler": "^5.4.5",
- "@smithy/node-http-handler": "^4.7.5",
- "@smithy/types": "^4.14.2",
+ "@aws-sdk/core": "^3.974.20",
+ "@aws-sdk/signature-v4-multi-region": "^3.996.34",
+ "@aws-sdk/types": "^3.973.12",
+ "@smithy/core": "^3.24.6",
+ "@smithy/fetch-http-handler": "^5.4.6",
+ "@smithy/node-http-handler": "^4.7.6",
+ "@smithy/types": "^4.14.3",
"tslib": "^2.6.2"
},
"engines": {
@@ -849,15 +781,15 @@
}
},
"node_modules/@aws-sdk/signature-v4-multi-region": {
- "version": "3.996.30",
- "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.996.30.tgz",
- "integrity": "sha512-HULDLMVzkmTSEv6//7kx2kRevp/VYUpm8hJNNFbmhxDn0fUiGTxVcM9yg31TukvTq8nyOBDUN2gH0o5IRbKjdw==",
+ "version": "3.996.34",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.996.34.tgz",
+ "integrity": "sha512-mx1L5qlumSOt/nKM3BFaHE2HVkWwz0i4Bw0pyYO42FfX/FeLlo8YI6csC0gSPprEk6fTIqI+CZN9RwUwKd5krQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/types": "^3.973.9",
- "@smithy/signature-v4": "^5.4.5",
- "@smithy/types": "^4.14.2",
+ "@aws-sdk/types": "^3.973.12",
+ "@smithy/signature-v4": "^5.4.6",
+ "@smithy/types": "^4.14.3",
"tslib": "^2.6.2"
},
"engines": {
@@ -865,17 +797,17 @@
}
},
"node_modules/@aws-sdk/token-providers": {
- "version": "3.1056.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.1056.0.tgz",
- "integrity": "sha512-81duvlltQlsfn5K+o8zILcystBRdbT1G2JJYVCML5NZHBz4CL/zf+sAemCtBh/uh6RQUMyInGeZLQ7/8igZhbA==",
+ "version": "3.1066.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.1066.0.tgz",
+ "integrity": "sha512-UqEUJq7dqa44hneLDUcX7UJy95cg8YqEWyakRpvIPnrNS3Mq+UlQHgCDGu5pvwAPtlIW4qcYbvW6reG6++FyvA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.974.15",
- "@aws-sdk/nested-clients": "^3.997.13",
- "@aws-sdk/types": "^3.973.9",
- "@smithy/core": "^3.24.5",
- "@smithy/types": "^4.14.2",
+ "@aws-sdk/core": "^3.974.20",
+ "@aws-sdk/nested-clients": "^3.997.20",
+ "@aws-sdk/types": "^3.973.12",
+ "@smithy/core": "^3.24.6",
+ "@smithy/types": "^4.14.3",
"tslib": "^2.6.2"
},
"engines": {
@@ -883,13 +815,13 @@
}
},
"node_modules/@aws-sdk/types": {
- "version": "3.973.9",
- "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.973.9.tgz",
- "integrity": "sha512-kuBfgQVdcz5Bmapc4A13YbpVw/pXkesfhetcFYwbntqas8sF41OHyd4o28+/TG2ZQdHBsv90Lsu5y6oitvYCdg==",
+ "version": "3.973.12",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.973.12.tgz",
+ "integrity": "sha512-43ajd1NF0RMgX5k0hxCNUyEdrtFUsb2aHT2QvpktSC/2Eyb2Jr/JPVqdp0XIoaHWikZJq5tNWSLO6kB5q2eMCA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@smithy/types": "^4.14.2",
+ "@smithy/types": "^4.14.3",
"tslib": "^2.6.2"
},
"engines": {
@@ -897,13 +829,13 @@
}
},
"node_modules/@aws-sdk/util-format-url": {
- "version": "3.972.17",
- "resolved": "https://registry.npmjs.org/@aws-sdk/util-format-url/-/util-format-url-3.972.17.tgz",
- "integrity": "sha512-Y/VVghC8yAz9fe2f47tqVoKZDfE5fvmnuIimifrRK04oy8PLezI7bgTB+KjDZaV1dnAq076DKaaQPxFgx6YN7A==",
+ "version": "3.972.22",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/util-format-url/-/util-format-url-3.972.22.tgz",
+ "integrity": "sha512-ygzBtG3xDxvMWTg3EjlZ5FSYxUiRCsCZvKPk+sOhXeMcDTdzPqIGQipiUiIYJm/Om8h8qXyhchMb0baW1PhE+w==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.974.15",
+ "@aws-sdk/core": "^3.974.20",
"tslib": "^2.6.2"
},
"engines": {
@@ -911,9 +843,9 @@
}
},
"node_modules/@aws-sdk/util-locate-window": {
- "version": "3.965.5",
- "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.965.5.tgz",
- "integrity": "sha512-WhlJNNINQB+9qtLtZJcpQdgZw3SCDCpXdUJP7cToGwHbCWCnRckGlc6Bx/OhWwIYFNAn+FIydY8SZ0QmVu3xTQ==",
+ "version": "3.965.7",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.965.7.tgz",
+ "integrity": "sha512-M0D6oIpohdNHjc7udzTHEQyot0+0iuA36jc2I9Hps+f/GtKi2HO/pyijQnCnNcwZqLB5+rtn81z3eZK/GyjAmA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -934,13 +866,13 @@
}
},
"node_modules/@aws-sdk/xml-builder": {
- "version": "3.972.26",
- "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.26.tgz",
- "integrity": "sha512-cDbrqvDS73whl6YAPSPq0U6whzG6UWI9PuWh0wrUuGoZexhWEqhdunbukV7iBoaWnFV1AODutM5hOD6rtn439g==",
+ "version": "3.972.29",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.29.tgz",
+ "integrity": "sha512-fk0niuGFxfi8yIJuMVM4mhwObkiQSuwZFj3tAPrLVx64Pk3BkrEIpqjzHKY4hKoEBUD6Jg/S74Zj9jy+5F3DnQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@smithy/types": "^4.14.2",
+ "@smithy/types": "^4.14.3",
"fast-xml-parser": "5.7.3",
"tslib": "^2.6.2"
},
@@ -1500,9 +1432,9 @@
}
},
"node_modules/@biomejs/biome": {
- "version": "2.4.16",
- "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.4.16.tgz",
- "integrity": "sha512-x9ajFh1zChVybCiM3TN6OD4phAqLgtPZjFrZF+aTMYCPjwBO+k529TX7PPsAqtGNLeV4UgzwQnowEgS7bGmzcA==",
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.5.0.tgz",
+ "integrity": "sha512-4kURkd9hAPrdDM3C9n82ycYgx8hvQcW6MjKTEejruj8rK0N8P3OPpdy8BvI8kt3KWY4ycF5XtDOrktetEfhfuw==",
"dev": true,
"license": "MIT OR Apache-2.0",
"bin": {
@@ -1516,20 +1448,20 @@
"url": "https://opencollective.com/biome"
},
"optionalDependencies": {
- "@biomejs/cli-darwin-arm64": "2.4.16",
- "@biomejs/cli-darwin-x64": "2.4.16",
- "@biomejs/cli-linux-arm64": "2.4.16",
- "@biomejs/cli-linux-arm64-musl": "2.4.16",
- "@biomejs/cli-linux-x64": "2.4.16",
- "@biomejs/cli-linux-x64-musl": "2.4.16",
- "@biomejs/cli-win32-arm64": "2.4.16",
- "@biomejs/cli-win32-x64": "2.4.16"
+ "@biomejs/cli-darwin-arm64": "2.5.0",
+ "@biomejs/cli-darwin-x64": "2.5.0",
+ "@biomejs/cli-linux-arm64": "2.5.0",
+ "@biomejs/cli-linux-arm64-musl": "2.5.0",
+ "@biomejs/cli-linux-x64": "2.5.0",
+ "@biomejs/cli-linux-x64-musl": "2.5.0",
+ "@biomejs/cli-win32-arm64": "2.5.0",
+ "@biomejs/cli-win32-x64": "2.5.0"
}
},
"node_modules/@biomejs/cli-darwin-arm64": {
- "version": "2.4.16",
- "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.4.16.tgz",
- "integrity": "sha512-wxPvu4XOA85YJk9ixSWUmq/QBHbid85BISbOAqqBM/5xQpPk9ayjk5375tOlSC0BeCwNSbPFafQBm+vBumXq0A==",
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.5.0.tgz",
+ "integrity": "sha512-Mn3Fwi3SA5fgmfCPqmzpWF2DLZnms3BVAhM088nTnGrTZmHS3wwIjcoZPqpXeNgd3DrrLH6xp8vTLIBuJoZiXw==",
"cpu": [
"arm64"
],
@@ -1544,9 +1476,9 @@
}
},
"node_modules/@biomejs/cli-darwin-x64": {
- "version": "2.4.16",
- "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.4.16.tgz",
- "integrity": "sha512-xFCqGPwYusQJp4N4NJLi1XJiZqjwFdjhT+KqtNy+Ug3qgfczqnTa6MSDvxJF6TkuDLoYJItMapz6tAf7kCekFw==",
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.5.0.tgz",
+ "integrity": "sha512-rg3VPL5P8mYro6pqlXYXuJWph21slVp3SZtAqWSrkZs40d2gTzYmHF8E/X1iTID25btmNKltNDJ926sqVBp7DQ==",
"cpu": [
"x64"
],
@@ -1561,9 +1493,9 @@
}
},
"node_modules/@biomejs/cli-linux-arm64": {
- "version": "2.4.16",
- "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.4.16.tgz",
- "integrity": "sha512-2kFb4//jxfZaP6D+Rj5VkHkxgyD9EoRAVBEQb8PKRv+s4NO2zYNJKXFaJmK1CmhufJOWEfpHKaRbOja7qjmdhQ==",
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.5.0.tgz",
+ "integrity": "sha512-tl+LW8fdD96/xdeWtWwc82LIOc5CoY7N2AsogLTp5R4ECErYt+8Jl/N68ezN9vzSiqPTxw6vjcihoLPYKZHrlw==",
"cpu": [
"arm64"
],
@@ -1581,9 +1513,9 @@
}
},
"node_modules/@biomejs/cli-linux-arm64-musl": {
- "version": "2.4.16",
- "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.4.16.tgz",
- "integrity": "sha512-oYxnW0ARfJkr72ezzF2OR8N/rtkgLUQeYtF8cFhVswbknHxtTcmzSsanVJP8yQKnGpGpc2ck6c5zLvHahL6Cbg==",
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.5.0.tgz",
+ "integrity": "sha512-vQdM4oSGaf7ZNeGO9w5+Y8SBtyser9M6znxYbm7Ec8wInxJu1WiKxFYZW5Auj2d80bcVvefuGGRxoFOE0eee8g==",
"cpu": [
"arm64"
],
@@ -1601,9 +1533,9 @@
}
},
"node_modules/@biomejs/cli-linux-x64": {
- "version": "2.4.16",
- "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.4.16.tgz",
- "integrity": "sha512-NbcBbi/nJqn5baae6wqRXdS7Gadf2uRpehSh6vMSYpG8OhkXl/Xg8aorWrJ+9VWqAT5ml90alLvorkpMW0nBwQ==",
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.5.0.tgz",
+ "integrity": "sha512-zpEGf4RQbFEh8Vt7OmavLyyOzRbtcE9osCqrS1kfvt8jDvxwhKXLSf7n0ebr/ov0RJ9ssP+lhs6C8a9WwFvrQA==",
"cpu": [
"x64"
],
@@ -1621,9 +1553,9 @@
}
},
"node_modules/@biomejs/cli-linux-x64-musl": {
- "version": "2.4.16",
- "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.4.16.tgz",
- "integrity": "sha512-iHDS+MCM65DPqWGu+ECC3uoALyj2H7F4nVUPxIPjz/PIl94EUu+EDfGZDzFP+NY1EOPVt9NQvwFqq7HdMmowdg==",
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.5.0.tgz",
+ "integrity": "sha512-+9hIcMngJ+yGUahXqZuZ8CoWKJE9SAZsFsM3QDvXpNsLbXZ9lqVzgBhOk/jTSYkOA0GLP9eu3teukqpLUojHMg==",
"cpu": [
"x64"
],
@@ -1641,9 +1573,9 @@
}
},
"node_modules/@biomejs/cli-win32-arm64": {
- "version": "2.4.16",
- "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.4.16.tgz",
- "integrity": "sha512-0rgImMsNb5v/chhkIFe3wu7PEFClS6RBAYUijGL9UsYN3PanSaoK24HSSuSJb1pYbYYVjzAyZTl3gtjJ84BM8A==",
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.5.0.tgz",
+ "integrity": "sha512-jB0wAvTLI4itx5VidqVUejPQFhRUxiZ9l9FvZ26D5fl6t3qme+ZB4PD3bTSeL1vZ8NI2Rx/zj6H9zcESuGHKGw==",
"cpu": [
"arm64"
],
@@ -1658,9 +1590,9 @@
}
},
"node_modules/@biomejs/cli-win32-x64": {
- "version": "2.4.16",
- "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.4.16.tgz",
- "integrity": "sha512-Kp85jgoBHa05gix6UIRjfCDiUV3w/8VIdZ247VyyO2gEjaw12WEVhdIjlxp/AMzXxqxQwbxNTDVZ3Mwd2RG5rw==",
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.5.0.tgz",
+ "integrity": "sha512-VT/lF+GId+67j8aDfLkxdxNoVApsPSTbyAtB3jJq0IWTrY77WXfbPfpngxq0bA6JCEv/7k8C9qWjDRKRznDlyw==",
"cpu": [
"x64"
],
@@ -1701,9 +1633,9 @@
}
},
"node_modules/@cloudflare/workerd-darwin-64": {
- "version": "1.20260526.1",
- "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20260526.1.tgz",
- "integrity": "sha512-/pR3GH3gfv0PUp7DjI8v0aAIDOqFwibq4bg5xT7TZgcVdBV/cJQWckdXCMqiRtHiawLwogUX00EIOINkYJ1Zqg==",
+ "version": "1.20260611.1",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20260611.1.tgz",
+ "integrity": "sha512-iJICldmi4sBGgi7IrQles8cStOGXM/Tmv95C4OODVs6VIbMsJPqThUM5h3uYVQNULuJ8I/aVvnJ3Eh/wZCKwuA==",
"cpu": [
"x64"
],
@@ -1718,9 +1650,9 @@
}
},
"node_modules/@cloudflare/workerd-darwin-arm64": {
- "version": "1.20260526.1",
- "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20260526.1.tgz",
- "integrity": "sha512-rcyu0iANYfaiezKh3Mcao1O4IIgVfQldxduiL5TZT1sP0NIeRY4YReSTrzPxNnXxSYaIqaqRHMcHbUM/ic4knA==",
+ "version": "1.20260611.1",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20260611.1.tgz",
+ "integrity": "sha512-yBbVXvbZyltR3I7NJdC4C4ItkItjZSiabcA/3HzEWOUQjLVKFqRh4so6ToHr70VCYh8VGeR8EDZL23igLhXqFQ==",
"cpu": [
"arm64"
],
@@ -1735,9 +1667,9 @@
}
},
"node_modules/@cloudflare/workerd-linux-64": {
- "version": "1.20260526.1",
- "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20260526.1.tgz",
- "integrity": "sha512-5EZAEnlLwa9oGJRo8Nd3iY5Wcd9ROGNNG90xNIGp8MEjj8v2jTn42NC47fCZKFdnLj3+S+vWEhu1x0GVJnALjA==",
+ "version": "1.20260611.1",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20260611.1.tgz",
+ "integrity": "sha512-PfNjpxOlaIgZFYuhD7+neEEewCN2Ud993wEEN0fmbtSOax1AK53LGqmXUDvFhnbkHxJLFAxYCSNISW8QbzaAIg==",
"cpu": [
"x64"
],
@@ -1752,9 +1684,9 @@
}
},
"node_modules/@cloudflare/workerd-linux-arm64": {
- "version": "1.20260526.1",
- "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20260526.1.tgz",
- "integrity": "sha512-X/YBQXeXFeCN7QTStoWrATEBc9WKl7PIqkw/dQkjyJ72gh3rkLe0+Xkzp3wO7gtxTDQMa7NPGy1W4+sdMf8q1g==",
+ "version": "1.20260611.1",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20260611.1.tgz",
+ "integrity": "sha512-GEp4XbuIKjlF8pakqXcUDJfKiJosD/Q7S83J0d+r+z9XIlYGfF3ntm08e2aiF5TFTwp3fnG4yMoPUAKNhNJpvQ==",
"cpu": [
"arm64"
],
@@ -1769,9 +1701,9 @@
}
},
"node_modules/@cloudflare/workerd-windows-64": {
- "version": "1.20260526.1",
- "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20260526.1.tgz",
- "integrity": "sha512-R+tqpFFdcfZIljx8fIW9rj9fRTtDgfoA2yonsfAGa6e8snrmr+38mdFHtkRC0D3UyZpn/hOtmXiUBfdX2gMR7Q==",
+ "version": "1.20260611.1",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20260611.1.tgz",
+ "integrity": "sha512-S6JkS0kEbcCKs19RGqEPhjCRbP8GBkQwqYLp2fhBJtD/KTlwqLzOJ9E6PQ7gQKgWHtxy1NBG3oXarlNFRNU/dw==",
"cpu": [
"x64"
],
@@ -1786,9 +1718,9 @@
}
},
"node_modules/@cloudflare/workers-types": {
- "version": "4.20260601.1",
- "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20260601.1.tgz",
- "integrity": "sha512-pYORr1EKlDu55HCHhln8XSXoOSvKAkrTkovJL66bX8xw6DAT2fhs39B6FLjCJD+x++hjBEE2bmKB1TcFKS+0Dw==",
+ "version": "4.20260615.1",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20260615.1.tgz",
+ "integrity": "sha512-fGOiTwoLj/8bU8mj3VAfa1EULx4ceZhDwnjvY+afDBlSXI9pvY7PE9t62rGEhJjbAOGd7i5WUDun0eZCWBDrzg==",
"dev": true,
"license": "MIT OR Apache-2.0"
},
@@ -2193,9 +2125,9 @@
}
},
"node_modules/@duckdb/duckdb-wasm/node_modules/@types/node": {
- "version": "20.19.41",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.41.tgz",
- "integrity": "sha512-ECymXOukMnOoVkC2bb1Vc/w/836DXncOg5m8Xj1RH7xSHZJWNYY6Zh7EH477vcnD5egKNNfy2RpNOmuChhFPgQ==",
+ "version": "20.19.43",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.43.tgz",
+ "integrity": "sha512-6oYBAi5ikg4Pl+kGsoYtawUMBT2zZMCvPNF7pVLnHZfd1zf38DRiWn/gT01RYCdUqkv7Fhr+C9ot4/tb+2sVvA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -2475,9 +2407,9 @@
}
},
"node_modules/@esbuild/aix-ppc64": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.0.tgz",
- "integrity": "sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz",
+ "integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==",
"cpu": [
"ppc64"
],
@@ -2491,9 +2423,9 @@
}
},
"node_modules/@esbuild/android-arm": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.0.tgz",
- "integrity": "sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz",
+ "integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==",
"cpu": [
"arm"
],
@@ -2507,9 +2439,9 @@
}
},
"node_modules/@esbuild/android-arm64": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.0.tgz",
- "integrity": "sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz",
+ "integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==",
"cpu": [
"arm64"
],
@@ -2523,9 +2455,9 @@
}
},
"node_modules/@esbuild/android-x64": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.0.tgz",
- "integrity": "sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz",
+ "integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==",
"cpu": [
"x64"
],
@@ -2539,9 +2471,9 @@
}
},
"node_modules/@esbuild/darwin-arm64": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.0.tgz",
- "integrity": "sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz",
+ "integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==",
"cpu": [
"arm64"
],
@@ -2555,9 +2487,9 @@
}
},
"node_modules/@esbuild/darwin-x64": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.0.tgz",
- "integrity": "sha512-fyzLm/DLDl/84OCfp2f/XQ4flmORsjU7VKt8HLjvIXChJoFFOIL6pLJPH4Yhd1n1gGFF9mPwtlN5Wf82DZs+LQ==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz",
+ "integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==",
"cpu": [
"x64"
],
@@ -2571,9 +2503,9 @@
}
},
"node_modules/@esbuild/freebsd-arm64": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.0.tgz",
- "integrity": "sha512-l9GeW5UZBT9k9brBYI+0WDffcRxgHQD8ShN2Ur4xWq/NFzUKm3k5lsH4PdaRgb2w7mI9u61nr2gI2mLI27Nh3Q==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz",
+ "integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==",
"cpu": [
"arm64"
],
@@ -2587,9 +2519,9 @@
}
},
"node_modules/@esbuild/freebsd-x64": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.0.tgz",
- "integrity": "sha512-BXoQai/A0wPO6Es3yFJ7APCiKGc1tdAEOgeTNy3SsB491S3aHn4S4r3e976eUnPdU+NbdtmBuLncYir2tMU9Nw==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz",
+ "integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==",
"cpu": [
"x64"
],
@@ -2603,9 +2535,9 @@
}
},
"node_modules/@esbuild/linux-arm": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.0.tgz",
- "integrity": "sha512-CjaaREJagqJp7iTaNQjjidaNbCKYcd4IDkzbwwxtSvjI7NZm79qiHc8HqciMddQ6CKvJT6aBd8lO9kN/ZudLlw==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz",
+ "integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==",
"cpu": [
"arm"
],
@@ -2619,9 +2551,9 @@
}
},
"node_modules/@esbuild/linux-arm64": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.0.tgz",
- "integrity": "sha512-RVyzfb3FWsGA55n6WY0MEIEPURL1FcbhFE6BffZEMEekfCzCIMtB5yyDcFnVbTnwk+CLAgTujmV/Lgvih56W+A==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz",
+ "integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==",
"cpu": [
"arm64"
],
@@ -2635,9 +2567,9 @@
}
},
"node_modules/@esbuild/linux-ia32": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.0.tgz",
- "integrity": "sha512-KBnSTt1kxl9x70q+ydterVdl+Cn0H18ngRMRCEQfrbqdUuntQQ0LoMZv47uB97NljZFzY6HcfqEZ2SAyIUTQBQ==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz",
+ "integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==",
"cpu": [
"ia32"
],
@@ -2651,9 +2583,9 @@
}
},
"node_modules/@esbuild/linux-loong64": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.0.tgz",
- "integrity": "sha512-zpSlUce1mnxzgBADvxKXX5sl8aYQHo2ezvMNI8I0lbblJtp8V4odlm3Yzlj7gPyt3T8ReksE6bK+pT3WD+aJRg==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz",
+ "integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==",
"cpu": [
"loong64"
],
@@ -2667,9 +2599,9 @@
}
},
"node_modules/@esbuild/linux-mips64el": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.0.tgz",
- "integrity": "sha512-2jIfP6mmjkdmeTlsX/9vmdmhBmKADrWqN7zcdtHIeNSCH1SqIoNI63cYsjQR8J+wGa4Y5izRcSHSm8K3QWmk3w==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz",
+ "integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==",
"cpu": [
"mips64el"
],
@@ -2683,9 +2615,9 @@
}
},
"node_modules/@esbuild/linux-ppc64": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.0.tgz",
- "integrity": "sha512-bc0FE9wWeC0WBm49IQMPSPILRocGTQt3j5KPCA8os6VprfuJ7KD+5PzESSrJ6GmPIPJK965ZJHTUlSA6GNYEhg==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz",
+ "integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==",
"cpu": [
"ppc64"
],
@@ -2699,9 +2631,9 @@
}
},
"node_modules/@esbuild/linux-riscv64": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.0.tgz",
- "integrity": "sha512-SQPZOwoTTT/HXFXQJG/vBX8sOFagGqvZyXcgLA3NhIqcBv1BJU1d46c0rGcrij2B56Z2rNiSLaZOYW5cUk7yLQ==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz",
+ "integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==",
"cpu": [
"riscv64"
],
@@ -2715,9 +2647,9 @@
}
},
"node_modules/@esbuild/linux-s390x": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.0.tgz",
- "integrity": "sha512-SCfR0HN8CEEjnYnySJTd2cw0k9OHB/YFzt5zgJEwa+wL/T/raGWYMBqwDNAC6dqFKmJYZoQBRfHjgwLHGSrn3Q==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz",
+ "integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==",
"cpu": [
"s390x"
],
@@ -2731,9 +2663,9 @@
}
},
"node_modules/@esbuild/linux-x64": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.0.tgz",
- "integrity": "sha512-us0dSb9iFxIi8srnpl931Nvs65it/Jd2a2K3qs7fz2WfGPHqzfzZTfec7oxZJRNPXPnNYZtanmRc4AL/JwVzHQ==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz",
+ "integrity": "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==",
"cpu": [
"x64"
],
@@ -2747,9 +2679,9 @@
}
},
"node_modules/@esbuild/netbsd-arm64": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.0.tgz",
- "integrity": "sha512-CR/RYotgtCKwtftMwJlUU7xCVNg3lMYZ0RzTmAHSfLCXw3NtZtNpswLEj/Kkf6kEL3Gw+BpOekRX0BYCtklhUw==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz",
+ "integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==",
"cpu": [
"arm64"
],
@@ -2763,9 +2695,9 @@
}
},
"node_modules/@esbuild/netbsd-x64": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.0.tgz",
- "integrity": "sha512-nU1yhmYutL+fQ71Kxnhg8uEOdC0pwEW9entHykTgEbna2pw2dkbFSMeqjjyHZoCmt8SBkOSvV+yNmm94aUrrqw==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz",
+ "integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==",
"cpu": [
"x64"
],
@@ -2779,9 +2711,9 @@
}
},
"node_modules/@esbuild/openbsd-arm64": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.0.tgz",
- "integrity": "sha512-cXb5vApOsRsxsEl4mcZ1XY3D4DzcoMxR/nnc4IyqYs0rTI8ZKmW6kyyg+11Z8yvgMfAEldKzP7AdP64HnSC/6g==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz",
+ "integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==",
"cpu": [
"arm64"
],
@@ -2795,9 +2727,9 @@
}
},
"node_modules/@esbuild/openbsd-x64": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.0.tgz",
- "integrity": "sha512-8wZM2qqtv9UP3mzy7HiGYNH/zjTA355mpeuA+859TyR+e+Tc08IHYpLJuMsfpDJwoLo1ikIJI8jC3GFjnRClzA==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz",
+ "integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==",
"cpu": [
"x64"
],
@@ -2811,9 +2743,9 @@
}
},
"node_modules/@esbuild/openharmony-arm64": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.0.tgz",
- "integrity": "sha512-FLGfyizszcef5C3YtoyQDACyg95+dndv79i2EekILBofh5wpCa1KuBqOWKrEHZg3zrL3t5ouE5jgr94vA+Wb2w==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz",
+ "integrity": "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==",
"cpu": [
"arm64"
],
@@ -2827,9 +2759,9 @@
}
},
"node_modules/@esbuild/sunos-x64": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.0.tgz",
- "integrity": "sha512-1ZgjUoEdHZZl/YlV76TSCz9Hqj9h9YmMGAgAPYd+q4SicWNX3G5GCyx9uhQWSLcbvPW8Ni7lj4gDa1T40akdlw==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz",
+ "integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==",
"cpu": [
"x64"
],
@@ -2843,9 +2775,9 @@
}
},
"node_modules/@esbuild/win32-arm64": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.0.tgz",
- "integrity": "sha512-Q9StnDmQ/enxnpxCCLSg0oo4+34B9TdXpuyPeTedN/6+iXBJ4J+zwfQI28u/Jl40nOYAxGoNi7mFP40RUtkmUA==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz",
+ "integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==",
"cpu": [
"arm64"
],
@@ -2859,9 +2791,9 @@
}
},
"node_modules/@esbuild/win32-ia32": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.0.tgz",
- "integrity": "sha512-zF3ag/gfiCe6U2iczcRzSYJKH1DCI+ByzSENHlM2FcDbEeo5Zd2C86Aq0tKUYAJJ1obRP84ymxIAksZUcdztHA==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz",
+ "integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==",
"cpu": [
"ia32"
],
@@ -2875,9 +2807,9 @@
}
},
"node_modules/@esbuild/win32-x64": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.0.tgz",
- "integrity": "sha512-pEl1bO9mfAmIC+tW5btTmrKaujg3zGtUmWNdCw/xs70FBjwAL3o9OEKNHvNmnyylD6ubxUERiEhdsL0xBQ9efw==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz",
+ "integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==",
"cpu": [
"x64"
],
@@ -3885,14 +3817,14 @@
}
},
"node_modules/@napi-rs/wasm-runtime": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz",
- "integrity": "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==",
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.5.tgz",
+ "integrity": "sha512-AWPoBRJ9tsnVhor4sjO7rkni+7p+2IAEFj6cx06UgP10jkQHqay/36uRV/bFkgrh18D9vb4cr8Q0Pthskgzy+Q==",
"dev": true,
"license": "MIT",
"optional": true,
"dependencies": {
- "@tybys/wasm-util": "^0.10.1"
+ "@tybys/wasm-util": "^0.10.2"
},
"funding": {
"type": "github",
@@ -3904,9 +3836,9 @@
}
},
"node_modules/@nodable/entities": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/@nodable/entities/-/entities-2.1.1.tgz",
- "integrity": "sha512-Pig3HxDIoMgjdEH8OCf/dkcTmLFjJRjWuq8jSnklu284/TKOPibSRERmOykiwmyXTtv61mP+44f3GMx0tLAyjg==",
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@nodable/entities/-/entities-2.2.0.tgz",
+ "integrity": "sha512-9uGyhaQavEUMC8AIddIjau4NsnsXhou+j5sBAGojCM1oxmQpVKTWR/9JxABD6UAv12vpIms55fPZKFQEhG6uBg==",
"dev": true,
"funding": [
{
@@ -4447,14 +4379,14 @@
}
},
"node_modules/@smithy/core": {
- "version": "3.24.5",
- "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.24.5.tgz",
- "integrity": "sha512-Kt8phUg45M15EjhYAbZ+fFikYneijLu9Liugz8ZsYz2i8j0hzGv27LWKpEHYRfvj+LyCOSijpcR/2i8RouV+cA==",
+ "version": "3.24.7",
+ "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.24.7.tgz",
+ "integrity": "sha512-KoUi4M1f3BG6kzN1FnCwL7oyFptTbyBJKjR6yhSib+JHRdUmM1o+VwsFtJ66NZCkCzVfJMWRHJNo0R0jznp0Pg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/crc32": "5.2.0",
- "@smithy/types": "^4.14.2",
+ "@smithy/types": "^4.14.4",
"tslib": "^2.6.2"
},
"engines": {
@@ -4462,14 +4394,14 @@
}
},
"node_modules/@smithy/credential-provider-imds": {
- "version": "4.3.6",
- "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.3.6.tgz",
- "integrity": "sha512-tHhdiWZfG1ZIh2YcRfPJmY2gHcBmqbAzqm3ER4TIDFYsSEqTD5tICT7cgQ/kI8LRakxp12myOYyK68XPn7MnHw==",
+ "version": "4.3.9",
+ "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.3.9.tgz",
+ "integrity": "sha512-ZlfJ/4Fa3jYb+3eaohPfG9utX9HmdhFNcFtpoGAhUhdynAOmGXtmigbi7eEiONKM+ykHw8RwKuDEb85Lx7t7fA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@smithy/core": "^3.24.5",
- "@smithy/types": "^4.14.2",
+ "@smithy/core": "^3.24.7",
+ "@smithy/types": "^4.14.4",
"tslib": "^2.6.2"
},
"engines": {
@@ -4477,14 +4409,14 @@
}
},
"node_modules/@smithy/fetch-http-handler": {
- "version": "5.4.5",
- "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.4.5.tgz",
- "integrity": "sha512-SK3VMeH0fibgdTg2QeB+O4p7Yy/2E5HBOHJeC58FshkDdeuX8lOgO7PfjYfLyPLP1ch55j91cQqKBzDS0mRjSQ==",
+ "version": "5.4.7",
+ "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.4.7.tgz",
+ "integrity": "sha512-NslaM2ir0N2hisDmzXLstPaVINZheh8SokyOC++kzFPloZucL2R7Y7bS57mSzx/1Fc/fqmn7twjkeezTTrV0EA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@smithy/core": "^3.24.5",
- "@smithy/types": "^4.14.2",
+ "@smithy/core": "^3.24.7",
+ "@smithy/types": "^4.14.4",
"tslib": "^2.6.2"
},
"engines": {
@@ -4505,14 +4437,14 @@
}
},
"node_modules/@smithy/node-http-handler": {
- "version": "4.7.5",
- "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.7.5.tgz",
- "integrity": "sha512-3dA9TQ+ybRSZ/m0wnbZhiBy4Dezjgq1Ib/ZZrYTpJDBgpoLLU/SDzZc/g0x0MNAdOJe1wPcM+x2PBRmoOur+Sw==",
+ "version": "4.7.8",
+ "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.7.8.tgz",
+ "integrity": "sha512-f+DbsWUwSbtMu1a/j8Y93KiU1SRg9nyzfjereqn1BJ33QOTUXxdlYvVXMhAYl1vuR1Kmna5aIJe09KSIfyFNYw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@smithy/core": "^3.24.5",
- "@smithy/types": "^4.14.2",
+ "@smithy/core": "^3.24.7",
+ "@smithy/types": "^4.14.4",
"tslib": "^2.6.2"
},
"engines": {
@@ -4520,14 +4452,14 @@
}
},
"node_modules/@smithy/signature-v4": {
- "version": "5.4.5",
- "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.4.5.tgz",
- "integrity": "sha512-QBJKWGqIknH0dc9LWpfH1mkdokAx6iXYN3UcQ3eY6uIEyScuoQAhfl94ge7ozUy9WgFUdE8xsvwBjaYBbWmPNA==",
+ "version": "5.4.7",
+ "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.4.7.tgz",
+ "integrity": "sha512-LwQZazFayImv+IOm0S0enoLeUJwmAlhGC5O6YCcLWezyu08dF46GOxPOq35OpBIHkgd7OvNvBStIFwVNyrvoBw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@smithy/core": "^3.24.5",
- "@smithy/types": "^4.14.2",
+ "@smithy/core": "^3.24.7",
+ "@smithy/types": "^4.14.4",
"tslib": "^2.6.2"
},
"engines": {
@@ -4535,9 +4467,9 @@
}
},
"node_modules/@smithy/types": {
- "version": "4.14.2",
- "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.14.2.tgz",
- "integrity": "sha512-P+otAxbV4CqBybp7EkcJCrig63yE2E7PuNVOmilVMRcx/O+QDzGULTrKsq4DV13gSfak9ObPrWaHl/9bL5YcWw==",
+ "version": "4.14.4",
+ "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.14.4.tgz",
+ "integrity": "sha512-B2S9+UGm1+/pHkcx3ZoLVX1a+pmSk8rqxRR+ZsNqZaJ5q9FWX9AFGQVM4qG5+OBeQUZVy99HY8HqW8gK/wgXzQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -4629,9 +4561,9 @@
}
},
"node_modules/@speed-highlight/core": {
- "version": "1.2.15",
- "resolved": "https://registry.npmjs.org/@speed-highlight/core/-/core-1.2.15.tgz",
- "integrity": "sha512-BMq1K3DsElxDWawkX6eLg9+CKJrTVGCBAWVuHXVUV2u0s2711qiChLSId6ikYPfxhdYocLNt3wWwSvDiTvFabw==",
+ "version": "1.2.17",
+ "resolved": "https://registry.npmjs.org/@speed-highlight/core/-/core-1.2.17.tgz",
+ "integrity": "sha512-Z92FwKpCtfaW1V0jTU/fh3QzYEZN8wDwrzRIBoADCJfn4mJCNcJN/XegifX7BDrQ8/h9Xh/JnbyMchL0FqXrkg==",
"dev": true,
"license": "CC0-1.0"
},
@@ -4785,9 +4717,9 @@
}
},
"node_modules/@sveltejs/kit": {
- "version": "2.61.1",
- "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.61.1.tgz",
- "integrity": "sha512-Ny8s1SR1TyQS2hD2Rvw0XKzU2Nw1eUF52dTb6T2bdcgz7wSC+Nyb5IwjWYlR4b2dvbbR5NJDiQwHg3rnNseghg==",
+ "version": "2.65.1",
+ "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.65.1.tgz",
+ "integrity": "sha512-Sa1rFYYqBB+zv3rIxAg/CsFskR/x4aj5BY/hvLxBd9r/mqbipxM945As1K3PqsDicJAyekPR0BlWoVIiw2OHYg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4945,9 +4877,9 @@
"license": "MIT"
},
"node_modules/@types/node": {
- "version": "25.9.1",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-25.9.1.tgz",
- "integrity": "sha512-xfrlY7UD5rMJk3ZVJP8BNzS28J36YJg+xp+LPXV1TdWxr8uMH5A860QNxYDGQe/ylDSgjxE52Q9VnO7p75tJxg==",
+ "version": "25.9.3",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-25.9.3.tgz",
+ "integrity": "sha512-603BddQMv3pUcr4U2dhujk83N2tTDVr/34wII2B6bJy6g+8WD6yUb11jszNs0gdi4PesVWl7ABt8nYMVpnLUcg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5092,9 +5024,9 @@
}
},
"node_modules/acorn": {
- "version": "8.16.0",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz",
- "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==",
+ "version": "8.17.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.17.0.tgz",
+ "integrity": "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==",
"license": "MIT",
"bin": {
"acorn": "bin/acorn"
@@ -5255,6 +5187,19 @@
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
+ "node_modules/anynum": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/anynum/-/anynum-1.0.0.tgz",
+ "integrity": "sha512-xjR9/zBVnUOP6ztMIIgShjsxui80nQUQH+5xJnvrYLs+90bF25/KJqaAi8mk+B4RDtX1Nspi6fmp4YTEts8SfA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/NaturalIntelligence"
+ }
+ ],
+ "license": "MIT"
+ },
"node_modules/apache-arrow": {
"version": "21.1.0",
"resolved": "https://registry.npmjs.org/apache-arrow/-/apache-arrow-21.1.0.tgz",
@@ -5276,18 +5221,18 @@
}
},
"node_modules/apache-arrow/node_modules/@types/node": {
- "version": "24.12.4",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-24.12.4.tgz",
- "integrity": "sha512-GUUEShf+PBCGW2KaXwcIt3Yk+e3pkKwWKb9GSyM9WQVE+ep2jzmHdGsHzu4wgcZy5fN9FBdVzjpBQsYlpfpgLA==",
+ "version": "24.13.2",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-24.13.2.tgz",
+ "integrity": "sha512-fRa09kZTgu8o71KFcDjUFuc7F+dEbZYZmkI0mg5YBTRs0yMKjYHsq/c0urDKeDb+D5qVgXOdFcuu+DZPKOITwA==",
"license": "MIT",
"dependencies": {
- "undici-types": "~7.16.0"
+ "undici-types": "~7.18.0"
}
},
"node_modules/apache-arrow/node_modules/undici-types": {
- "version": "7.16.0",
- "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz",
- "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==",
+ "version": "7.18.2",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz",
+ "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==",
"license": "MIT"
},
"node_modules/argparse": {
@@ -5472,9 +5417,9 @@
"license": "MIT"
},
"node_modules/baseline-browser-mapping": {
- "version": "2.10.33",
- "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.33.tgz",
- "integrity": "sha512-bA6+tcSLpz2tIEdDXZPpPTIuxBcC4+w6SieaYyfigIa4h8GlFxbA17v22Vx3JUtuZQj9SgOsnbK+aTBzyDyEuw==",
+ "version": "2.10.37",
+ "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.37.tgz",
+ "integrity": "sha512-girxaJ7WZssDOFhzCGZTDKoTa1gk6A1TbflaYTpykLJ4UU9Fz9kx1aREM8JCuoVHbL8X8T/mJg7w2oYSq72Oig==",
"dev": true,
"license": "Apache-2.0",
"bin": {
@@ -5638,9 +5583,9 @@
}
},
"node_modules/caniuse-lite": {
- "version": "1.0.30001793",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001793.tgz",
- "integrity": "sha512-iwSsYWaCOoh26cV8NwNRViHlrfUvYsHDfRVcbtmw0Kg6PJIZZXwMkj1442FYLBGkeUf1juAsU3DTfxW579mrPA==",
+ "version": "1.0.30001799",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001799.tgz",
+ "integrity": "sha512-hG1bReV+OUU+MOqK4t/ZWI0tZOyz3rqS9XuhOUz1cIcbwBKjOyJEJuw9ER5JuNyqxNk8u/JUVbGibBOL1yrjFw==",
"dev": true,
"funding": [
{
@@ -5792,9 +5737,9 @@
}
},
"node_modules/cheerio/node_modules/undici": {
- "version": "7.26.0",
- "resolved": "https://registry.npmjs.org/undici/-/undici-7.26.0.tgz",
- "integrity": "sha512-3O9Tf67pGhgOv9jM35AbhkXAKi13f3oy3aE4CSgr+TckGeY+/iu97ZXN+J7DpHPzLbVApFd1IFhcnBjREYXYcg==",
+ "version": "7.27.2",
+ "resolved": "https://registry.npmjs.org/undici/-/undici-7.27.2.tgz",
+ "integrity": "sha512-uZsKNuzQxDMUY6M3pIMvy5tvlGmtq8XJ2oLAkfRKGNu+1VQAIvLy2xIVG5ATZl5wDXl/tddByAWCizRbOme+TA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -6021,9 +5966,9 @@
}
},
"node_modules/cosmiconfig": {
- "version": "9.0.1",
- "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.1.tgz",
- "integrity": "sha512-hr4ihw+DBqcvrsEDioRO31Z17x71pUYoNe/4h6Z0wB72p7MU7/9gH8Q3s12NFhHPfYBBOV3qyfUxmr/Yn3shnQ==",
+ "version": "9.0.2",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.2.tgz",
+ "integrity": "sha512-gtTZxTDau1wL7Y7zifc2dd8jHSK/k6BTx/2Xp/BpdlAdnlYWFVt7qhJqgwi7637yRwRQ3qL4ZidbB4I8tA5VOg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6422,9 +6367,9 @@
}
},
"node_modules/electron-to-chromium": {
- "version": "1.5.364",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.364.tgz",
- "integrity": "sha512-G/dYE3+AYhyHwzTwg8UbnXf7zqMERYh7l2jJ3QujhFsH8agSYwtnGAR2aZ7f0AakIKJXd5En/Hre4igIUrdlYw==",
+ "version": "1.5.372",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.372.tgz",
+ "integrity": "sha512-M3yhbAlilnwqC8D21t28UCDGHyitShTmmLRU/H+b74P6Ski16Nb9HONYEaVpMj/pwC7BEo5B95FpjODLCWbtfA==",
"dev": true,
"license": "ISC"
},
@@ -6539,9 +6484,9 @@
}
},
"node_modules/es-toolkit": {
- "version": "1.47.0",
- "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.47.0.tgz",
- "integrity": "sha512-n1GuoD0WEQZMBk5tttoZSqwgyLx01oqa5XsBmCHwPyNe1S9jPBEmtR2pSgp2kJuWE3ciFZ6yRHmY4pM4C3OOkw==",
+ "version": "1.47.1",
+ "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.47.1.tgz",
+ "integrity": "sha512-5RAqEwf4P4E17p+W75KLOWw/nOvKZzSQpxM32IpI2KZLaVonjTrZ0Ai5ghMaVI9eKC2p8eoQgcBdkEDgzFk6+Q==",
"dev": true,
"license": "MIT",
"workspaces": [
@@ -6550,9 +6495,9 @@
]
},
"node_modules/esbuild": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.0.tgz",
- "integrity": "sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz",
+ "integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==",
"hasInstallScript": true,
"license": "MIT",
"bin": {
@@ -6562,32 +6507,32 @@
"node": ">=18"
},
"optionalDependencies": {
- "@esbuild/aix-ppc64": "0.28.0",
- "@esbuild/android-arm": "0.28.0",
- "@esbuild/android-arm64": "0.28.0",
- "@esbuild/android-x64": "0.28.0",
- "@esbuild/darwin-arm64": "0.28.0",
- "@esbuild/darwin-x64": "0.28.0",
- "@esbuild/freebsd-arm64": "0.28.0",
- "@esbuild/freebsd-x64": "0.28.0",
- "@esbuild/linux-arm": "0.28.0",
- "@esbuild/linux-arm64": "0.28.0",
- "@esbuild/linux-ia32": "0.28.0",
- "@esbuild/linux-loong64": "0.28.0",
- "@esbuild/linux-mips64el": "0.28.0",
- "@esbuild/linux-ppc64": "0.28.0",
- "@esbuild/linux-riscv64": "0.28.0",
- "@esbuild/linux-s390x": "0.28.0",
- "@esbuild/linux-x64": "0.28.0",
- "@esbuild/netbsd-arm64": "0.28.0",
- "@esbuild/netbsd-x64": "0.28.0",
- "@esbuild/openbsd-arm64": "0.28.0",
- "@esbuild/openbsd-x64": "0.28.0",
- "@esbuild/openharmony-arm64": "0.28.0",
- "@esbuild/sunos-x64": "0.28.0",
- "@esbuild/win32-arm64": "0.28.0",
- "@esbuild/win32-ia32": "0.28.0",
- "@esbuild/win32-x64": "0.28.0"
+ "@esbuild/aix-ppc64": "0.28.1",
+ "@esbuild/android-arm": "0.28.1",
+ "@esbuild/android-arm64": "0.28.1",
+ "@esbuild/android-x64": "0.28.1",
+ "@esbuild/darwin-arm64": "0.28.1",
+ "@esbuild/darwin-x64": "0.28.1",
+ "@esbuild/freebsd-arm64": "0.28.1",
+ "@esbuild/freebsd-x64": "0.28.1",
+ "@esbuild/linux-arm": "0.28.1",
+ "@esbuild/linux-arm64": "0.28.1",
+ "@esbuild/linux-ia32": "0.28.1",
+ "@esbuild/linux-loong64": "0.28.1",
+ "@esbuild/linux-mips64el": "0.28.1",
+ "@esbuild/linux-ppc64": "0.28.1",
+ "@esbuild/linux-riscv64": "0.28.1",
+ "@esbuild/linux-s390x": "0.28.1",
+ "@esbuild/linux-x64": "0.28.1",
+ "@esbuild/netbsd-arm64": "0.28.1",
+ "@esbuild/netbsd-x64": "0.28.1",
+ "@esbuild/openbsd-arm64": "0.28.1",
+ "@esbuild/openbsd-x64": "0.28.1",
+ "@esbuild/openharmony-arm64": "0.28.1",
+ "@esbuild/sunos-x64": "0.28.1",
+ "@esbuild/win32-arm64": "0.28.1",
+ "@esbuild/win32-ia32": "0.28.1",
+ "@esbuild/win32-x64": "0.28.1"
}
},
"node_modules/escalade": {
@@ -6628,9 +6573,9 @@
}
},
"node_modules/esrap": {
- "version": "2.2.9",
- "resolved": "https://registry.npmjs.org/esrap/-/esrap-2.2.9.tgz",
- "integrity": "sha512-4KijP+NxCWthMCUC3qHbE6n4vCjqgJS1uAYKhuT/GWfFTf1Qyive2TgOjep+gzbSzRfnNyaN/UU9YmdOt8Eg0A==",
+ "version": "2.2.11",
+ "resolved": "https://registry.npmjs.org/esrap/-/esrap-2.2.11.tgz",
+ "integrity": "sha512-gPdx+I+BjYEinNMQaBXFjbaJVyoPMU4ZODg5mE+M4DqVG9VusAVHHjcBX+zqyITlI0DIARwDMMzZwAWj36dRoQ==",
"license": "MIT",
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.4.15"
@@ -8628,16 +8573,16 @@
}
},
"node_modules/miniflare": {
- "version": "4.20260526.0",
- "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-4.20260526.0.tgz",
- "integrity": "sha512-JYQ7jPZZWoaaj9jWHb8Ucp6Cu2SbDVqIsAJhumqdzzLkkfq0pYkDeino/sZfW1ixJWPjv/C44zjm9gVJC2izCA==",
+ "version": "4.20260611.0",
+ "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-4.20260611.0.tgz",
+ "integrity": "sha512-i+JwEo8vN96naz1WL3ntFgFyRluBDYL408zwhHKvR2jefJ464KsZ/gCmJAQ5k+oaWeb5Ug+s7yne5AyiAEswjg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@cspotcode/source-map-support": "0.8.1",
- "sharp": "^0.34.5",
+ "sharp": "0.34.5",
"undici": "7.24.8",
- "workerd": "1.20260526.1",
+ "workerd": "1.20260611.1",
"ws": "8.20.1",
"youch": "4.1.0-beta.10"
},
@@ -8862,9 +8807,9 @@
}
},
"node_modules/node-releases": {
- "version": "2.0.46",
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.46.tgz",
- "integrity": "sha512-GYVXHE2KnrzAfsAjl4uP++evGFCrAU1jta4ubEjIG7YWt/64Gqv66a30yKwWczVjA6j3bM4nBwH7Pk1JmDHaxQ==",
+ "version": "2.0.47",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.47.tgz",
+ "integrity": "sha512-Uzmd6LXpouKo8EUK68IjH4+E01w/hXyV3R3g/geCJo+rXLNfh1xucB+LOzYEOQPSiUK3h/xZf0cQGcSsmyL2Og==",
"dev": true,
"license": "MIT",
"engines": {
@@ -8960,15 +8905,18 @@
"license": "MIT"
},
"node_modules/obug": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz",
- "integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==",
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.3.tgz",
+ "integrity": "sha512-9miFgM2OFba7hB+pRgvtV84pYTBaoTHohvmIgiRt6dRIzbwEOIaNaP+dIlGs2fNFoB0SeISs0Jz5WFVRid6Xyg==",
"dev": true,
"funding": [
"https://github.com/sponsors/sxzz",
"https://opencollective.com/debug"
],
- "license": "MIT"
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.20.0"
+ }
},
"node_modules/once": {
"version": "1.4.0",
@@ -9330,11 +9278,10 @@
"license": "ISC"
},
"node_modules/protobufjs": {
- "version": "8.5.0",
- "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-8.5.0.tgz",
- "integrity": "sha512-df1jWDPA5VIBNRtuAHjqr09f2qN5D4Vke1wYqOQg1XJ7ZDpA7BD6L7E4tyChgGRLB5hqk2m79Zsy0WHwV9a84A==",
+ "version": "8.6.3",
+ "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-8.6.3.tgz",
+ "integrity": "sha512-alQyzT0j401LGBtwsqu6uprjR6pfNH1UJf9N6GBFMjIcd+HzTe0/HrjAbFCqun+zvnfLarrxAtMM2xvZ+kFZ5A==",
"dev": true,
- "hasInstallScript": true,
"license": "BSD-3-Clause",
"dependencies": {
"long": "^5.3.2"
@@ -9558,66 +9505,6 @@
"@rolldown/binding-win32-x64-msvc": "1.0.3"
}
},
- "node_modules/rosie-skills": {
- "version": "0.6.4",
- "resolved": "https://registry.npmjs.org/rosie-skills/-/rosie-skills-0.6.4.tgz",
- "integrity": "sha512-ojfhSiQRdZ2QyWbmKAHOSAUbaLYrTc5zIH7mS1jKoP8KCFSQddwVhMyFqldckTeybTfW3zNcsZzyOTzGTN1SBA==",
- "dev": true,
- "license": "BSD-3-Clause",
- "bin": {
- "rosie-skills": "dist/bin.js"
- },
- "engines": {
- "node": ">=18"
- },
- "optionalDependencies": {
- "rosie-skills-darwin-arm64": "0.6.4",
- "rosie-skills-freebsd-x64": "0.6.4",
- "rosie-skills-linux-x64": "0.6.4"
- }
- },
- "node_modules/rosie-skills-darwin-arm64": {
- "version": "0.6.4",
- "resolved": "https://registry.npmjs.org/rosie-skills-darwin-arm64/-/rosie-skills-darwin-arm64-0.6.4.tgz",
- "integrity": "sha512-rn1s5hqFKcxeiDEWWoFa1hdGPshR8TkwHLzy/cBavb9XJNAaUxbe3oQ78W9sQkRHAgRyzJYyk9tw68Qrdnizgg==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "BSD-3-Clause",
- "optional": true,
- "os": [
- "darwin"
- ]
- },
- "node_modules/rosie-skills-freebsd-x64": {
- "version": "0.6.4",
- "resolved": "https://registry.npmjs.org/rosie-skills-freebsd-x64/-/rosie-skills-freebsd-x64-0.6.4.tgz",
- "integrity": "sha512-SxCRduPBMtfjkQ+q56Yw9OLA3PyaqoALzt7kER7IDKuUVfM2O/1w8sa5xhTDiCvWkZJixnH5d5Ya6KT+/Mwcng==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "BSD-3-Clause",
- "optional": true,
- "os": [
- "freebsd"
- ]
- },
- "node_modules/rosie-skills-linux-x64": {
- "version": "0.6.4",
- "resolved": "https://registry.npmjs.org/rosie-skills-linux-x64/-/rosie-skills-linux-x64-0.6.4.tgz",
- "integrity": "sha512-D9Y9mfu7goB0s0X59uU3hcFeUTef3VbpCIDwFMzyvJrAq3XhRACWBDMHQsHlyWdHxTXPX/ILyW65RXyrJlgqng==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "BSD-3-Clause",
- "optional": true,
- "os": [
- "linux"
- ]
- },
"node_modules/run-parallel": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
@@ -9720,9 +9607,9 @@
"license": "MIT"
},
"node_modules/semver": {
- "version": "7.8.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.1.tgz",
- "integrity": "sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==",
+ "version": "7.8.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.4.tgz",
+ "integrity": "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==",
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
@@ -9812,15 +9699,15 @@
}
},
"node_modules/side-channel": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
- "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz",
+ "integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
- "object-inspect": "^1.13.3",
- "side-channel-list": "^1.0.0",
+ "object-inspect": "^1.13.4",
+ "side-channel-list": "^1.0.1",
"side-channel-map": "^1.0.1",
"side-channel-weakmap": "^1.0.2"
},
@@ -10114,9 +10001,9 @@
}
},
"node_modules/strnum": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.3.0.tgz",
- "integrity": "sha512-ums3KNd42PGyx5xaoVTO1mjU1bH3NpY4vsrVlnv9PNGqQj8wd7rJ6nEypLrJ7z5vxK5RP0yMLo6J/Gsm62DI5Q==",
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.4.0.tgz",
+ "integrity": "sha512-sHrVyWWdq28RbhjuJdZsA1SnGRJV6NiXbk6AXBxDOsgAcA+lmpUZCYjOdLBxkXMwis6RRe7dlZt4VlIWFVzkmg==",
"dev": true,
"funding": [
{
@@ -10124,7 +10011,10 @@
"url": "https://github.com/sponsors/NaturalIntelligence"
}
],
- "license": "MIT"
+ "license": "MIT",
+ "dependencies": {
+ "anynum": "^1.0.0"
+ }
},
"node_modules/supports-color": {
"version": "7.2.0",
@@ -10139,9 +10029,9 @@
}
},
"node_modules/svelte": {
- "version": "5.56.0",
- "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.56.0.tgz",
- "integrity": "sha512-kTXr26t1bchFp28ROrb957LtbujpBmBDibmqMGziVpUs7awBi96TGgX6SovrA8BNoEUDVRK2Fb9FkeYlGspoVg==",
+ "version": "5.56.3",
+ "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.56.3.tgz",
+ "integrity": "sha512-w7JvrM5IFl5cmfbY0TLik9o7mjRUJmRMhOR51tBPu708Gr/MjbGs7VnJnr/B0CaXeI4vtnOh7RKxDr0cwhMdDA==",
"license": "MIT",
"dependencies": {
"@jridgewell/remapping": "^2.3.4",
@@ -10155,7 +10045,7 @@
"clsx": "^2.1.1",
"devalue": "^5.8.1",
"esm-env": "^1.2.1",
- "esrap": "^2.2.9",
+ "esrap": "^2.2.11",
"is-reference": "^3.0.3",
"locate-character": "^3.0.0",
"magic-string": "^0.30.11",
@@ -10454,9 +10344,9 @@
"license": "MIT"
},
"node_modules/undici": {
- "version": "8.3.0",
- "resolved": "https://registry.npmjs.org/undici/-/undici-8.3.0.tgz",
- "integrity": "sha512-TkUDgb6tl7KOGZ+7e8E3d2FYgUQgF6z5YypqjWmixVQSQERFcVrVg0ySADm2LVLRh5ljAaHTCR5Fmz3Q34rB7Q==",
+ "version": "8.4.1",
+ "resolved": "https://registry.npmjs.org/undici/-/undici-8.4.1.tgz",
+ "integrity": "sha512-RNHlB4fxZK0IrkhBsxhlbx7s8kFWwr7rzzOqj5nvZugw3ig3RsB7KW3zVlV0eu8POl+rx5d1hmL7rRg0z1owow==",
"dev": true,
"license": "MIT",
"engines": {
@@ -10748,15 +10638,15 @@
}
},
"node_modules/vite-plugin-mkcert": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/vite-plugin-mkcert/-/vite-plugin-mkcert-2.0.0.tgz",
- "integrity": "sha512-+5roXeOT91WRO3NKFRcDZKEHhze/1uahSSKOIq3vz2w19mJojBcyOo0JyLRHbME31Ym5qPRNJ8CwKO0mu4RJ2Q==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/vite-plugin-mkcert/-/vite-plugin-mkcert-2.1.0.tgz",
+ "integrity": "sha512-UQS5iyknruwCsvqDPsKRyHIVSVfv/iGdRPmUPaM1JRwNJo8wo/MubzJ66ckWwOLxFU4wW90oZq9GviV87nRHsg==",
"dev": true,
"license": "MIT",
"dependencies": {
"debug": "^4.4.3",
"supports-color": "^10.2.2",
- "undici": "^8.0.2"
+ "undici": "^8.3.0"
},
"engines": {
"node": ">=22.19.0"
@@ -10922,9 +10812,9 @@
}
},
"node_modules/workerd": {
- "version": "1.20260526.1",
- "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20260526.1.tgz",
- "integrity": "sha512-IHzymht98p10JH1zzwdCpbViAqw97HrwKl7+KfZeASFMsYSrIsAULWdPn0LRC5FTUzBpamLNyKCCKxbgXHgRHQ==",
+ "version": "1.20260611.1",
+ "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20260611.1.tgz",
+ "integrity": "sha512-CS/640T7pIJ2HYX6x2DwKFGbcSckAWN3tgcdq+ptB6SaqjWUhlzIgA/YhPuwIU+/NnMnGpqOFX/hC18Oyge63w==",
"dev": true,
"hasInstallScript": true,
"license": "Apache-2.0",
@@ -10935,11 +10825,11 @@
"node": ">=16"
},
"optionalDependencies": {
- "@cloudflare/workerd-darwin-64": "1.20260526.1",
- "@cloudflare/workerd-darwin-arm64": "1.20260526.1",
- "@cloudflare/workerd-linux-64": "1.20260526.1",
- "@cloudflare/workerd-linux-arm64": "1.20260526.1",
- "@cloudflare/workerd-windows-64": "1.20260526.1"
+ "@cloudflare/workerd-darwin-64": "1.20260611.1",
+ "@cloudflare/workerd-darwin-arm64": "1.20260611.1",
+ "@cloudflare/workerd-linux-64": "1.20260611.1",
+ "@cloudflare/workerd-linux-arm64": "1.20260611.1",
+ "@cloudflare/workerd-windows-64": "1.20260611.1"
}
},
"node_modules/worktop": {
@@ -10957,9 +10847,9 @@
}
},
"node_modules/wrangler": {
- "version": "4.95.0",
- "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-4.95.0.tgz",
- "integrity": "sha512-vgXzFVSCdUbeCadgVXvu8fK5tzNm8T9W+7lriyGWZMx0B1+CAdr4d8JTlZszHfgjypRAHmAxb49etZGIRD9pgg==",
+ "version": "4.100.0",
+ "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-4.100.0.tgz",
+ "integrity": "sha512-dSQO7DO+mD6XDzkVWIWBoGLO3yw+lacWSc/KhFvd7pgfpth+kX98qb5SGRHZN8ACCDhhfwzDLXwB6qHsIHhfBg==",
"dev": true,
"license": "MIT OR Apache-2.0",
"dependencies": {
@@ -10967,13 +10857,13 @@
"@cloudflare/unenv-preset": "2.16.1",
"blake3-wasm": "2.1.5",
"esbuild": "0.27.3",
- "miniflare": "4.20260526.0",
+ "miniflare": "4.20260611.0",
"path-to-regexp": "6.3.0",
- "rosie-skills": "^0.6.3",
"unenv": "2.0.0-rc.24",
- "workerd": "1.20260526.1"
+ "workerd": "1.20260611.1"
},
"bin": {
+ "cf-wrangler": "bin/cf-wrangler.js",
"wrangler": "bin/wrangler.js",
"wrangler2": "bin/wrangler.js"
},
@@ -10981,10 +10871,10 @@
"node": ">=22.0.0"
},
"optionalDependencies": {
- "fsevents": "~2.3.2"
+ "fsevents": "2.3.3"
},
"peerDependencies": {
- "@cloudflare/workers-types": "^4.20260526.1"
+ "@cloudflare/workers-types": "^4.20260611.1"
},
"peerDependenciesMeta": {
"@cloudflare/workers-types": {
diff --git a/package.json b/package.json
index 90aa530..4600fc8 100644
--- a/package.json
+++ b/package.json
@@ -34,7 +34,7 @@
"test:sast:semgrep": "semgrep scan --config auto --error",
"test:sast:trivy": "trivy fs --scanners vuln,license --include-dev-deps --ignored-licenses 0BSD,Apache-2.0,BSD-1-Clause,BSD-2-Clause,BSD-3-Clause,CC0-1.0,CC-BY-4.0,ISC,MIT,MPL-2.0,BlueOak-1.0.0,Unlicense,Python-2.0,LGPL-3.0-or-later --exit-code 1 --skip-files '**/bun.lock' --disable-telemetry .",
"test:sast:trufflehog": "trufflehog filesystem --only-verified --log-level=-1 ./",
- "test:sast:zizmor": "zizmor .github/workflows/",
+ "test:sast:zizmor": "zizmor .github",
"test:types": "tstyche",
"test:mutation": "npm run test:mutation --workspaces --if-present",
"test:perf": "node --test --test-concurrency=1 'packages/**/*.perf.js'",
diff --git a/packages/aws/s3.js b/packages/aws/s3.js
index b5698fe..b3a22f6 100644
--- a/packages/aws/s3.js
+++ b/packages/aws/s3.js
@@ -185,13 +185,8 @@ const _concatBuffers = (buffers) => {
return tmp.buffer;
};
const _arrayBufferToBase64 = (buffer) => {
- let binary = "";
const bytes = new Uint8Array(buffer);
- const len = bytes.byteLength;
- for (let i = 0; i < len; i++) {
- binary += String.fromCharCode(bytes[i]);
- }
- return btoa(binary);
+ return btoa(String.fromCharCode(...bytes));
};
export default {
From 1f44d8532860d79c1bf55465594115d9e704f162 Mon Sep 17 00:00:00 2001
From: will Farrell
Date: Mon, 15 Jun 2026 06:41:36 -0600
Subject: [PATCH 16/27] fix: perf improvement
Signed-off-by: will Farrell
---
packages/encrypt/index.web.js | 23 +++++++++--------------
1 file changed, 9 insertions(+), 14 deletions(-)
diff --git a/packages/encrypt/index.web.js b/packages/encrypt/index.web.js
index 05c8669..54b8b3c 100644
--- a/packages/encrypt/index.web.js
+++ b/packages/encrypt/index.web.js
@@ -3,6 +3,8 @@
/* global crypto */
import { createTransformStream } from "@datastream/core";
+const textEncoder = new TextEncoder();
+
const DEFAULT_MAX_INPUT_SIZE = 64 * 1024 * 1024; // 64MB
const expectedIvSize = {
@@ -67,8 +69,7 @@ const validateAad = (aad, algorithm) => {
const concatBuffers = (chunks) => {
let totalLength = 0;
const buffers = chunks.map((chunk) => {
- const buf =
- chunk instanceof Uint8Array ? chunk : new TextEncoder().encode(chunk);
+ const buf = chunk instanceof Uint8Array ? chunk : textEncoder.encode(chunk);
totalLength += buf.byteLength;
return buf;
});
@@ -132,8 +133,7 @@ const aesGcmEncrypt = async (
let inputSize = 0;
let authTag;
const transform = (chunk) => {
- const buf =
- chunk instanceof Uint8Array ? chunk : new TextEncoder().encode(chunk);
+ const buf = chunk instanceof Uint8Array ? chunk : textEncoder.encode(chunk);
inputSize += buf.byteLength;
if (inputSize > maxInputSize) {
throw new Error(
@@ -189,8 +189,7 @@ const aesGcmDecrypt = async (
const chunks = [];
let inputSize = 0;
const transform = (chunk) => {
- const buf =
- chunk instanceof Uint8Array ? chunk : new TextEncoder().encode(chunk);
+ const buf = chunk instanceof Uint8Array ? chunk : textEncoder.encode(chunk);
// Bound memory before buffering/decryption: maxOutputSize alone is checked
// only post-decryption, after the full ciphertext is already allocated.
inputSize += buf.byteLength;
@@ -250,8 +249,7 @@ const aesCtrEncrypt = async (
let blockOffset = 0n;
let inputSize = 0;
const transform = async (chunk, enqueue) => {
- const buf =
- chunk instanceof Uint8Array ? chunk : new TextEncoder().encode(chunk);
+ const buf = chunk instanceof Uint8Array ? chunk : textEncoder.encode(chunk);
inputSize += buf.byteLength;
if (inputSize > maxInputSize) {
throw new Error(
@@ -295,8 +293,7 @@ const aesCtrDecrypt = async (
let blockOffset = 0n;
let outputSize = 0;
const transform = async (chunk, enqueue) => {
- const buf =
- chunk instanceof Uint8Array ? chunk : new TextEncoder().encode(chunk);
+ const buf = chunk instanceof Uint8Array ? chunk : textEncoder.encode(chunk);
const counter = incrementCounter(iv, blockOffset);
// length:128 — see aesCtrEncrypt; the full 128-bit counter must match.
const decrypted = await crypto.subtle.decrypt(
@@ -334,8 +331,7 @@ const chacha20Encrypt = async (
let inputSize = 0;
let authTag;
const transform = (chunk) => {
- const buf =
- chunk instanceof Uint8Array ? chunk : new TextEncoder().encode(chunk);
+ const buf = chunk instanceof Uint8Array ? chunk : textEncoder.encode(chunk);
inputSize += buf.byteLength;
if (inputSize > maxInputSize) {
throw new Error(
@@ -378,8 +374,7 @@ const chacha20Decrypt = async (
const chunks = [];
let inputSize = 0;
const transform = (chunk) => {
- const buf =
- chunk instanceof Uint8Array ? chunk : new TextEncoder().encode(chunk);
+ const buf = chunk instanceof Uint8Array ? chunk : textEncoder.encode(chunk);
// Bound memory before buffering/decryption (maxOutputSize is post-decrypt).
inputSize += buf.byteLength;
if (inputSize > maxInputSize) {
From 74f0971ab41c7955417ac5b5d5fd91692b31a149 Mon Sep 17 00:00:00 2001
From: will Farrell
Date: Mon, 15 Jun 2026 06:52:45 -0600
Subject: [PATCH 17/27] feat: add in new batch processing streams
Signed-off-by: will Farrell
---
packages/arrow/README.md | 52 +
packages/arrow/index.d.ts | 42 +
packages/arrow/index.fuzz.js | 176 ++
packages/arrow/index.js | 296 +++
packages/arrow/index.perf.js | 125 +
packages/arrow/index.test.js | 822 +++++++
packages/arrow/index.tst.ts | 74 +
packages/arrow/package.json | 70 +
packages/duckdb/README.md | 52 +
packages/duckdb/index.d.ts | 27 +
packages/duckdb/index.fuzz.js | 176 ++
packages/duckdb/index.node.js | 271 +++
packages/duckdb/index.perf.js | 101 +
packages/duckdb/index.test.js | 2016 +++++++++++++++++
packages/duckdb/index.tst.ts | 50 +
packages/duckdb/index.web.js | 186 ++
packages/duckdb/package.json | 91 +
packages/kafka/README.md | 52 +
packages/kafka/index.d.ts | 82 +
packages/kafka/index.fuzz.js | 326 +++
packages/kafka/index.node.js | 271 +++
packages/kafka/index.perf.js | 228 ++
packages/kafka/index.test.js | 1596 +++++++++++++
packages/kafka/index.tst.ts | 71 +
packages/kafka/index.web.js | 24 +
packages/kafka/package.json | 81 +
packages/protobuf/README.md | 52 +
packages/protobuf/_old.js | 0
packages/protobuf/index.d.ts | 50 +
packages/protobuf/index.fuzz.js | 234 ++
packages/protobuf/index.js | 169 ++
packages/protobuf/index.perf.js | 124 +
packages/protobuf/index.test.js | 290 +++
packages/protobuf/index.tst.ts | 66 +
packages/protobuf/package.json | 81 +
packages/schema-registry/README.md | 52 +
packages/schema-registry/index.d.ts | 54 +
packages/schema-registry/index.fuzz.js | 242 ++
packages/schema-registry/index.js | 380 ++++
packages/schema-registry/index.perf.js | 142 ++
packages/schema-registry/index.test.js | 1377 +++++++++++
packages/schema-registry/index.tst.ts | 73 +
packages/schema-registry/package.json | 71 +
.../src/routes/docs/packages/arrow/+page.md | 123 +
.../src/routes/docs/packages/duckdb/+page.md | 124 +
.../src/routes/docs/packages/kafka/+page.md | 128 ++
.../routes/docs/packages/protobuf/+page.md | 110 +
.../docs/packages/schema-registry/+page.md | 98 +
48 files changed, 11398 insertions(+)
create mode 100644 packages/arrow/README.md
create mode 100644 packages/arrow/index.d.ts
create mode 100644 packages/arrow/index.fuzz.js
create mode 100644 packages/arrow/index.js
create mode 100644 packages/arrow/index.perf.js
create mode 100644 packages/arrow/index.test.js
create mode 100644 packages/arrow/index.tst.ts
create mode 100644 packages/arrow/package.json
create mode 100644 packages/duckdb/README.md
create mode 100644 packages/duckdb/index.d.ts
create mode 100644 packages/duckdb/index.fuzz.js
create mode 100644 packages/duckdb/index.node.js
create mode 100644 packages/duckdb/index.perf.js
create mode 100644 packages/duckdb/index.test.js
create mode 100644 packages/duckdb/index.tst.ts
create mode 100644 packages/duckdb/index.web.js
create mode 100644 packages/duckdb/package.json
create mode 100644 packages/kafka/README.md
create mode 100644 packages/kafka/index.d.ts
create mode 100644 packages/kafka/index.fuzz.js
create mode 100644 packages/kafka/index.node.js
create mode 100644 packages/kafka/index.perf.js
create mode 100644 packages/kafka/index.test.js
create mode 100644 packages/kafka/index.tst.ts
create mode 100644 packages/kafka/index.web.js
create mode 100644 packages/kafka/package.json
create mode 100644 packages/protobuf/README.md
create mode 100644 packages/protobuf/_old.js
create mode 100644 packages/protobuf/index.d.ts
create mode 100644 packages/protobuf/index.fuzz.js
create mode 100644 packages/protobuf/index.js
create mode 100644 packages/protobuf/index.perf.js
create mode 100644 packages/protobuf/index.test.js
create mode 100644 packages/protobuf/index.tst.ts
create mode 100644 packages/protobuf/package.json
create mode 100644 packages/schema-registry/README.md
create mode 100644 packages/schema-registry/index.d.ts
create mode 100644 packages/schema-registry/index.fuzz.js
create mode 100644 packages/schema-registry/index.js
create mode 100644 packages/schema-registry/index.perf.js
create mode 100644 packages/schema-registry/index.test.js
create mode 100644 packages/schema-registry/index.tst.ts
create mode 100644 packages/schema-registry/package.json
create mode 100644 websites/datastream.js.org/src/routes/docs/packages/arrow/+page.md
create mode 100644 websites/datastream.js.org/src/routes/docs/packages/duckdb/+page.md
create mode 100644 websites/datastream.js.org/src/routes/docs/packages/kafka/+page.md
create mode 100644 websites/datastream.js.org/src/routes/docs/packages/protobuf/+page.md
create mode 100644 websites/datastream.js.org/src/routes/docs/packages/schema-registry/+page.md
diff --git a/packages/arrow/README.md b/packages/arrow/README.md
new file mode 100644
index 0000000..799be45
--- /dev/null
+++ b/packages/arrow/README.md
@@ -0,0 +1,52 @@
+
+ <datastream> `arrow`
+
+ Apache Arrow record batch transform streams.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+You can read the documentation at: https://datastream.js.org
+
+
+
+## Install
+
+To install datastream you can use NPM:
+
+```bash
+npm install --save @datastream/arrow
+```
+
+
+## Documentation and examples
+
+For documentation and examples, refer to the main [datastream monorepo on GitHub](https://github.com/willfarrell/datastream) or [datastream official website](https://datastream.js.org).
+
+
+## Contributing
+
+Everyone is very welcome to contribute to this repository. Feel free to [raise issues](https://github.com/willfarrell/datastream/issues) or to [submit Pull Requests](https://github.com/willfarrell/datastream/pulls).
+
+
+## License
+
+Licensed under [MIT License](LICENSE). Copyright (c) 2026 [will Farrell](https://github.com/willfarrell), and [datastream contributors](https://github.com/willfarrell/datastream/graphs/contributors).
\ No newline at end of file
diff --git a/packages/arrow/index.d.ts b/packages/arrow/index.d.ts
new file mode 100644
index 0000000..84d7dd6
--- /dev/null
+++ b/packages/arrow/index.d.ts
@@ -0,0 +1,42 @@
+// Copyright 2026 will Farrell, and datastream contributors.
+// SPDX-License-Identifier: MIT
+import type {
+ DatastreamPassThrough,
+ DatastreamTransform,
+ ResultStream,
+ StreamOptions,
+} from "@datastream/core";
+import type { RecordBatch, Schema } from "apache-arrow";
+
+export interface ArrowDetectSchemaResult {
+ schema: Schema | null;
+ fields: string[] | null;
+}
+
+export function arrowDetectSchemaStream(
+ options?: { sampleSize?: number; resultKey?: string },
+ streamOptions?: StreamOptions,
+): DatastreamPassThrough & ResultStream;
+
+export function arrowBatchFromArrayStream(
+ options: { schema: Schema | (() => Schema); batchSize?: number },
+ streamOptions?: StreamOptions,
+): DatastreamTransform;
+
+export function arrowBatchFromObjectStream(
+ options: {
+ schema: Schema | (() => Schema);
+ batchSize?: number;
+ },
+ streamOptions?: StreamOptions,
+): DatastreamTransform, RecordBatch>;
+
+export function arrowToArrayStream(
+ options?: Record,
+ streamOptions?: StreamOptions,
+): DatastreamTransform;
+
+export function arrowToObjectStream(
+ options?: Record,
+ streamOptions?: StreamOptions,
+): DatastreamTransform>;
diff --git a/packages/arrow/index.fuzz.js b/packages/arrow/index.fuzz.js
new file mode 100644
index 0000000..53c3d8d
--- /dev/null
+++ b/packages/arrow/index.fuzz.js
@@ -0,0 +1,176 @@
+import test from "node:test";
+import {
+ arrowBatchFromArrayStream,
+ arrowBatchFromObjectStream,
+ arrowDetectSchemaStream,
+ arrowToArrayStream,
+ arrowToObjectStream,
+} from "@datastream/arrow";
+import {
+ createReadableStream,
+ pipejoin,
+ streamToArray,
+} from "@datastream/core";
+import fc from "fast-check";
+
+const catchError = (input, e) => {
+ const expectedErrors = [];
+ if (expectedErrors.includes(e.message)) {
+ return;
+ }
+ console.error(input, e);
+ throw e;
+};
+
+// Helper: run arrowDetectSchemaStream in isolation and return the detected schema.
+// Returns null when the input produces no detectable schema (e.g. empty stream or
+// all-empty objects).
+const detectSchema = async (input) => {
+ const detect = arrowDetectSchemaStream({ sampleSize: 10 });
+ await streamToArray(pipejoin([createReadableStream(input), detect]));
+ return detect.result().value.schema;
+};
+
+// *** arrowDetectSchemaStream *** //
+test("fuzz arrowDetectSchemaStream w/ object array input", async () => {
+ await fc.assert(
+ fc.asyncProperty(fc.array(fc.object({ maxDepth: 0 })), async (input) => {
+ try {
+ await detectSchema(input);
+ } catch (e) {
+ catchError(input, e);
+ }
+ }),
+ {
+ numRuns: 1_000,
+ verbose: 2,
+ examples: [],
+ },
+ );
+});
+
+// *** arrowBatchFromObjectStream via detect *** //
+// Skip when the detected schema is null (empty stream) or has no fields (all-empty
+// objects were sampled), as those are valid edge-cases tested by the unit suite.
+test("fuzz arrowBatchFromObjectStream w/ detected schema", async () => {
+ await fc.assert(
+ fc.asyncProperty(
+ fc.array(fc.object({ maxDepth: 0 }), { minLength: 1 }),
+ async (input) => {
+ try {
+ const schema = await detectSchema(input);
+ if (schema === null || schema.fields.length === 0) {
+ return;
+ }
+ const streams = [
+ createReadableStream(input),
+ arrowBatchFromObjectStream({ schema, batchSize: 50 }),
+ ];
+ await streamToArray(pipejoin(streams));
+ } catch (e) {
+ catchError(input, e);
+ }
+ },
+ ),
+ {
+ numRuns: 1_000,
+ verbose: 2,
+ examples: [],
+ },
+ );
+});
+
+// *** arrowBatchFromArrayStream via detect *** //
+test("fuzz arrowBatchFromArrayStream w/ detected schema", async () => {
+ await fc.assert(
+ fc.asyncProperty(
+ fc.array(
+ fc.array(fc.oneof(fc.integer(), fc.string(), fc.boolean()), {
+ minLength: 1,
+ maxLength: 5,
+ }),
+ { minLength: 1 },
+ ),
+ async (input) => {
+ try {
+ const schema = await detectSchema(input);
+ if (schema === null || schema.fields.length === 0) {
+ return;
+ }
+ const streams = [
+ createReadableStream(input),
+ arrowBatchFromArrayStream({ schema, batchSize: 50 }),
+ ];
+ await streamToArray(pipejoin(streams));
+ } catch (e) {
+ catchError(input, e);
+ }
+ },
+ ),
+ {
+ numRuns: 1_000,
+ verbose: 2,
+ examples: [],
+ },
+ );
+});
+
+// *** detect -> batch -> arrowToObjectStream roundtrip *** //
+test("fuzz arrowToObjectStream roundtrip w/ detected schema", async () => {
+ await fc.assert(
+ fc.asyncProperty(
+ fc.array(fc.object({ maxDepth: 0 }), { minLength: 1 }),
+ async (input) => {
+ try {
+ const schema = await detectSchema(input);
+ if (schema === null || schema.fields.length === 0) {
+ return;
+ }
+ const streams = [
+ createReadableStream(input),
+ arrowBatchFromObjectStream({ schema, batchSize: 50 }),
+ arrowToObjectStream(),
+ ];
+ await streamToArray(pipejoin(streams));
+ } catch (e) {
+ catchError(input, e);
+ }
+ },
+ ),
+ {
+ numRuns: 1_000,
+ verbose: 2,
+ examples: [],
+ },
+ );
+});
+
+// *** detect -> batch -> arrowToArrayStream roundtrip *** //
+test("fuzz arrowToArrayStream roundtrip w/ detected schema", async () => {
+ await fc.assert(
+ fc.asyncProperty(
+ fc.array(fc.object({ maxDepth: 0 }), { minLength: 1 }),
+ async (input) => {
+ try {
+ const schema = await detectSchema(input);
+ if (schema === null || schema.fields.length === 0) {
+ return;
+ }
+ const streams = [
+ createReadableStream(input),
+ arrowBatchFromObjectStream({ schema, batchSize: 50 }),
+ arrowToArrayStream(),
+ ];
+ await streamToArray(pipejoin(streams));
+ } catch (e) {
+ catchError(input, e);
+ }
+ },
+ ),
+ {
+ numRuns: 1_000,
+ verbose: 2,
+ examples: [],
+ },
+ );
+});
diff --git a/packages/arrow/index.js b/packages/arrow/index.js
new file mode 100644
index 0000000..a936363
--- /dev/null
+++ b/packages/arrow/index.js
@@ -0,0 +1,296 @@
+// Copyright 2026 will Farrell, and datastream contributors.
+// SPDX-License-Identifier: MIT
+import { createTransformStream, resolveLazy } from "@datastream/core";
+import {
+ Bool,
+ Field,
+ Float64,
+ Int32,
+ makeBuilder,
+ makeData,
+ RecordBatch,
+ Schema,
+ Struct,
+ TimestampMillisecond,
+ Utf8,
+} from "apache-arrow";
+
+const inferType = (value) => {
+ if (value === null || value === undefined || value === "") return null;
+ if (typeof value === "boolean") return new Bool();
+ if (typeof value === "number") {
+ if (!Number.isInteger(value)) return new Float64();
+ // Integers outside the signed 32-bit range silently wrap inside an Int32
+ // builder, so widen them to Float64 (exact up to 2^53).
+ return value > 2147483647 || value < -2147483648
+ ? new Float64()
+ : new Int32();
+ }
+ if (value instanceof Date) return new TimestampMillisecond();
+ return new Utf8();
+};
+
+const fieldsFromSamples = (samples, fieldNames, isArray) => {
+ return fieldNames.map((name, idx) => {
+ let type = null;
+ for (const sample of samples) {
+ const v = isArray ? sample[idx] : sample[name];
+ type = inferType(v);
+ if (type !== null) break;
+ }
+ return new Field(name, type ?? new Utf8(), true);
+ });
+};
+
+const isTimestampType = (type) => type instanceof TimestampMillisecond;
+
+export const arrowDetectSchemaStream = (
+ { sampleSize = 100, resultKey } = {},
+ streamOptions = {},
+) => {
+ const value = { schema: null, fields: null };
+ const samples = [];
+ let sealed = false;
+
+ const seal = () => {
+ // Nothing to seal until at least one row has been sampled. Once sealed,
+ // `samples` is cleared (below), so this same guard makes a repeat call a
+ // no-op without needing a separate sealed flag here.
+ if (!samples.length) return;
+ const isArray = Array.isArray(samples[0]);
+ let fieldNames;
+ if (isArray) {
+ // Column count is the widest array seen across all sampled rows.
+ let width = 0;
+ for (const sample of samples) {
+ width = Math.max(width, sample.length);
+ }
+ fieldNames = [];
+ for (let i = 0; i < width; i++) fieldNames.push(`column${i}`);
+ } else {
+ // Union the keys across every sampled row (preserving first-seen order),
+ // so columns that only appear in later rows are not dropped.
+ const seen = new Set();
+ fieldNames = [];
+ for (const sample of samples) {
+ for (const key of Object.keys(sample)) {
+ if (!seen.has(key)) {
+ seen.add(key);
+ fieldNames.push(key);
+ }
+ }
+ }
+ }
+ const fields = fieldsFromSamples(samples, fieldNames, isArray);
+ value.schema = new Schema(fields);
+ value.fields = fieldNames;
+ sealed = true;
+ // The sampled rows are no longer needed once the schema is computed;
+ // release them so they are not retained for the stream's lifetime.
+ samples.length = 0;
+ };
+
+ const buffered = [];
+ const transform = (chunk, enqueue) => {
+ if (sealed) {
+ enqueue(chunk);
+ return;
+ }
+ samples.push(chunk);
+ buffered.push(chunk);
+ if (samples.length >= sampleSize) {
+ seal();
+ while (buffered.length) enqueue(buffered.shift());
+ }
+ };
+ const flush = (enqueue) => {
+ // Seal a short stream that never reached sampleSize, then flush whatever is
+ // still buffered. If the stream already sealed mid-stream, `samples` is
+ // empty so seal() is a no-op and `buffered` has already been drained.
+ seal();
+ while (buffered.length) enqueue(buffered.shift());
+ };
+
+ const stream = createTransformStream(transform, flush, streamOptions);
+ stream.result = () => ({ key: resultKey ?? "arrowDetectSchema", value });
+ return stream;
+};
+
+const buildRecordBatch = (schema, builders, length) => {
+ const childrenData = builders.map((b) => b.flush());
+ const structData = makeData({
+ type: new Struct(schema.fields),
+ length,
+ children: childrenData,
+ });
+ return new RecordBatch(schema, structData);
+};
+
+const makeBuilders = (schema) =>
+ schema.fields.map((field) =>
+ makeBuilder({ type: field.type, nullValues: [null, undefined] }),
+ );
+
+// A zero-field schema cannot represent rows: apache-arrow derives a
+// RecordBatch's length from its child columns, so with no columns every batch
+// reports numRows 0 and silently discards every row. Reject it explicitly
+// instead of emitting corrupt empty batches.
+const assertSchema = (name, schema) => {
+ if (!schema) throw new Error(`${name}: schema is required`);
+ if (schema.fields.length === 0)
+ throw new Error(`${name}: schema must have at least one field`);
+ return schema;
+};
+
+export const arrowBatchFromArrayStream = (
+ { schema, batchSize = 10_000 } = {},
+ streamOptions = {},
+) => {
+ let resolvedSchema;
+ let builders;
+ let rowCount = 0;
+
+ const init = () => {
+ if (builders) return;
+ resolvedSchema = assertSchema(
+ "arrowBatchFromArrayStream",
+ resolveLazy(schema),
+ );
+ builders = makeBuilders(resolvedSchema);
+ };
+
+ // Eagerly validate a concrete schema at construction so a missing/misconfigured
+ // schema surfaces at the call site rather than only once rows happen to flow.
+ if (typeof schema !== "function")
+ assertSchema("arrowBatchFromArrayStream", resolveLazy(schema));
+
+ const transform = (row, enqueue) => {
+ init();
+ for (let i = 0, l = builders.length; i < l; i++) {
+ builders[i].append(row[i]);
+ }
+ rowCount++;
+ if (rowCount >= batchSize) {
+ enqueue(buildRecordBatch(resolvedSchema, builders, rowCount));
+ rowCount = 0;
+ }
+ };
+ const flush = (enqueue) => {
+ // Always run init so a missing lazy schema throws even for an empty stream.
+ init();
+ if (rowCount > 0) {
+ enqueue(buildRecordBatch(resolvedSchema, builders, rowCount));
+ rowCount = 0;
+ }
+ };
+
+ return createTransformStream(transform, flush, streamOptions);
+};
+
+export const arrowBatchFromObjectStream = (
+ { schema, batchSize = 10_000 } = {},
+ streamOptions = {},
+) => {
+ let resolvedSchema;
+ let fieldNames;
+ let builders;
+ let rowCount = 0;
+
+ const init = () => {
+ if (builders) return;
+ resolvedSchema = assertSchema(
+ "arrowBatchFromObjectStream",
+ resolveLazy(schema),
+ );
+ fieldNames = resolvedSchema.fields.map((f) => f.name);
+ builders = makeBuilders(resolvedSchema);
+ };
+
+ // Eagerly validate a concrete schema at construction so a missing/misconfigured
+ // schema surfaces at the call site rather than only once rows happen to flow.
+ if (typeof schema !== "function")
+ assertSchema("arrowBatchFromObjectStream", resolveLazy(schema));
+
+ const transform = (row, enqueue) => {
+ init();
+ for (let i = 0, l = builders.length; i < l; i++) {
+ builders[i].append(row[fieldNames[i]]);
+ }
+ rowCount++;
+ if (rowCount >= batchSize) {
+ enqueue(buildRecordBatch(resolvedSchema, builders, rowCount));
+ rowCount = 0;
+ }
+ };
+ const flush = (enqueue) => {
+ // Always run init so a missing lazy schema throws even for an empty stream.
+ init();
+ if (rowCount > 0) {
+ enqueue(buildRecordBatch(resolvedSchema, builders, rowCount));
+ rowCount = 0;
+ }
+ };
+
+ return createTransformStream(transform, flush, streamOptions);
+};
+
+// Read one cell, restoring Date for timestamp columns (which Arrow vectors
+// otherwise return as raw epoch-millisecond numbers) so round-trips preserve type.
+const readCell = (col, isTimestamp, r) => {
+ const value = col.get(r);
+ if (isTimestamp && typeof value === "number") return new Date(value);
+ return value;
+};
+
+export const arrowToArrayStream = (_options = {}, streamOptions = {}) => {
+ const transform = (batch, enqueue) => {
+ const colCount = batch.schema.fields.length;
+ const cols = [];
+ const isTimestamp = [];
+ for (let i = 0; i < colCount; i++) {
+ cols.push(batch.getChildAt(i));
+ isTimestamp.push(isTimestampType(batch.schema.fields[i].type));
+ }
+ const rowCount = batch.numRows;
+ for (let r = 0; r < rowCount; r++) {
+ // The row is fully populated by the loop below, so build it by pushing
+ // each cell rather than pre-sizing (which is observationally identical).
+ const row = [];
+ for (let i = 0; i < colCount; i++)
+ row.push(readCell(cols[i], isTimestamp[i], r));
+ enqueue(row);
+ }
+ };
+ return createTransformStream(transform, streamOptions);
+};
+
+export const arrowToObjectStream = (_options = {}, streamOptions = {}) => {
+ const transform = (batch, enqueue) => {
+ const fields = batch.schema.fields;
+ const colCount = fields.length;
+ const names = [];
+ const cols = [];
+ const isTimestamp = [];
+ for (let i = 0; i < colCount; i++) {
+ names.push(fields[i].name);
+ cols.push(batch.getChildAt(i));
+ isTimestamp.push(isTimestampType(fields[i].type));
+ }
+ const rowCount = batch.numRows;
+ for (let r = 0; r < rowCount; r++) {
+ const row = {};
+ for (let i = 0; i < colCount; i++)
+ row[names[i]] = readCell(cols[i], isTimestamp[i], r);
+ enqueue(row);
+ }
+ };
+ return createTransformStream(transform, streamOptions);
+};
+
+export default {
+ detectSchemaStream: arrowDetectSchemaStream,
+ batchFromArrayStream: arrowBatchFromArrayStream,
+ batchFromObjectStream: arrowBatchFromObjectStream,
+ toArrayStream: arrowToArrayStream,
+ toObjectStream: arrowToObjectStream,
+};
diff --git a/packages/arrow/index.perf.js b/packages/arrow/index.perf.js
new file mode 100644
index 0000000..a0aff3f
--- /dev/null
+++ b/packages/arrow/index.perf.js
@@ -0,0 +1,125 @@
+import test from "node:test";
+import {
+ arrowBatchFromObjectStream,
+ arrowDetectSchemaStream,
+ arrowToArrayStream,
+ arrowToObjectStream,
+} from "@datastream/arrow";
+import {
+ createReadableStream,
+ pipejoin,
+ streamToArray,
+} from "@datastream/core";
+import { Field, Int32, Schema, Utf8 } from "apache-arrow";
+import { Bench } from "tinybench";
+
+// -- Data generators --
+
+const ITEMS = 10_000;
+const time = Number(process.env.BENCH_TIME ?? 5_000);
+
+const usersSchema = new Schema([
+ new Field("id", new Int32(), true),
+ new Field("name", new Utf8(), true),
+]);
+
+const objects = Array.from({ length: ITEMS }, (_, i) => ({
+ id: i,
+ name: `user_${i}`,
+}));
+
+// -- Tests --
+
+test("perf: arrowDetectSchemaStream", async () => {
+ const bench = new Bench({ name: "arrowDetectSchemaStream", time });
+
+ bench.add(`${ITEMS} objects`, async () => {
+ const detect = arrowDetectSchemaStream({ sampleSize: 100 });
+ const streams = [createReadableStream(objects), detect];
+ await streamToArray(pipejoin(streams));
+ });
+
+ await bench.run();
+ console.log(`\n${bench.name}`);
+ console.table(bench.table());
+});
+
+test("perf: arrowBatchFromObjectStream", async () => {
+ const bench = new Bench({ name: "arrowBatchFromObjectStream", time });
+
+ bench.add(`${ITEMS} objects, batchSize 1000`, async () => {
+ const streams = [
+ createReadableStream(objects),
+ arrowBatchFromObjectStream({ schema: usersSchema, batchSize: 1_000 }),
+ ];
+ await streamToArray(pipejoin(streams));
+ });
+
+ bench.add(`${ITEMS} objects, batchSize 100`, async () => {
+ const streams = [
+ createReadableStream(objects),
+ arrowBatchFromObjectStream({ schema: usersSchema, batchSize: 100 }),
+ ];
+ await streamToArray(pipejoin(streams));
+ });
+
+ await bench.run();
+ console.log(`\n${bench.name}`);
+ console.table(bench.table());
+});
+
+test("perf: arrowToObjectStream (batch -> objects)", async () => {
+ const bench = new Bench({ name: "arrowToObjectStream", time });
+
+ bench.add(`${ITEMS} objects, batchSize 1000`, async () => {
+ const streams = [
+ createReadableStream(objects),
+ arrowBatchFromObjectStream({ schema: usersSchema, batchSize: 1_000 }),
+ arrowToObjectStream(),
+ ];
+ await streamToArray(pipejoin(streams));
+ });
+
+ await bench.run();
+ console.log(`\n${bench.name}`);
+ console.table(bench.table());
+});
+
+test("perf: arrowToArrayStream (batch -> arrays)", async () => {
+ const bench = new Bench({ name: "arrowToArrayStream", time });
+
+ bench.add(`${ITEMS} objects, batchSize 1000`, async () => {
+ const streams = [
+ createReadableStream(objects),
+ arrowBatchFromObjectStream({ schema: usersSchema, batchSize: 1_000 }),
+ arrowToArrayStream(),
+ ];
+ await streamToArray(pipejoin(streams));
+ });
+
+ await bench.run();
+ console.log(`\n${bench.name}`);
+ console.table(bench.table());
+});
+
+test("perf: object roundtrip (detect -> batch -> objects)", async () => {
+ const bench = new Bench({ name: "object roundtrip", time });
+
+ bench.add(`${ITEMS} objects`, async () => {
+ const detect = arrowDetectSchemaStream({ sampleSize: 100 });
+ const streams = [
+ createReadableStream(objects),
+ detect,
+ arrowBatchFromObjectStream({
+ schema: () => detect.result().value.schema,
+ batchSize: 1_000,
+ }),
+ arrowToObjectStream(),
+ ];
+ await streamToArray(pipejoin(streams));
+ });
+
+ await bench.run();
+ console.log(`\n${bench.name}`);
+ console.table(bench.table());
+});
diff --git a/packages/arrow/index.test.js b/packages/arrow/index.test.js
new file mode 100644
index 0000000..c04c09a
--- /dev/null
+++ b/packages/arrow/index.test.js
@@ -0,0 +1,822 @@
+import { deepStrictEqual, ok, strictEqual, throws } from "node:assert";
+import test from "node:test";
+import {
+ arrowBatchFromArrayStream,
+ arrowBatchFromObjectStream,
+ arrowDetectSchemaStream,
+ arrowToArrayStream,
+ arrowToObjectStream,
+} from "@datastream/arrow";
+import {
+ createReadableStream,
+ pipejoin,
+ streamToArray,
+} from "@datastream/core";
+import { Field, Float64, Int32, RecordBatch, Schema, Utf8 } from "apache-arrow";
+
+let variant = "unknown";
+for (const execArgv of process.execArgv) {
+ const flag = "--conditions=";
+ if (execArgv.includes(flag)) {
+ variant = execArgv.replace(flag, "");
+ }
+}
+
+const usersSchema = new Schema([
+ new Field("id", new Int32(), true),
+ new Field("name", new Utf8(), true),
+]);
+
+// *** arrowDetectSchemaStream *** //
+test(`${variant}: arrowDetectSchemaStream should infer schema from object rows`, async () => {
+ const detect = arrowDetectSchemaStream({ sampleSize: 2 });
+ const stream = pipejoin([
+ createReadableStream([
+ { id: 1, name: "alice" },
+ { id: 2, name: "bob" },
+ { id: 3, name: "carol" },
+ ]),
+ detect,
+ ]);
+ const output = await streamToArray(stream);
+
+ strictEqual(output.length, 3);
+ const { value } = detect.result();
+ ok(value.schema);
+ deepStrictEqual(value.fields, ["id", "name"]);
+ strictEqual(value.schema.fields.length, 2);
+ strictEqual(value.schema.fields[0].name, "id");
+ strictEqual(value.schema.fields[1].name, "name");
+});
+
+test(`${variant}: arrowDetectSchemaStream should infer column names for array rows`, async () => {
+ const detect = arrowDetectSchemaStream({ sampleSize: 1 });
+ const stream = pipejoin([
+ createReadableStream([
+ [1, "alice"],
+ [2, "bob"],
+ ]),
+ detect,
+ ]);
+ await streamToArray(stream);
+ const { value } = detect.result();
+ deepStrictEqual(value.fields, ["column0", "column1"]);
+});
+
+test(`${variant}: arrowDetectSchemaStream widens out-of-range integers to Float64 (no Int32 overflow)`, async () => {
+ const big = 3_000_000_000; // > 2^31, overflows Int32
+ const detect = arrowDetectSchemaStream({ sampleSize: 1 });
+ const stream = pipejoin([
+ createReadableStream([{ id: big, small: 5 }]),
+ detect,
+ ]);
+ await streamToArray(stream);
+ const { value } = detect.result();
+ // Out-of-range integer must not be inferred as Int32 (which silently wraps).
+ strictEqual(value.schema.fields[0].type instanceof Float64, true);
+ // In-range integer stays Int32.
+ strictEqual(value.schema.fields[1].type instanceof Int32, true);
+});
+
+test(`${variant}: detect -> batch -> rows preserves a large integer exactly (no Int32 wraparound)`, async () => {
+ const input = [{ id: 3_000_000_000, name: "alice" }];
+ const detect = arrowDetectSchemaStream({ sampleSize: 1 });
+ const stream = pipejoin([
+ createReadableStream(input),
+ detect,
+ arrowBatchFromObjectStream({
+ schema: () => detect.result().value.schema,
+ batchSize: 10,
+ }),
+ arrowToObjectStream(),
+ ]);
+ const rows = await streamToArray(stream);
+ strictEqual(rows[0].id, 3_000_000_000);
+ strictEqual(rows[0].name, "alice");
+});
+
+test(`${variant}: arrowDetectSchemaStream should seal on flush when fewer rows than sampleSize`, async () => {
+ const detect = arrowDetectSchemaStream({ sampleSize: 100 });
+ const stream = pipejoin([
+ createReadableStream([{ id: 1, name: "alice" }]),
+ detect,
+ ]);
+ await streamToArray(stream);
+ const { value } = detect.result();
+ ok(value.schema);
+ deepStrictEqual(value.fields, ["id", "name"]);
+});
+
+// The schema must be sealed mid-stream exactly when `samples.length` REACHES
+// sampleSize, using only the rows seen so far. With sampleSize 2 the first two
+// 1-element array rows seal a single-column schema; the wider later row
+// [3, 4, 5] arrives after sealing and must NOT widen the schema. A mutant that
+// defers sealing (>= -> >, the guard removed, or `if (false)`) would instead
+// sample the wider row and infer three columns.
+test(`${variant}: arrowDetectSchemaStream seals mid-stream at sampleSize, ignoring wider later rows`, async () => {
+ const detect = arrowDetectSchemaStream({ sampleSize: 2 });
+ const stream = pipejoin([
+ createReadableStream([[1], [2], [3, 4, 5]]),
+ detect,
+ ]);
+ const rows = await streamToArray(stream);
+ const { value } = detect.result();
+ deepStrictEqual(value.fields, ["column0"]);
+ strictEqual(value.schema.fields.length, 1);
+ // All input rows still flow through unchanged (the wider row is passed as-is).
+ strictEqual(rows.length, 3);
+ deepStrictEqual(rows[2], [3, 4, 5]);
+});
+
+// *** arrowBatchFromArrayStream *** //
+test(`${variant}: arrowBatchFromArrayStream should emit a RecordBatch per batchSize rows`, async () => {
+ const stream = pipejoin([
+ createReadableStream([
+ [1, "a"],
+ [2, "b"],
+ [3, "c"],
+ ]),
+ arrowBatchFromArrayStream({ schema: usersSchema, batchSize: 2 }),
+ ]);
+ const batches = await streamToArray(stream);
+
+ strictEqual(batches.length, 2);
+ ok(batches[0] instanceof RecordBatch);
+ strictEqual(batches[0].numRows, 2);
+ strictEqual(batches[1].numRows, 1);
+ strictEqual(batches[0].getChildAt(0).get(0), 1);
+ strictEqual(batches[0].getChildAt(1).get(1), "b");
+});
+
+test(`${variant}: arrowBatchFromArrayStream should resolve a lazy schema`, async () => {
+ const stream = pipejoin([
+ createReadableStream([[1, "a"]]),
+ arrowBatchFromArrayStream({
+ schema: () => usersSchema,
+ batchSize: 10,
+ }),
+ ]);
+ const batches = await streamToArray(stream);
+ strictEqual(batches.length, 1);
+ strictEqual(batches[0].numRows, 1);
+});
+
+// *** arrowBatchFromObjectStream *** //
+test(`${variant}: arrowBatchFromObjectStream should batch object rows`, async () => {
+ const stream = pipejoin([
+ createReadableStream([
+ { id: 1, name: "a" },
+ { id: 2, name: "b" },
+ ]),
+ arrowBatchFromObjectStream({ schema: usersSchema, batchSize: 10 }),
+ ]);
+ const batches = await streamToArray(stream);
+ strictEqual(batches.length, 1);
+ strictEqual(batches[0].numRows, 2);
+ strictEqual(batches[0].getChildAt(0).get(1), 2);
+ strictEqual(batches[0].getChildAt(1).get(0), "a");
+});
+
+// *** arrowToArrayStream / arrowToObjectStream *** //
+test(`${variant}: arrowToArrayStream should emit one array row per record-batch row`, async () => {
+ const buildStream = pipejoin([
+ createReadableStream([
+ { id: 1, name: "a" },
+ { id: 2, name: "b" },
+ ]),
+ arrowBatchFromObjectStream({ schema: usersSchema, batchSize: 10 }),
+ arrowToArrayStream(),
+ ]);
+ const rows = await streamToArray(buildStream);
+ deepStrictEqual(rows, [
+ [1, "a"],
+ [2, "b"],
+ ]);
+});
+
+test(`${variant}: round-trip rows -> arrow -> rows preserves data`, async () => {
+ const input = [
+ { id: 1, name: "alice" },
+ { id: 2, name: "bob" },
+ { id: 3, name: "carol" },
+ ];
+ const stream = pipejoin([
+ createReadableStream(input),
+ arrowBatchFromObjectStream({ schema: usersSchema, batchSize: 2 }),
+ arrowToObjectStream(),
+ ]);
+ const rows = await streamToArray(stream);
+ deepStrictEqual(rows, input);
+});
+
+// *** lazy schema wired to detect *** //
+test(`${variant}: detect + batchFromObject end-to-end with lazy schema`, async () => {
+ const detect = arrowDetectSchemaStream({ sampleSize: 2 });
+ const stream = pipejoin([
+ createReadableStream([
+ { id: 1, name: "a" },
+ { id: 2, name: "b" },
+ { id: 3, name: "c" },
+ ]),
+ detect,
+ arrowBatchFromObjectStream({
+ schema: () => detect.result().value.schema,
+ batchSize: 10,
+ }),
+ arrowToObjectStream(),
+ ]);
+ const rows = await streamToArray(stream);
+ deepStrictEqual(rows, [
+ { id: 1, name: "a" },
+ { id: 2, name: "b" },
+ { id: 3, name: "c" },
+ ]);
+});
+
+// *** heterogeneous keys: schema detection must union across all sampled rows *** //
+test(`${variant}: arrowDetectSchemaStream unions object keys across all sampled rows`, async () => {
+ const detect = arrowDetectSchemaStream({ sampleSize: 10 });
+ const stream = pipejoin([
+ createReadableStream([{ id: 1 }, { id: 2, name: "bob" }]),
+ detect,
+ ]);
+ await streamToArray(stream);
+ const { value } = detect.result();
+ deepStrictEqual(value.fields, ["id", "name"]);
+ strictEqual(value.schema.fields.length, 2);
+ // 'name' should be a Utf8 column inferred from the second row.
+ strictEqual(value.schema.fields[1].name, "name");
+ strictEqual(value.schema.fields[1].type instanceof Utf8, true);
+});
+
+test(`${variant}: arrowDetectSchemaStream uses max array width across sampled rows`, async () => {
+ const detect = arrowDetectSchemaStream({ sampleSize: 10 });
+ const stream = pipejoin([
+ createReadableStream([[1], [2, "bob", true]]),
+ detect,
+ ]);
+ await streamToArray(stream);
+ const { value } = detect.result();
+ deepStrictEqual(value.fields, ["column0", "column1", "column2"]);
+ strictEqual(value.schema.fields.length, 3);
+});
+
+test(`${variant}: detect -> batch -> rows preserves a column present only in a later row`, async () => {
+ const input = [{ id: 1 }, { id: 2, name: "bob" }];
+ const detect = arrowDetectSchemaStream({ sampleSize: 10 });
+ const stream = pipejoin([
+ createReadableStream(input),
+ detect,
+ arrowBatchFromObjectStream({
+ schema: () => detect.result().value.schema,
+ batchSize: 10,
+ }),
+ arrowToObjectStream(),
+ ]);
+ const rows = await streamToArray(stream);
+ strictEqual(rows.length, 2);
+ strictEqual(rows[1].name, "bob");
+});
+
+// *** Date round-trip *** //
+test(`${variant}: detect -> batch -> rows round-trips Date values as Date`, async () => {
+ const when = new Date("2020-06-01T00:00:00.000Z");
+ const input = [{ id: 1, at: when }];
+ const detect = arrowDetectSchemaStream({ sampleSize: 1 });
+ const stream = pipejoin([
+ createReadableStream(input),
+ detect,
+ arrowBatchFromObjectStream({
+ schema: () => detect.result().value.schema,
+ batchSize: 10,
+ }),
+ arrowToObjectStream(),
+ ]);
+ const rows = await streamToArray(stream);
+ ok(rows[0].at instanceof Date, "at should come back as a Date");
+ strictEqual(rows[0].at.getTime(), when.getTime());
+});
+
+test(`${variant}: arrowToArrayStream round-trips Date values as Date`, async () => {
+ const when = new Date("2020-06-01T00:00:00.000Z");
+ const detect = arrowDetectSchemaStream({ sampleSize: 1 });
+ const stream = pipejoin([
+ createReadableStream([{ at: when }]),
+ detect,
+ arrowBatchFromObjectStream({
+ schema: () => detect.result().value.schema,
+ batchSize: 10,
+ }),
+ arrowToArrayStream(),
+ ]);
+ const rows = await streamToArray(stream);
+ ok(rows[0][0] instanceof Date, "at should come back as a Date");
+ strictEqual(rows[0][0].getTime(), when.getTime());
+});
+
+// *** empty / zero-field schema must error rather than silently lose rows *** //
+// apache-arrow derives a RecordBatch's length from its child columns, so a
+// zero-field schema can never carry rows; rejecting it prevents corrupt
+// numRows:0 batches that silently discard data.
+test(`${variant}: arrowBatchFromObjectStream rejects a zero-field schema instead of losing rows`, () => {
+ throws(
+ () => arrowBatchFromObjectStream({ schema: new Schema([]), batchSize: 10 }),
+ /at least one field/,
+ );
+});
+
+test(`${variant}: arrowBatchFromArrayStream rejects a zero-field schema instead of losing rows`, () => {
+ throws(
+ () => arrowBatchFromArrayStream({ schema: new Schema([]), batchSize: 10 }),
+ /at least one field/,
+ );
+});
+
+// *** missing-schema validation, including empty input *** //
+// A concrete missing schema is rejected eagerly at construction.
+test(`${variant}: arrowBatchFromObjectStream throws eagerly when schema is missing`, () => {
+ throws(() => arrowBatchFromObjectStream({}), /schema is required/);
+ throws(() => arrowBatchFromObjectStream(), /schema is required/);
+});
+
+test(`${variant}: arrowBatchFromArrayStream throws eagerly when schema is missing`, () => {
+ throws(() => arrowBatchFromArrayStream({}), /schema is required/);
+ throws(() => arrowBatchFromArrayStream(), /schema is required/);
+});
+
+// A lazy schema that resolves to nothing must still error even for an empty
+// stream: init runs on flush, so the config bug is surfaced (as a stream error)
+// rather than silently swallowed.
+const errorFromEmptyLazy = (build) =>
+ new Promise((resolve, reject) => {
+ const src = createReadableStream([]);
+ const stream = build();
+ stream.on("error", resolve);
+ stream.on("end", () => reject(new Error("expected an error, got end")));
+ stream.on("close", () => reject(new Error("expected an error, got close")));
+ src.pipe(stream);
+ stream.resume();
+ });
+
+test(`${variant}: arrowBatchFromObjectStream errors for a lazy missing schema even on empty input`, async () => {
+ const error = await errorFromEmptyLazy(() =>
+ arrowBatchFromObjectStream({ schema: () => undefined }),
+ );
+ ok(/schema is required/.test(error.message));
+});
+
+test(`${variant}: arrowBatchFromArrayStream errors for a lazy missing schema even on empty input`, async () => {
+ const error = await errorFromEmptyLazy(() =>
+ arrowBatchFromArrayStream({ schema: () => undefined }),
+ );
+ ok(/schema is required/.test(error.message));
+});
+
+// *** inferType: null/undefined/empty-string branch *** //
+// Kills: LogicalOperator (|| -> &&), ConditionalExpression short-circuits,
+// StringLiteral ("" -> "Stryker was here!")
+test(`${variant}: inferType treats null as no-type (first non-null row wins)`, async () => {
+ const detect = arrowDetectSchemaStream({ sampleSize: 10 });
+ const stream = pipejoin([
+ createReadableStream([{ x: null }, { x: 42 }]),
+ detect,
+ ]);
+ await streamToArray(stream);
+ const { value } = detect.result();
+ strictEqual(value.schema.fields[0].type instanceof Int32, true);
+});
+
+test(`${variant}: inferType treats undefined as no-type (first non-null row wins)`, async () => {
+ const detect = arrowDetectSchemaStream({ sampleSize: 10 });
+ const stream = pipejoin([
+ createReadableStream([{ x: undefined }, { x: 7 }]),
+ detect,
+ ]);
+ await streamToArray(stream);
+ const { value } = detect.result();
+ strictEqual(value.schema.fields[0].type instanceof Int32, true);
+});
+
+test(`${variant}: inferType treats empty string as no-type (first non-empty row wins)`, async () => {
+ const detect = arrowDetectSchemaStream({ sampleSize: 10 });
+ const stream = pipejoin([
+ createReadableStream([{ x: "" }, { x: "hello" }]),
+ detect,
+ ]);
+ await streamToArray(stream);
+ const { value } = detect.result();
+ strictEqual(value.schema.fields[0].type instanceof Utf8, true);
+});
+
+// *** inferType: boolean branch *** //
+// Kills: ConditionalExpression (false), StringLiteral ("" for "boolean")
+test(`${variant}: inferType returns Bool typeId for boolean true`, async () => {
+ const detect = arrowDetectSchemaStream({ sampleSize: 1 });
+ const stream = pipejoin([createReadableStream([{ flag: true }]), detect]);
+ await streamToArray(stream);
+ const { value } = detect.result();
+ strictEqual(value.schema.fields[0].type.typeId, 6); // Bool typeId
+});
+
+test(`${variant}: inferType returns Bool typeId for boolean false`, async () => {
+ const detect = arrowDetectSchemaStream({ sampleSize: 10 });
+ const stream = pipejoin([
+ createReadableStream([{ flag: false }, { flag: true }]),
+ detect,
+ ]);
+ await streamToArray(stream);
+ const { value } = detect.result();
+ strictEqual(value.schema.fields[0].type.typeId, 6); // Bool typeId
+});
+
+// *** inferType: number/Float64/Int32 boundary checks *** //
+// Kills: ConditionalExpression (!isInteger false), EqualityOperator (>= vs >),
+// lower-bound ConditionalExpression and EqualityOperator.
+test(`${variant}: inferType returns Float64 for non-integer number`, async () => {
+ const detect = arrowDetectSchemaStream({ sampleSize: 1 });
+ const stream = pipejoin([createReadableStream([{ x: 3.14 }]), detect]);
+ await streamToArray(stream);
+ const { value } = detect.result();
+ strictEqual(value.schema.fields[0].type instanceof Float64, true);
+});
+
+test(`${variant}: inferType returns Int32 for integer at INT32_MAX (2147483647)`, async () => {
+ const detect = arrowDetectSchemaStream({ sampleSize: 1 });
+ const stream = pipejoin([createReadableStream([{ x: 2147483647 }]), detect]);
+ await streamToArray(stream);
+ const { value } = detect.result();
+ strictEqual(value.schema.fields[0].type instanceof Int32, true);
+});
+
+test(`${variant}: inferType returns Float64 for integer one above INT32_MAX (2147483648)`, async () => {
+ const detect = arrowDetectSchemaStream({ sampleSize: 1 });
+ const stream = pipejoin([createReadableStream([{ x: 2147483648 }]), detect]);
+ await streamToArray(stream);
+ const { value } = detect.result();
+ strictEqual(value.schema.fields[0].type instanceof Float64, true);
+});
+
+test(`${variant}: inferType returns Int32 for integer at INT32_MIN (-2147483648)`, async () => {
+ const detect = arrowDetectSchemaStream({ sampleSize: 1 });
+ const stream = pipejoin([createReadableStream([{ x: -2147483648 }]), detect]);
+ await streamToArray(stream);
+ const { value } = detect.result();
+ strictEqual(value.schema.fields[0].type instanceof Int32, true);
+});
+
+test(`${variant}: inferType returns Float64 for integer one below INT32_MIN (-2147483649)`, async () => {
+ const detect = arrowDetectSchemaStream({ sampleSize: 1 });
+ const stream = pipejoin([createReadableStream([{ x: -2147483649 }]), detect]);
+ await streamToArray(stream);
+ const { value } = detect.result();
+ strictEqual(value.schema.fields[0].type instanceof Float64, true);
+});
+
+// *** inferType: Date branch *** //
+// Kills: ConditionalExpression (false for instanceof Date)
+test(`${variant}: inferType returns TimestampMillisecond typeId for Date values`, async () => {
+ const detect = arrowDetectSchemaStream({ sampleSize: 1 });
+ const stream = pipejoin([createReadableStream([{ ts: new Date() }]), detect]);
+ await streamToArray(stream);
+ const { value } = detect.result();
+ strictEqual(value.schema.fields[0].type.typeId, 10); // Timestamp typeId
+});
+
+// *** fieldsFromSamples: type !== null break + nullable Field *** //
+// Kills: ConditionalExpression (true/false on break), EqualityOperator (=== null),
+// BooleanLiteral (false for nullable).
+test(`${variant}: fieldsFromSamples skips null rows and uses first non-null type`, async () => {
+ const detect = arrowDetectSchemaStream({ sampleSize: 10 });
+ const stream = pipejoin([
+ createReadableStream([{ x: null }, { x: null }, { x: 99 }]),
+ detect,
+ ]);
+ await streamToArray(stream);
+ const { value } = detect.result();
+ strictEqual(value.schema.fields[0].type instanceof Int32, true);
+ strictEqual(value.schema.fields[0].nullable, true);
+});
+
+// *** fieldsFromSamples: type ?? new Utf8() fallback when ALL sampled values are null *** //
+// Kills: branch where every sampled value for a field is null/undefined/empty-string,
+// so type stays null and the ?? fallback produces a Utf8 Field.
+test(`${variant}: fieldsFromSamples falls back to Utf8 when all sampled values are null`, async () => {
+ const detect = arrowDetectSchemaStream({ sampleSize: 10 });
+ const stream = pipejoin([
+ createReadableStream([{ x: null }, { x: null }]),
+ detect,
+ ]);
+ await streamToArray(stream);
+ const { value } = detect.result();
+ strictEqual(value.schema.fields[0].type instanceof Utf8, true);
+ strictEqual(value.schema.fields[0].nullable, true);
+});
+
+// *** arrowDetectSchemaStream: value object must have schema + fields keys *** //
+// Kills: ObjectLiteral ({} for {schema:null, fields:null})
+test(`${variant}: arrowDetectSchemaStream result value has schema and fields properties`, async () => {
+ const detect = arrowDetectSchemaStream({ sampleSize: 10 });
+ const stream = pipejoin([createReadableStream([{ id: 1 }]), detect]);
+ await streamToArray(stream);
+ const { value } = detect.result();
+ ok("schema" in value, "value must have schema key");
+ ok("fields" in value, "value must have fields key");
+});
+
+// *** seal() guarding: empty stream leaves schema null *** //
+// Kills: ConditionalExpression (false for sealed || !samples.length),
+// LogicalOperator (|| -> &&).
+test(`${variant}: arrowDetectSchemaStream leaves schema null for empty stream`, async () => {
+ const detect = arrowDetectSchemaStream({ sampleSize: 10 });
+ const stream = pipejoin([createReadableStream([]), detect]);
+ await streamToArray(stream);
+ const { value } = detect.result();
+ strictEqual(value.schema, null);
+});
+
+// *** seal(): sealed = true flag *** //
+// Kills: BooleanLiteral (false for sealed = true)
+test(`${variant}: arrowDetectSchemaStream sealed flag prevents re-sealing`, async () => {
+ const detect = arrowDetectSchemaStream({ sampleSize: 2 });
+ const stream = pipejoin([
+ createReadableStream([{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }]),
+ detect,
+ ]);
+ await streamToArray(stream);
+ const { value } = detect.result();
+ ok(value.schema !== null);
+ strictEqual(value.schema.fields.length, 1);
+});
+
+// *** transform: samples.length >= sampleSize threshold *** //
+// Kills: ConditionalExpression (false), EqualityOperator (> vs >=).
+test(`${variant}: arrowDetectSchemaStream seals at exactly sampleSize rows`, async () => {
+ const detect = arrowDetectSchemaStream({ sampleSize: 2 });
+ const stream = pipejoin([
+ createReadableStream([{ id: 1 }, { id: 2 }]),
+ detect,
+ ]);
+ const rows = await streamToArray(stream);
+ const { value } = detect.result();
+ strictEqual(rows.length, 2);
+ ok(value.schema !== null);
+});
+
+// *** transform: BlockStatement kill (buffered rows emitted after seal) *** //
+// Kills: BlockStatement (empty block when sampleSize reached).
+test(`${variant}: arrowDetectSchemaStream emits all rows when sampleSize is hit mid-stream`, async () => {
+ const detect = arrowDetectSchemaStream({ sampleSize: 2 });
+ const stream = pipejoin([
+ createReadableStream([{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }]),
+ detect,
+ ]);
+ const rows = await streamToArray(stream);
+ strictEqual(rows.length, 4);
+});
+
+// *** flush(): !sealed branch *** //
+// Kills: ConditionalExpression (true for !sealed), BlockStatement (empty).
+test(`${variant}: arrowDetectSchemaStream flush path emits the buffered row`, async () => {
+ const detect = arrowDetectSchemaStream({ sampleSize: 100 });
+ const stream = pipejoin([createReadableStream([{ id: 42 }]), detect]);
+ const rows = await streamToArray(stream);
+ strictEqual(rows.length, 1);
+ strictEqual(rows[0].id, 42);
+});
+
+// *** stream.result: ?? vs && and default key string *** //
+// Kills: LogicalOperator (?? -> &&), StringLiteral ("" for "arrowDetectSchema").
+test(`${variant}: arrowDetectSchemaStream result key defaults to "arrowDetectSchema"`, async () => {
+ const detect = arrowDetectSchemaStream({ sampleSize: 1 });
+ const stream = pipejoin([createReadableStream([{ id: 1 }]), detect]);
+ await streamToArray(stream);
+ strictEqual(detect.result().key, "arrowDetectSchema");
+});
+
+test(`${variant}: arrowDetectSchemaStream result key uses provided resultKey`, async () => {
+ const detect = arrowDetectSchemaStream({ sampleSize: 1, resultKey: "myKey" });
+ const stream = pipejoin([createReadableStream([{ id: 1 }]), detect]);
+ await streamToArray(stream);
+ strictEqual(detect.result().key, "myKey");
+});
+
+// *** makeBuilders: nullValues must include null and undefined *** //
+// Kills: ArrayDeclaration ([] for [null, undefined]).
+test(`${variant}: null field values survive object stream round-trip as null`, async () => {
+ const stream = pipejoin([
+ createReadableStream([
+ { id: 1, name: "alice" },
+ { id: 2, name: null },
+ ]),
+ arrowBatchFromObjectStream({ schema: usersSchema, batchSize: 10 }),
+ arrowToObjectStream(),
+ ]);
+ const rows = await streamToArray(stream);
+ strictEqual(rows[1].name, null);
+});
+
+test(`${variant}: undefined field values survive array stream round-trip as null`, async () => {
+ const stream = pipejoin([
+ createReadableStream([
+ [1, "alice"],
+ [2, undefined],
+ ]),
+ arrowBatchFromArrayStream({ schema: usersSchema, batchSize: 10 }),
+ arrowToArrayStream(),
+ ]);
+ const rows = await streamToArray(stream);
+ strictEqual(rows[1][1], null);
+});
+
+// *** assertSchema error messages include function name *** //
+// Kills: StringLiteral ("" for "arrowBatchFromArrayStream" / "arrowBatchFromObjectStream").
+test(`${variant}: arrowBatchFromArrayStream error message includes function name`, () => {
+ throws(
+ () => arrowBatchFromArrayStream({}),
+ (err) => {
+ ok(/arrowBatchFromArrayStream/.test(err.message), `got: ${err.message}`);
+ return true;
+ },
+ );
+});
+
+test(`${variant}: arrowBatchFromObjectStream error message includes function name`, () => {
+ throws(
+ () => arrowBatchFromObjectStream({}),
+ (err) => {
+ ok(/arrowBatchFromObjectStream/.test(err.message), `got: ${err.message}`);
+ return true;
+ },
+ );
+});
+
+// *** arrowBatchFromArrayStream flush: rowCount > 0 guards *** //
+// Kills: ConditionalExpression (true), EqualityOperator (>= 0 vs > 0).
+test(`${variant}: arrowBatchFromArrayStream flush emits no extra batch when rowCount is 0`, async () => {
+ const stream = pipejoin([
+ createReadableStream([
+ [1, "a"],
+ [2, "b"],
+ ]),
+ arrowBatchFromArrayStream({ schema: usersSchema, batchSize: 2 }),
+ ]);
+ const batches = await streamToArray(stream);
+ strictEqual(batches.length, 1);
+ strictEqual(batches[0].numRows, 2);
+});
+
+// *** arrowBatchFromObjectStream transform: rowCount >= batchSize + BlockStatement *** //
+// Kills: EqualityOperator (> vs >=), ConditionalExpression (false), BlockStatement.
+test(`${variant}: arrowBatchFromObjectStream emits batch at exactly batchSize rows`, async () => {
+ const stream = pipejoin([
+ createReadableStream([
+ { id: 1, name: "a" },
+ { id: 2, name: "b" },
+ { id: 3, name: "c" },
+ ]),
+ arrowBatchFromObjectStream({ schema: usersSchema, batchSize: 2 }),
+ ]);
+ const batches = await streamToArray(stream);
+ strictEqual(batches.length, 2);
+ strictEqual(batches[0].numRows, 2);
+ strictEqual(batches[1].numRows, 1);
+});
+
+// *** arrowBatchFromObjectStream flush: rowCount > 0 guards *** //
+// Kills: ConditionalExpression (true), EqualityOperator (>= 0 vs > 0).
+test(`${variant}: arrowBatchFromObjectStream flush emits no extra batch when rowCount is 0`, async () => {
+ const stream = pipejoin([
+ createReadableStream([
+ { id: 1, name: "a" },
+ { id: 2, name: "b" },
+ ]),
+ arrowBatchFromObjectStream({ schema: usersSchema, batchSize: 2 }),
+ ]);
+ const batches = await streamToArray(stream);
+ strictEqual(batches.length, 1);
+ strictEqual(batches[0].numRows, 2);
+});
+
+// *** readCell: isTimestamp && typeof value === "number" *** //
+// Kills: ConditionalExpression (isTimestamp && true).
+test(`${variant}: readCell does not wrap null timestamp cell in Date`, async () => {
+ const when = new Date("2021-01-01T00:00:00.000Z");
+ const detect = arrowDetectSchemaStream({ sampleSize: 1 });
+ const stream = pipejoin([
+ createReadableStream([{ ts: when }, { ts: null }]),
+ detect,
+ arrowBatchFromObjectStream({
+ schema: () => detect.result().value.schema,
+ batchSize: 10,
+ }),
+ arrowToObjectStream(),
+ ]);
+ const rows = await streamToArray(stream);
+ ok(rows[0].ts instanceof Date);
+ strictEqual(rows[1].ts, null);
+});
+
+// *** arrowToArrayStream: new Array(colCount) pre-allocates with colCount *** //
+// Kills: ArrayDeclaration (new Array() instead of new Array(colCount)).
+test(`${variant}: arrowToArrayStream row length equals schema column count`, async () => {
+ const stream = pipejoin([
+ createReadableStream([{ id: 1, name: "alice" }]),
+ arrowBatchFromObjectStream({ schema: usersSchema, batchSize: 10 }),
+ arrowToArrayStream(),
+ ]);
+ const rows = await streamToArray(stream);
+ strictEqual(rows[0].length, 2);
+});
+
+// *** default export must contain all five functions *** //
+// Kills: ObjectLiteral ({} for the default export object).
+test(`${variant}: default export exposes all five stream factory functions`, async () => {
+ const mod = await import("@datastream/arrow");
+ const def = mod.default;
+ ok(typeof def.detectSchemaStream === "function");
+ ok(typeof def.batchFromArrayStream === "function");
+ ok(typeof def.batchFromObjectStream === "function");
+ ok(typeof def.toArrayStream === "function");
+ ok(typeof def.toObjectStream === "function");
+});
+// *** fieldsFromSamples: first non-null type must win (break kills last-wins mutant) *** //
+// Kills: ConditionalExpression (if (false) break - never breaks, last type wins).
+test(`${variant}: fieldsFromSamples uses FIRST non-null type not last`, async () => {
+ // Two values with different types: Int32 first, Utf8 last.
+ // Real (break on first non-null): Int32. Mutant (never break): Utf8.
+ const detect = arrowDetectSchemaStream({ sampleSize: 10 });
+ const stream = pipejoin([
+ createReadableStream([{ x: 42 }, { x: "hello" }]),
+ detect,
+ ]);
+ await streamToArray(stream);
+ const { value } = detect.result();
+ strictEqual(value.schema.fields[0].type instanceof Int32, true);
+});
+
+// *** fieldsFromSamples: max array width uses > not >= or always-true *** //
+// Kills: ConditionalExpression (if (true)) - always updates width to last sample's length.
+test(`${variant}: arrowDetectSchemaStream uses max width across descending-width array rows`, async () => {
+ // First row has 3 cols, second has 1. Real: width=3 (never shrinks).
+ // Mutant (if true): width=1 (last row wins), giving only column0.
+ const detect = arrowDetectSchemaStream({ sampleSize: 10 });
+ const stream = pipejoin([createReadableStream([[1, 2, 3], [4]]), detect]);
+ await streamToArray(stream);
+ const { value } = detect.result();
+ deepStrictEqual(value.fields, ["column0", "column1", "column2"]);
+ strictEqual(value.schema.fields.length, 3);
+});
+
+// *** init() in arrowBatchFromArrayStream: error message from lazy schema must include function name *** //
+// Kills: StringLiteral ( for arrowBatchFromArrayStream in init()).
+test(`${variant}: arrowBatchFromArrayStream lazy schema error includes function name`, async () => {
+ const err = await errorFromEmptyLazy(() =>
+ arrowBatchFromArrayStream({ schema: () => undefined }),
+ );
+ ok(/arrowBatchFromArrayStream/.test(err.message), `got: ${err.message}`);
+});
+
+// *** init() in arrowBatchFromObjectStream: error message from lazy schema must include function name *** //
+// Kills: StringLiteral ( for arrowBatchFromObjectStream in init()).
+test(`${variant}: arrowBatchFromObjectStream lazy schema error includes function name`, async () => {
+ const err = await errorFromEmptyLazy(() =>
+ arrowBatchFromObjectStream({ schema: () => undefined }),
+ );
+ ok(/arrowBatchFromObjectStream/.test(err.message), `got: ${err.message}`);
+});
+// *** Kill empty-string mutants by testing against a non-string next value *** //
+// Kills: ConditionalExpression (false for value === ""),
+// StringLiteral ("Stryker was here!" for "").
+// If empty-string is NOT skipped, it types as Utf8 and breaks. Next value (42) is
+// never seen. Result would be Utf8 instead of Int32.
+test(`${variant}: inferType skips empty string before a number (type from number row wins)`, async () => {
+ const detect = arrowDetectSchemaStream({ sampleSize: 10 });
+ const stream = pipejoin([
+ createReadableStream([{ x: "" }, { x: 42 }]),
+ detect,
+ ]);
+ await streamToArray(stream);
+ const { value } = detect.result();
+ // Real: "" skipped, 42 wins → Int32.
+ // Mutant: "" not skipped, Utf8 typed, breaks → Utf8 (wrong).
+ strictEqual(value.schema.fields[0].type instanceof Int32, true);
+});
+// *** Kill sealed = false mutant: schema must not be re-detected from later rows *** //
+// Kills: BooleanLiteral (false for sealed = true in seal()).
+// With sealed=false: seal() re-runs for every subsequent sampleSize rows, overwriting
+// the schema with types from the new batch. With sealed=true: schema is frozen after
+// the first sampleSize rows.
+test(`${variant}: arrowDetectSchemaStream schema is frozen after first sampleSize rows`, async () => {
+ // sampleSize=2: rows 1-2 produce Int32 schema. Rows 3-4 produce Float64 schema.
+ // Real (sealed=true): schema stays Int32.
+ // Mutant (sealed=false): seal() re-runs on rows 3-4, overwriting to Float64.
+ const detect = arrowDetectSchemaStream({ sampleSize: 2 });
+ const stream = pipejoin([
+ createReadableStream([{ x: 1 }, { x: 2 }, { x: 3.14 }, { x: 2.72 }]),
+ detect,
+ ]);
+ await streamToArray(stream);
+ const { value } = detect.result();
+ // Schema must reflect the FIRST two rows (Int32), not the last two (Float64).
+ strictEqual(value.schema.fields[0].type instanceof Int32, true);
+});
diff --git a/packages/arrow/index.tst.ts b/packages/arrow/index.tst.ts
new file mode 100644
index 0000000..885b0ac
--- /dev/null
+++ b/packages/arrow/index.tst.ts
@@ -0,0 +1,74 @@
+///
+///
+import type { ArrowDetectSchemaResult } from "@datastream/arrow";
+import {
+ arrowBatchFromArrayStream,
+ arrowBatchFromObjectStream,
+ arrowDetectSchemaStream,
+ arrowToArrayStream,
+ arrowToObjectStream,
+} from "@datastream/arrow";
+import type { Schema } from "apache-arrow";
+import { describe, expect, test } from "tstyche";
+
+const schema = {} as Schema;
+
+describe("ArrowDetectSchemaResult", () => {
+ test("has schema and fields", () => {
+ expect().type.toBeAssignableTo<{
+ schema: Schema | null;
+ fields: string[] | null;
+ }>();
+ });
+});
+
+describe("arrowDetectSchemaStream", () => {
+ test("accepts no options", () => {
+ expect(arrowDetectSchemaStream()).type.not.toBeAssignableTo();
+ });
+
+ test("accepts sampleSize", () => {
+ expect(
+ arrowDetectSchemaStream({ sampleSize: 100 }),
+ ).type.not.toBeAssignableTo();
+ });
+
+ test("exposes result", () => {
+ const stream = arrowDetectSchemaStream();
+ expect(stream.result).type.not.toBeAssignableTo();
+ });
+});
+
+describe("arrowBatchFromArrayStream", () => {
+ test("requires schema", () => {
+ expect(
+ arrowBatchFromArrayStream({ schema }),
+ ).type.not.toBeAssignableTo();
+ });
+
+ test("accepts lazy schema and batchSize", () => {
+ expect(
+ arrowBatchFromArrayStream({ schema: () => schema, batchSize: 512 }),
+ ).type.not.toBeAssignableTo();
+ });
+});
+
+describe("arrowBatchFromObjectStream", () => {
+ test("requires schema", () => {
+ expect(
+ arrowBatchFromObjectStream({ schema }),
+ ).type.not.toBeAssignableTo();
+ });
+});
+
+describe("arrowToArrayStream", () => {
+ test("accepts no options", () => {
+ expect(arrowToArrayStream()).type.not.toBeAssignableTo();
+ });
+});
+
+describe("arrowToObjectStream", () => {
+ test("accepts no options", () => {
+ expect(arrowToObjectStream()).type.not.toBeAssignableTo();
+ });
+});
diff --git a/packages/arrow/package.json b/packages/arrow/package.json
new file mode 100644
index 0000000..ab12ca0
--- /dev/null
+++ b/packages/arrow/package.json
@@ -0,0 +1,70 @@
+{
+ "name": "@datastream/arrow",
+ "version": "0.5.0",
+ "description": "Apache Arrow record batch transform streams",
+ "type": "module",
+ "engines": {
+ "node": ">=24"
+ },
+ "engineStrict": true,
+ "publishConfig": {
+ "access": "public"
+ },
+ "main": "./index.node.mjs",
+ "module": "./index.web.mjs",
+ "exports": {
+ ".": {
+ "node": {
+ "import": {
+ "types": "./index.d.ts",
+ "default": "./index.node.mjs"
+ }
+ },
+ "import": {
+ "types": "./index.d.ts",
+ "default": "./index.web.mjs"
+ }
+ },
+ "./webstream": {
+ "types": "./index.d.ts",
+ "default": "./index.web.mjs"
+ }
+ },
+ "types": "index.d.ts",
+ "files": [
+ "*.mjs",
+ "*.map",
+ "*.d.ts"
+ ],
+ "scripts": {
+ "test": "npm run test:unit",
+ "test:unit": "node --test",
+ "test:perf": "node --test index.perf.js",
+ "test:mutation": "cd ../.. && MUTATE_PACKAGE=\"$(basename \"$OLDPWD\")\" stryker run"
+ },
+ "license": "MIT",
+ "keywords": [
+ "arrow",
+ "apache-arrow",
+ "transform",
+ "Web Stream API",
+ "Node Stream API"
+ ],
+ "author": {
+ "name": "datastream contributors",
+ "url": "https://github.com/willfarrell/datastream/graphs/contributors"
+ },
+ "repository": {
+ "type": "git",
+ "url": "github:willfarrell/datastream",
+ "directory": "packages/arrow"
+ },
+ "bugs": {
+ "url": "https://github.com/willfarrell/datastream/issues"
+ },
+ "homepage": "https://datastream.js.org",
+ "dependencies": {
+ "@datastream/core": "0.5.0",
+ "apache-arrow": "21.1.0"
+ }
+}
diff --git a/packages/duckdb/README.md b/packages/duckdb/README.md
new file mode 100644
index 0000000..9895364
--- /dev/null
+++ b/packages/duckdb/README.md
@@ -0,0 +1,52 @@
+
+ <datastream> `duckdb`
+
+ DuckDB writable streams (copy-from).
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+You can read the documentation at: https://datastream.js.org
+
+
+
+## Install
+
+To install datastream you can use NPM:
+
+```bash
+npm install --save @datastream/duckdb
+```
+
+
+## Documentation and examples
+
+For documentation and examples, refer to the main [datastream monorepo on GitHub](https://github.com/willfarrell/datastream) or [datastream official website](https://datastream.js.org).
+
+
+## Contributing
+
+Everyone is very welcome to contribute to this repository. Feel free to [raise issues](https://github.com/willfarrell/datastream/issues) or to [submit Pull Requests](https://github.com/willfarrell/datastream/pulls).
+
+
+## License
+
+Licensed under [MIT License](LICENSE). Copyright (c) 2026 [will Farrell](https://github.com/willfarrell), and [datastream contributors](https://github.com/willfarrell/datastream/graphs/contributors).
\ No newline at end of file
diff --git a/packages/duckdb/index.d.ts b/packages/duckdb/index.d.ts
new file mode 100644
index 0000000..6834cd3
--- /dev/null
+++ b/packages/duckdb/index.d.ts
@@ -0,0 +1,27 @@
+// Copyright 2026 will Farrell, and datastream contributors.
+// SPDX-License-Identifier: MIT
+import type { DatastreamWritable, StreamOptions } from "@datastream/core";
+import type { RecordBatch, Schema } from "apache-arrow";
+
+export function duckdbConnect(
+ path?: string,
+ options?: Record,
+): Promise;
+
+export function duckdbAppenderStream(
+ options: {
+ db: unknown;
+ table: string;
+ schema?: Schema | (() => Schema);
+ },
+ streamOptions?: StreamOptions,
+): Promise>>;
+
+export function duckdbArrowInsertStream(
+ options: {
+ db: unknown;
+ table: string;
+ schema?: Schema | (() => Schema);
+ },
+ streamOptions?: StreamOptions,
+): Promise>;
diff --git a/packages/duckdb/index.fuzz.js b/packages/duckdb/index.fuzz.js
new file mode 100644
index 0000000..947769e
--- /dev/null
+++ b/packages/duckdb/index.fuzz.js
@@ -0,0 +1,176 @@
+import test from "node:test";
+import { arrowBatchFromObjectStream } from "@datastream/arrow";
+import { createReadableStream, pipeline } from "@datastream/core";
+import {
+ duckdbAppenderStream,
+ duckdbArrowInsertStream,
+ duckdbConnect,
+} from "@datastream/duckdb";
+import { Field, Int32, Schema, Utf8 } from "apache-arrow";
+import fc from "fast-check";
+
+const catchError = (input, e) => {
+ const expectedErrors = [
+ // Invalid table name (non-string or empty string)
+ "duckdb: identifier must be a non-empty string",
+ // DuckDB type coercion failures (e.g. out-of-range float → INTEGER)
+ "Failed to cast value:",
+ // Cannot store objects/arrays/symbols/functions into typed columns
+ "Cannot create values of type ANY. Specify a specific type.",
+ // Column count mismatch between batch and table
+ "column count mismatch",
+ ];
+ for (const prefix of expectedErrors) {
+ if (e.message?.includes(prefix) || e.message === prefix) {
+ return;
+ }
+ }
+ console.error(input, e);
+ throw e;
+};
+
+// Fixed in-memory schema for the shared users table used across fuzz iterations.
+const arrowSchema = new Schema([
+ new Field("id", new Int32(), true),
+ new Field("name", new Utf8(), true),
+]);
+
+// *** duckdbAppenderStream — fuzz random object rows *** //
+test("fuzz duckdbAppenderStream w/ random object rows", async () => {
+ const db = await duckdbConnect();
+ await db.run("CREATE TABLE fuzz_appender (id INTEGER, name VARCHAR)");
+
+ await fc.assert(
+ fc.asyncProperty(
+ // Generate arrays of objects with arbitrary id/name values (including
+ // edge cases like null, undefined, wrong types, booleans, etc.)
+ fc.array(
+ fc.record({
+ id: fc.oneof(
+ fc.integer(),
+ fc.float(),
+ fc.string(),
+ fc.boolean(),
+ fc.constant(null),
+ fc.constant(undefined),
+ ),
+ name: fc.oneof(
+ fc.string(),
+ fc.integer(),
+ fc.constant(null),
+ fc.constant(undefined),
+ ),
+ }),
+ { minLength: 1, maxLength: 20 },
+ ),
+ async (input) => {
+ try {
+ await pipeline([
+ createReadableStream(input),
+ await duckdbAppenderStream({ db, table: "fuzz_appender" }),
+ ]);
+ // Reset table for next iteration so row counts don't grow unbounded.
+ await db.run("DELETE FROM fuzz_appender");
+ } catch (e) {
+ catchError(input, e);
+ }
+ },
+ ),
+ {
+ numRuns: 200,
+ verbose: 2,
+ examples: [],
+ },
+ );
+
+ db.closeSync();
+});
+
+// *** duckdbAppenderStream — fuzz random table names and row shapes *** //
+test("fuzz duckdbAppenderStream w/ random table name", async () => {
+ await fc.assert(
+ fc.asyncProperty(
+ // Table names — many will be invalid (non-string, empty, etc.)
+ fc.oneof(
+ fc.string({ minLength: 0, maxLength: 50 }),
+ fc.integer(),
+ fc.constant(null),
+ fc.constant(undefined),
+ ),
+ fc.array(
+ fc.record({
+ id: fc.integer({ min: 0, max: 9_999 }),
+ name: fc.string({ minLength: 0, maxLength: 20 }),
+ }),
+ { minLength: 1, maxLength: 5 },
+ ),
+ async (table, input) => {
+ const db = await duckdbConnect();
+ // Only create the table when the name is a valid non-empty string so
+ // we exercise both valid and invalid-name paths cleanly.
+ if (typeof table === "string" && table.length > 0) {
+ try {
+ await db.run(
+ `CREATE TABLE "${table.replaceAll('"', '""')}" (id INTEGER, name VARCHAR)`,
+ );
+ } catch (_) {
+ // Some random strings produce invalid SQL even after quoting;
+ // skip table creation and let the appender surface the error.
+ }
+ }
+ try {
+ await pipeline([
+ createReadableStream(input),
+ await duckdbAppenderStream({ db, table }),
+ ]);
+ } catch (e) {
+ catchError({ table, input }, e);
+ }
+ db.closeSync();
+ },
+ ),
+ {
+ numRuns: 200,
+ verbose: 2,
+ examples: [],
+ },
+ );
+});
+
+// *** duckdbArrowInsertStream — fuzz random Arrow record batches *** //
+test("fuzz duckdbArrowInsertStream w/ random object rows via Arrow batches", async () => {
+ const db = await duckdbConnect();
+ await db.run("CREATE TABLE fuzz_arrow (id INTEGER, name VARCHAR)");
+
+ await fc.assert(
+ fc.asyncProperty(
+ fc.array(
+ fc.record({
+ id: fc.oneof(fc.integer({ min: 0, max: 9_999 }), fc.constant(null)),
+ name: fc.oneof(fc.string({ maxLength: 30 }), fc.constant(null)),
+ }),
+ { minLength: 1, maxLength: 50 },
+ ),
+ fc.integer({ min: 1, max: 100 }),
+ async (input, batchSize) => {
+ try {
+ await pipeline([
+ createReadableStream(input),
+ arrowBatchFromObjectStream({ schema: arrowSchema, batchSize }),
+ await duckdbArrowInsertStream({ db, table: "fuzz_arrow" }),
+ ]);
+ await db.run("DELETE FROM fuzz_arrow");
+ } catch (e) {
+ catchError({ input, batchSize }, e);
+ }
+ },
+ ),
+ {
+ numRuns: 200,
+ verbose: 2,
+ examples: [],
+ },
+ );
+
+ db.closeSync();
+});
diff --git a/packages/duckdb/index.node.js b/packages/duckdb/index.node.js
new file mode 100644
index 0000000..3e5df8f
--- /dev/null
+++ b/packages/duckdb/index.node.js
@@ -0,0 +1,271 @@
+// Copyright 2026 will Farrell, and datastream contributors.
+// SPDX-License-Identifier: MIT
+import { createWritableStream, resolveLazy } from "@datastream/core";
+import { DuckDBInstance } from "@duckdb/node-api";
+
+export const duckdbConnect = async (path = ":memory:", options) => {
+ // An empty path is a caller mistake (node-api would silently open an in-memory
+ // database, masking the bug). Reject it so the ":memory:" sentinel must be used
+ // explicitly for an in-memory database.
+ if (typeof path !== "string" || path.length === 0) {
+ throw new TypeError(
+ 'duckdb: path must be a non-empty string (use ":memory:" for in-memory)',
+ );
+ }
+ const instance = await DuckDBInstance.create(path, options);
+ return await instance.connect();
+};
+
+// DuckDB has no parameter binding for identifiers, so table/column names are
+// interpolated into SQL. Double the embedded quotes and require a non-empty
+// string so a crafted name can't break out of the quoted identifier.
+const quoteIdent = (name) => {
+ if (typeof name !== "string" || name.length === 0) {
+ throw new TypeError("duckdb: identifier must be a non-empty string");
+ }
+ return `"${name.replaceAll('"', '""')}"`;
+};
+
+// A failed existence probe should only be read as "table does not exist" when
+// the error is a missing-table/catalog error. Any other failure (lock,
+// permission, column read error, ...) must propagate so it is not masked by a
+// confusing downstream "table already exists" from CREATE TABLE.
+const isMissingTableError = (error) => {
+ const message = String(error?.message ?? error).toLowerCase();
+ return (
+ message.includes("does not exist") ||
+ message.includes("not found") ||
+ message.includes("catalog error")
+ );
+};
+
+const tableExists = async (db, table) => {
+ try {
+ await db.run(`SELECT 1 FROM ${quoteIdent(table)} LIMIT 0`);
+ return true;
+ } catch (error) {
+ if (isMissingTableError(error)) return false;
+ throw error;
+ }
+};
+
+const fetchColumnNames = async (db, table) => {
+ const reader = await db.runAndReadAll(
+ `SELECT * FROM ${quoteIdent(table)} LIMIT 0`,
+ );
+ return reader.columnNames();
+};
+
+const arrowTypeToDuckDBSQL = (type) => {
+ const name = type?.constructor?.name;
+ switch (name) {
+ case "Bool":
+ return "BOOLEAN";
+ case "Int8":
+ return "TINYINT";
+ case "Int16":
+ return "SMALLINT";
+ case "Int32":
+ return "INTEGER";
+ case "Int64":
+ return "BIGINT";
+ case "Uint8":
+ return "UTINYINT";
+ case "Uint16":
+ return "USMALLINT";
+ case "Uint32":
+ return "UINTEGER";
+ case "Uint64":
+ return "UBIGINT";
+ case "Float32":
+ return "REAL";
+ case "Float64":
+ return "DOUBLE";
+ case "Date_":
+ return "DATE";
+ case "TimestampSecond":
+ return "TIMESTAMP_S";
+ case "TimestampMillisecond":
+ return "TIMESTAMP_MS";
+ case "TimestampMicrosecond":
+ return "TIMESTAMP";
+ case "TimestampNanosecond":
+ return "TIMESTAMP_NS";
+ default:
+ return "VARCHAR";
+ }
+};
+
+const createTableFromArrowSchema = async (db, table, schema) => {
+ const cols = schema.fields
+ .map((f) => `${quoteIdent(f.name)} ${arrowTypeToDuckDBSQL(f.type)}`)
+ .join(", ");
+ await db.run(`CREATE TABLE ${quoteIdent(table)} (${cols})`);
+};
+
+const ensureTableAndColumns = async (db, table, schema) => {
+ if (schema && !(await tableExists(db, table))) {
+ await createTableFromArrowSchema(db, table, schema);
+ }
+ // Always derive the column order from the table's PHYSICAL layout. The
+ // appender appends positionally into physical columns, so trusting the
+ // provided schema.fields order would misalign (or hard-fail with a cast
+ // error) whenever the schema order differs from the physical column order.
+ return fetchColumnNames(db, table);
+};
+
+const appendCell = (appender, value) => {
+ if (value === null || value === undefined) {
+ appender.appendNull();
+ } else {
+ appender.appendValue(value);
+ }
+};
+
+// Release a native appender handle exactly once. createWritableStream only runs
+// final() on normal completion, so a thrown write() (or an aborted pipeline)
+// would otherwise leak the underlying native appender.
+const closeAppenderOnce = (state) => {
+ if (!state.appender || state.closed) return;
+ state.closed = true;
+ try {
+ state.appender.closeSync();
+ } catch (_error) {
+ // best-effort: the handle is being torn down on an error path.
+ }
+};
+
+// createWritableStream (core) only wires write/final, so error/abort teardown
+// never releases the native appender. Attach cleanup to the Writable's lifecycle
+// (error/close) and to streamOptions.signal so an upstream error or an abort
+// still closes the handle. closeAppenderOnce is idempotent, so the normal
+// final()-then-close path stays a no-op here.
+const wireAppenderCleanup = (stream, state, streamOptions) => {
+ const cleanup = () => closeAppenderOnce(state);
+ stream.once("error", cleanup);
+ stream.once("close", cleanup);
+ // streamOptions always defaults to {} at the public entry points, so it is
+ // never nullish here.
+ const signal = streamOptions.signal;
+ if (signal) {
+ // The appender is created lazily (during the first write), so it never
+ // exists yet at wiring time; an already-aborted signal is therefore handled
+ // by the stream's own abort teardown (which fires "error"/"close" above).
+ // For a not-yet-aborted signal, release the handle when it aborts and stop
+ // listening once the stream closes normally.
+ signal.addEventListener("abort", cleanup, { once: true });
+ stream.once("close", () => signal.removeEventListener("abort", cleanup));
+ }
+ return stream;
+};
+
+export const duckdbAppenderStream = async (
+ { db, table, schema },
+ streamOptions = {},
+) => {
+ // state.appender starts undefined (set lazily in init) and state.closed starts
+ // falsy; both are read with truthiness checks, so an empty object suffices.
+ const state = {};
+ let columnNames;
+
+ const init = async () => {
+ const resolvedSchema = resolveLazy(schema);
+ columnNames = await ensureTableAndColumns(db, table, resolvedSchema);
+ state.appender = await db.createAppender(table);
+ };
+
+ const write = async (row) => {
+ if (!state.appender) await init();
+ try {
+ const isArray = Array.isArray(row);
+ for (let i = 0, l = columnNames.length; i < l; i++) {
+ const v = isArray ? row[i] : row[columnNames[i]];
+ appendCell(state.appender, v);
+ }
+ state.appender.endRow();
+ } catch (error) {
+ closeAppenderOnce(state);
+ throw error;
+ }
+ };
+ const final = async () => {
+ if (state.appender && !state.closed) {
+ state.appender.flushSync();
+ closeAppenderOnce(state);
+ }
+ };
+
+ return wireAppenderCleanup(
+ createWritableStream(write, final, streamOptions),
+ state,
+ streamOptions,
+ );
+};
+
+export const duckdbArrowInsertStream = async (
+ { db, table, schema },
+ streamOptions = {},
+) => {
+ // See duckdbAppenderStream: appender/closed are only read for truthiness.
+ const state = {};
+ let columnNames;
+
+ const init = async () => {
+ const resolvedSchema = resolveLazy(schema);
+ columnNames = await ensureTableAndColumns(db, table, resolvedSchema);
+ state.appender = await db.createAppender(table);
+ };
+
+ const write = async (batch) => {
+ if (!state.appender) await init();
+ try {
+ const colCount = columnNames.length;
+ // Validate the batch's column count against the target table so a
+ // mismatch surfaces a clear schema error instead of a null-deref
+ // (too few columns) or silent column drop (too many columns).
+ const batchColCount = batch.schema?.fields?.length ?? batch.numCols;
+ if (batchColCount !== colCount) {
+ throw new Error(
+ `duckdb: record batch column count (${batchColCount}) does not match table "${table}" column count (${colCount})`,
+ );
+ }
+ const cols = [];
+ for (let i = 0; i < colCount; i++) {
+ const col = batch.getChildAt(i);
+ if (col === null || col === undefined) {
+ throw new Error(
+ `duckdb: record batch is missing column ${i} for table "${table}"`,
+ );
+ }
+ cols.push(col);
+ }
+ const rowCount = batch.numRows;
+ for (let r = 0; r < rowCount; r++) {
+ for (let i = 0; i < colCount; i++)
+ appendCell(state.appender, cols[i].get(r));
+ state.appender.endRow();
+ }
+ } catch (error) {
+ closeAppenderOnce(state);
+ throw error;
+ }
+ };
+ const final = async () => {
+ if (state.appender && !state.closed) {
+ state.appender.flushSync();
+ closeAppenderOnce(state);
+ }
+ };
+
+ return wireAppenderCleanup(
+ createWritableStream(write, final, streamOptions),
+ state,
+ streamOptions,
+ );
+};
+
+export default {
+ connect: duckdbConnect,
+ appenderStream: duckdbAppenderStream,
+ arrowInsertStream: duckdbArrowInsertStream,
+};
diff --git a/packages/duckdb/index.perf.js b/packages/duckdb/index.perf.js
new file mode 100644
index 0000000..350444e
--- /dev/null
+++ b/packages/duckdb/index.perf.js
@@ -0,0 +1,101 @@
+import test from "node:test";
+import {
+ arrowBatchFromObjectStream,
+ arrowDetectSchemaStream,
+} from "@datastream/arrow";
+import { createReadableStream, pipeline } from "@datastream/core";
+import {
+ duckdbAppenderStream,
+ duckdbArrowInsertStream,
+ duckdbConnect,
+} from "@datastream/duckdb";
+import { Field, Int32, Schema, Utf8 } from "apache-arrow";
+import { Bench } from "tinybench";
+
+// -- Config --
+
+const time = Number(process.env.BENCH_TIME ?? 5_000);
+const N = 10_000;
+
+// -- Data generators --
+
+const rows = Array.from({ length: N }, (_, i) => ({
+ id: i,
+ name: `user_${i}`,
+}));
+
+const arrowSchema = new Schema([
+ new Field("id", new Int32(), true),
+ new Field("name", new Utf8(), true),
+]);
+
+// -- Tests --
+
+test("perf: duckdbAppenderStream insert throughput", async () => {
+ const bench = new Bench({ name: "duckdbAppenderStream", time });
+ const db = await duckdbConnect();
+ let tableIdx = 0;
+
+ bench.add(`${N} object rows`, async () => {
+ const table = `bench_appender_${tableIdx++}`;
+ await db.run(`CREATE TABLE ${table} (id INTEGER, name VARCHAR)`);
+ await pipeline([
+ createReadableStream(rows),
+ await duckdbAppenderStream({ db, table }),
+ ]);
+ });
+
+ await bench.run();
+ db.closeSync();
+ console.log(`\n${bench.name}`);
+ console.table(bench.table());
+});
+
+test("perf: duckdbArrowInsertStream insert throughput", async () => {
+ const bench = new Bench({ name: "duckdbArrowInsertStream", time });
+ const db = await duckdbConnect();
+ let tableIdx = 0;
+
+ bench.add(`${N} rows via Arrow batches (batchSize=1000)`, async () => {
+ const table = `bench_arrow_${tableIdx++}`;
+ await db.run(`CREATE TABLE ${table} (id INTEGER, name VARCHAR)`);
+ await pipeline([
+ createReadableStream(rows),
+ arrowBatchFromObjectStream({ schema: arrowSchema, batchSize: 1_000 }),
+ await duckdbArrowInsertStream({ db, table }),
+ ]);
+ });
+
+ await bench.run();
+ db.closeSync();
+ console.log(`\n${bench.name}`);
+ console.table(bench.table());
+});
+
+test("perf: duckdbAppenderStream with schema auto-create table", async () => {
+ const bench = new Bench({
+ name: "duckdbAppenderStream (schema + auto-create)",
+ time,
+ });
+ const db = await duckdbConnect();
+ let tableIdx = 0;
+
+ bench.add(`${N} rows, schema provided`, async () => {
+ const table = `bench_appender_schema_${tableIdx++}`;
+ const detect = arrowDetectSchemaStream({ sampleSize: 10 });
+ await pipeline([
+ createReadableStream(rows),
+ detect,
+ await duckdbAppenderStream({
+ db,
+ table,
+ schema: () => detect.result().value.schema,
+ }),
+ ]);
+ });
+
+ await bench.run();
+ db.closeSync();
+ console.log(`\n${bench.name}`);
+ console.table(bench.table());
+});
diff --git a/packages/duckdb/index.test.js b/packages/duckdb/index.test.js
new file mode 100644
index 0000000..cc1fa23
--- /dev/null
+++ b/packages/duckdb/index.test.js
@@ -0,0 +1,2016 @@
+import { deepStrictEqual, ok, strictEqual } from "node:assert";
+import test from "node:test";
+
+import {
+ arrowBatchFromObjectStream,
+ arrowDetectSchemaStream,
+} from "@datastream/arrow";
+import { createReadableStream, pipeline } from "@datastream/core";
+import {
+ duckdbAppenderStream,
+ duckdbArrowInsertStream,
+ duckdbConnect,
+} from "@datastream/duckdb";
+import {
+ Bool,
+ Date_,
+ Field,
+ Float32,
+ Float64,
+ Int8,
+ Int16,
+ Int32,
+ Int64,
+ Schema,
+ TimestampMicrosecond,
+ TimestampMillisecond,
+ TimestampNanosecond,
+ TimestampSecond,
+ Uint8,
+ Uint16,
+ Uint32,
+ Uint64,
+ Utf8,
+} from "apache-arrow";
+
+let variant = "unknown";
+for (const execArgv of process.execArgv) {
+ const flag = "--conditions=";
+ if (execArgv.includes(flag)) {
+ variant = execArgv.replace(flag, "");
+ }
+}
+
+// Tests run unconditionally — Node satisfies the "node" export condition
+// under both --conditions=node and --conditions=webstream, so the @duckdb/node-api
+// impl loads either way.
+
+const usersArrowSchema = new Schema([
+ new Field("id", new Int32(), true),
+ new Field("name", new Utf8(), true),
+]);
+
+const setupTable = async () => {
+ const db = await duckdbConnect();
+ await db.run("CREATE TABLE users (id INTEGER, name VARCHAR)");
+ return db;
+};
+
+const selectAll = async (db) => {
+ const reader = await db.runAndReadAll(
+ "SELECT id, name FROM users ORDER BY id",
+ );
+ return reader.getRowsJS();
+};
+
+test(`${variant}: duckdbAppenderStream should insert object rows and pull schema from DESCRIBE`, async () => {
+ const db = await setupTable();
+ await pipeline([
+ createReadableStream([
+ { id: 1, name: "alice" },
+ { id: 2, name: "bob" },
+ ]),
+ await duckdbAppenderStream({ db, table: "users" }),
+ ]);
+ const rows = await selectAll(db);
+ deepStrictEqual(rows, [
+ [1, "alice"],
+ [2, "bob"],
+ ]);
+ db.closeSync();
+});
+
+test(`${variant}: duckdbAppenderStream should insert array rows`, async () => {
+ const db = await setupTable();
+ await pipeline([
+ createReadableStream([
+ [1, "alice"],
+ [2, "bob"],
+ ]),
+ await duckdbAppenderStream({ db, table: "users" }),
+ ]);
+ const rows = await selectAll(db);
+ strictEqual(rows.length, 2);
+ strictEqual(rows[0][1], "alice");
+ db.closeSync();
+});
+
+test(`${variant}: duckdbAppenderStream should handle nulls`, async () => {
+ const db = await setupTable();
+ await pipeline([
+ createReadableStream([{ id: 1, name: null }]),
+ await duckdbAppenderStream({ db, table: "users" }),
+ ]);
+ const rows = await selectAll(db);
+ deepStrictEqual(rows, [[1, null]]);
+ db.closeSync();
+});
+
+test(`${variant}: duckdbArrowInsertStream should insert Arrow record batches`, async () => {
+ const db = await setupTable();
+ const detect = arrowDetectSchemaStream({ sampleSize: 2 });
+ await pipeline([
+ createReadableStream([
+ { id: 1, name: "alice" },
+ { id: 2, name: "bob" },
+ { id: 3, name: "carol" },
+ ]),
+ detect,
+ arrowBatchFromObjectStream({
+ schema: () => detect.result().value.schema,
+ batchSize: 2,
+ }),
+ await duckdbArrowInsertStream({ db, table: "users" }),
+ ]);
+ const rows = await selectAll(db);
+ deepStrictEqual(rows, [
+ [1, "alice"],
+ [2, "bob"],
+ [3, "carol"],
+ ]);
+ db.closeSync();
+});
+
+test(`${variant}: duckdbAppenderStream should CREATE TABLE when given a schema and table is missing`, async () => {
+ const db = await duckdbConnect();
+ const detect = arrowDetectSchemaStream({ sampleSize: 2 });
+ await pipeline([
+ createReadableStream([
+ { id: 1, name: "alice" },
+ { id: 2, name: "bob" },
+ ]),
+ detect,
+ await duckdbAppenderStream({
+ db,
+ table: "users",
+ schema: () => detect.result().value.schema,
+ }),
+ ]);
+ const rows = await selectAll(db);
+ deepStrictEqual(rows, [
+ [1, "alice"],
+ [2, "bob"],
+ ]);
+ db.closeSync();
+});
+
+test(`${variant}: duckdbAppenderStream escapes identifiers / neutralizes SQL injection in table name`, async () => {
+ const db = await duckdbConnect();
+ await db.run("CREATE TABLE secret (id INTEGER)");
+ await db.run("INSERT INTO secret VALUES (1)");
+ // A quote-laden name must be treated as a single (weird) identifier, not as
+ // a statement boundary that drops `secret`.
+ const table = `evil"; DROP TABLE secret; --`;
+ const detect = arrowDetectSchemaStream({ sampleSize: 1 });
+ await pipeline([
+ createReadableStream([{ id: 1, name: "alice" }]),
+ detect,
+ await duckdbAppenderStream({
+ db,
+ table,
+ schema: () => detect.result().value.schema,
+ }),
+ ]);
+ // `secret` survived because the malicious name was escaped into one ident.
+ const reader = await db.runAndReadAll("SELECT id FROM secret");
+ deepStrictEqual(reader.getRowsJS(), [[1]]);
+ db.closeSync();
+});
+
+test(`${variant}: duckdbAppenderStream closes the appender when a write fails (no native handle leak)`, async () => {
+ let closed = false;
+ const appender = {
+ appendValue: (v) => {
+ if (v === "poison") throw new Error("bad cell");
+ },
+ appendNull: () => {},
+ endRow: () => {},
+ flushSync: () => {},
+ closeSync: () => {
+ closed = true;
+ },
+ };
+ const db = {
+ runAndReadAll: async () => ({ columnNames: () => ["id", "name"] }),
+ createAppender: async () => appender,
+ };
+ let caught;
+ try {
+ await pipeline([
+ createReadableStream([{ id: 1, name: "poison" }]),
+ await duckdbAppenderStream({ db, table: "users" }),
+ ]);
+ } catch (e) {
+ caught = e;
+ }
+ ok(caught, "the write error must propagate");
+ ok(caught.message.includes("bad cell"));
+ // The native appender handle must be released even though final() never ran.
+ strictEqual(closed, true);
+});
+
+test(`${variant}: duckdbArrowInsertStream closes the appender when a write fails (no native handle leak)`, async () => {
+ let closed = false;
+ const appender = {
+ appendValue: () => {
+ throw new Error("bad batch cell");
+ },
+ appendNull: () => {},
+ endRow: () => {},
+ flushSync: () => {},
+ closeSync: () => {
+ closed = true;
+ },
+ };
+ const db = {
+ runAndReadAll: async () => ({ columnNames: () => ["id", "name"] }),
+ createAppender: async () => appender,
+ };
+ const batchStream = arrowBatchFromObjectStream({
+ schema: usersArrowSchema,
+ batchSize: 10,
+ });
+ let caught;
+ try {
+ await pipeline([
+ createReadableStream([{ id: 1, name: "alice" }]),
+ batchStream,
+ await duckdbArrowInsertStream({ db, table: "users" }),
+ ]);
+ } catch (e) {
+ caught = e;
+ }
+ ok(caught, "the write error must propagate");
+ strictEqual(closed, true);
+});
+
+test(`${variant}: duckdbAppenderStream rejects a non-string table name`, async () => {
+ const db = await duckdbConnect();
+ try {
+ await pipeline([
+ createReadableStream([{ id: 1 }]),
+ await duckdbAppenderStream({ db, table: 42 }),
+ ]);
+ throw new Error("Should have thrown");
+ } catch (e) {
+ ok(e.message.includes("identifier must be a non-empty string"));
+ }
+ db.closeSync();
+});
+
+// Provided schema field order differs from the physical table column order.
+// The appender appends positionally into the table's PHYSICAL columns, so the
+// column order MUST come from the physical table, never from schema.fields.
+const reversedUsersSchema = new Schema([
+ new Field("name", new Utf8(), true),
+ new Field("id", new Int32(), true),
+]);
+
+test(`${variant}: duckdbAppenderStream maps object rows by physical column order when provided schema order differs`, async () => {
+ const db = await setupTable(); // physical order: id INTEGER, name VARCHAR
+ await pipeline([
+ createReadableStream([
+ { id: 1, name: "alice" },
+ { id: 2, name: "bob" },
+ ]),
+ await duckdbAppenderStream({
+ db,
+ table: "users",
+ schema: reversedUsersSchema,
+ }),
+ ]);
+ const rows = await selectAll(db);
+ deepStrictEqual(rows, [
+ [1, "alice"],
+ [2, "bob"],
+ ]);
+ db.closeSync();
+});
+
+test(`${variant}: duckdbArrowInsertStream maps batch columns by physical column order when provided schema order differs`, async () => {
+ const db = await setupTable(); // physical order: id INTEGER, name VARCHAR
+ await pipeline([
+ createReadableStream([
+ { id: 1, name: "alice" },
+ { id: 2, name: "bob" },
+ ]),
+ arrowBatchFromObjectStream({
+ schema: usersArrowSchema,
+ batchSize: 2,
+ }),
+ await duckdbArrowInsertStream({
+ db,
+ table: "users",
+ schema: reversedUsersSchema,
+ }),
+ ]);
+ const rows = await selectAll(db);
+ deepStrictEqual(rows, [
+ [1, "alice"],
+ [2, "bob"],
+ ]);
+ db.closeSync();
+});
+
+test(`${variant}: duckdbAppenderStream closes the appender when an upstream source errors AFTER init (no native handle leak)`, async () => {
+ let closed = false;
+ const appender = {
+ appendValue: () => {},
+ appendNull: () => {},
+ endRow: () => {},
+ flushSync: () => {},
+ closeSync: () => {
+ closed = true;
+ },
+ };
+ const db = {
+ runAndReadAll: async () => ({ columnNames: () => ["id", "name"] }),
+ createAppender: async () => appender,
+ };
+ async function* source() {
+ yield { id: 1, name: "alice" }; // creates the appender (init)
+ throw new Error("upstream boom");
+ }
+ let caught;
+ try {
+ await pipeline([
+ createReadableStream(source()),
+ await duckdbAppenderStream({ db, table: "users" }),
+ ]);
+ } catch (e) {
+ caught = e;
+ }
+ ok(caught, "the upstream error must propagate");
+ ok(caught.message.includes("upstream boom"));
+ // The native appender handle must be released even though the error came
+ // from upstream (final never runs, write's catch never fires).
+ strictEqual(closed, true);
+});
+
+test(`${variant}: duckdbAppenderStream handles its own "error" event (absorbs it and releases the appender)`, async () => {
+ let closed = false;
+ const appender = {
+ appendValue: () => {},
+ appendNull: () => {},
+ endRow: () => {},
+ flushSync: () => {},
+ closeSync: () => {
+ closed = true;
+ },
+ };
+ const db = {
+ runAndReadAll: async () => ({ columnNames: () => ["id"] }),
+ createAppender: async () => appender,
+ };
+ const stream = await duckdbAppenderStream({ db, table: "users" });
+ // Lazily create the native appender so cleanup has a handle to release.
+ await new Promise((resolve, reject) => {
+ stream.write({ id: 1 }, (error) => (error ? reject(error) : resolve()));
+ });
+ // The stream registers its own "error" listener, so emitting "error" must be
+ // absorbed (not rethrown as an unhandled "error" event) and must release the
+ // appender. Without that listener, emit("error") throws here.
+ let threw = false;
+ try {
+ stream.emit("error", new Error("boom"));
+ } catch {
+ threw = true;
+ }
+ strictEqual(threw, false, 'the stream must handle its own "error" event');
+ strictEqual(closed, true, "the appender handle must be released on error");
+ stream.destroy();
+});
+
+test(`${variant}: duckdbArrowInsertStream closes the appender when an upstream source errors AFTER init (no native handle leak)`, async () => {
+ let closed = false;
+ const appender = {
+ appendValue: () => {},
+ appendNull: () => {},
+ endRow: () => {},
+ flushSync: () => {},
+ closeSync: () => {
+ closed = true;
+ },
+ };
+ const db = {
+ runAndReadAll: async () => ({ columnNames: () => ["id", "name"] }),
+ createAppender: async () => appender,
+ };
+ // A passthrough-style fake batch (2 columns, matching the table) that
+ // triggers init() on first write, then the upstream errors before final().
+ const fakeBatch = {
+ schema: { fields: [{ name: "id" }, { name: "name" }] },
+ numRows: 1,
+ getChildAt: () => ({ get: () => 1 }),
+ };
+ async function* source() {
+ yield fakeBatch; // creates the appender (init)
+ throw new Error("upstream batch boom");
+ }
+ let caught;
+ try {
+ await pipeline([
+ createReadableStream(source()),
+ await duckdbArrowInsertStream({ db, table: "users" }),
+ ]);
+ } catch (e) {
+ caught = e;
+ }
+ ok(caught, "the upstream error must propagate");
+ ok(caught.message.includes("upstream batch boom"));
+ strictEqual(closed, true);
+});
+
+test(`${variant}: duckdbArrowInsertStream throws a descriptive error when the batch column count does not match the table`, async () => {
+ const db = await setupTable(); // table users(id, name) -> 2 columns
+ // A batch with only one column does not match the 2-column table.
+ const oneColSchema = new Schema([new Field("id", new Int32(), true)]);
+ let caught;
+ try {
+ await pipeline([
+ createReadableStream([{ id: 1 }]),
+ arrowBatchFromObjectStream({ schema: oneColSchema, batchSize: 2 }),
+ await duckdbArrowInsertStream({ db, table: "users" }),
+ ]);
+ } catch (e) {
+ caught = e;
+ }
+ ok(caught, "a column-count mismatch must throw");
+ ok(
+ caught.message.includes("column"),
+ `error must mention column mismatch, got: ${caught?.message}`,
+ );
+ db.closeSync();
+});
+
+// *** web duckdbArrowInsertStream (direct file import) *** //
+// index.web.js's duckdb-wasm connect path requires a Worker-capable browser
+// runtime, but the Arrow-IPC serialization path (the data-loss bug) can be
+// exercised with a fake db that only records what is inserted. Node resolves
+// @datastream/duckdb to the node build under both conditions, so import the web
+// source directly to test the web code path.
+const importWeb = () =>
+ import(`file://${new URL("./index.web.js", import.meta.url).pathname}`);
+
+test(`${variant}: web duckdbArrowInsertStream inserts ALL record batches, not just the first`, async () => {
+ const { duckdbArrowInsertStream: webArrowInsertStream } = await importWeb();
+ let inserted;
+ const db = {
+ // tableExists() probe — succeed so the table is treated as existing.
+ query: async () => ({ schema: { fields: usersArrowSchema.fields } }),
+ insertArrowTable: async (arrowTable) => {
+ inserted = arrowTable;
+ },
+ };
+ // batchSize 1 forces three separate RecordBatch objects (the bug merged
+ // three complete IPC streams and the reader stopped at the first EOS,
+ // dropping batches 2 and 3).
+ await pipeline([
+ createReadableStream([
+ { id: 1, name: "alice" },
+ { id: 2, name: "bob" },
+ { id: 3, name: "carol" },
+ ]),
+ arrowBatchFromObjectStream({ schema: usersArrowSchema, batchSize: 1 }),
+ await webArrowInsertStream({
+ db,
+ table: "users",
+ schema: usersArrowSchema,
+ }),
+ ]);
+ ok(inserted, "insertArrowTable must be called");
+ strictEqual(inserted.numRows, 3);
+ const idCol = inserted.getChild("id");
+ deepStrictEqual([idCol.get(0), idCol.get(1), idCol.get(2)], [1, 2, 3]);
+});
+
+test(`${variant}: web duckdbAppenderStream sends object rows via a by-name prepared INSERT`, async () => {
+ const { duckdbAppenderStream: webAppenderStream } = await importWeb();
+ let preparedSql;
+ let closed = false;
+ const sent = [];
+ const db = {
+ // tableExists() probe — succeed so the table is treated as existing.
+ query: async () => ({ schema: { fields: usersArrowSchema.fields } }),
+ prepare: async (sql) => {
+ preparedSql = sql;
+ return {
+ send: async (...values) => {
+ sent.push(values);
+ },
+ close: async () => {
+ closed = true;
+ },
+ };
+ },
+ };
+ await pipeline([
+ createReadableStream([
+ { id: 1, name: "alice" },
+ { id: 2, name: "bob" },
+ ]),
+ await webAppenderStream({ db, table: "users" }),
+ ]);
+ // The web build binds by name: the INSERT must list the (physical) columns
+ // and the sent values must follow that same column order.
+ ok(
+ preparedSql.includes('INSERT INTO "users"'),
+ `unexpected SQL: ${preparedSql}`,
+ );
+ ok(preparedSql.includes('"id"') && preparedSql.includes('"name"'));
+ deepStrictEqual(sent, [
+ [1, "alice"],
+ [2, "bob"],
+ ]);
+ strictEqual(closed, true, "prepared statement must be closed");
+});
+
+test(`${variant}: web duckdbAppenderStream maps object rows by physical column order when provided schema order differs`, async () => {
+ const { duckdbAppenderStream: webAppenderStream } = await importWeb();
+ const sent = [];
+ // Physical column order reported by the table probe is [id, name].
+ const db = {
+ query: async () => ({ schema: { fields: usersArrowSchema.fields } }),
+ prepare: async () => ({
+ send: async (...values) => {
+ sent.push(values);
+ },
+ close: async () => {},
+ }),
+ };
+ await pipeline([
+ createReadableStream([{ id: 1, name: "alice" }]),
+ await webAppenderStream({
+ db,
+ table: "users",
+ schema: reversedUsersSchema,
+ }),
+ ]);
+ // Even with a reversed provided schema, values follow physical order [id, name].
+ deepStrictEqual(sent, [[1, "alice"]]);
+});
+
+// *** arrowTypeToDuckDBSQL coverage *** //
+// Each Arrow type must map to its corresponding DuckDB SQL type name so that
+// CREATE TABLE produces the right column definition. We exercise every branch
+// through duckdbAppenderStream with a schema (which calls createTableFromArrowSchema
+// then DESCRIBE to confirm the column type).
+
+const describeColumns = async (db, table) => {
+ const r = await db.runAndReadAll(`DESCRIBE ${table}`);
+ const rows = r.getRowsJS();
+ return Object.fromEntries(rows.map((row) => [row[0], row[1]]));
+};
+
+test(`${variant}: arrowTypeToDuckDBSQL maps every Arrow type to the correct DuckDB column type`, async () => {
+ const db = await duckdbConnect();
+ const allTypesSchema = new Schema([
+ new Field("c_bool", new Bool(), true),
+ new Field("c_int8", new Int8(), true),
+ new Field("c_int16", new Int16(), true),
+ // Int32 is already exercised by the usersArrowSchema tests
+ new Field("c_int64", new Int64(), true),
+ new Field("c_uint8", new Uint8(), true),
+ new Field("c_uint16", new Uint16(), true),
+ new Field("c_uint32", new Uint32(), true),
+ new Field("c_uint64", new Uint64(), true),
+ new Field("c_float32", new Float32(), true),
+ new Field("c_float64", new Float64(), true),
+ new Field("c_date", new Date_(), true),
+ new Field("c_ts_s", new TimestampSecond(), true),
+ new Field("c_ts_ms", new TimestampMillisecond(), true),
+ new Field("c_ts_us", new TimestampMicrosecond(), true),
+ new Field("c_ts_ns", new TimestampNanosecond(), true),
+ new Field("c_str", new Utf8(), true),
+ ]);
+ await pipeline([
+ createReadableStream([
+ {
+ c_bool: null,
+ c_int8: null,
+ c_int16: null,
+ c_int64: null,
+ c_uint8: null,
+ c_uint16: null,
+ c_uint32: null,
+ c_uint64: null,
+ c_float32: null,
+ c_float64: null,
+ c_date: null,
+ c_ts_s: null,
+ c_ts_ms: null,
+ c_ts_us: null,
+ c_ts_ns: null,
+ c_str: null,
+ },
+ ]),
+ await duckdbAppenderStream({
+ db,
+ table: "all_types",
+ schema: allTypesSchema,
+ }),
+ ]);
+ const cols = await describeColumns(db, "all_types");
+ strictEqual(cols.c_bool, "BOOLEAN");
+ strictEqual(cols.c_int8, "TINYINT");
+ strictEqual(cols.c_int16, "SMALLINT");
+ strictEqual(cols.c_int64, "BIGINT");
+ strictEqual(cols.c_uint8, "UTINYINT");
+ strictEqual(cols.c_uint16, "USMALLINT");
+ strictEqual(cols.c_uint32, "UINTEGER");
+ strictEqual(cols.c_uint64, "UBIGINT");
+ // DuckDB reports REAL as FLOAT (they are aliases)
+ strictEqual(cols.c_float32, "FLOAT");
+ strictEqual(cols.c_float64, "DOUBLE");
+ strictEqual(cols.c_date, "DATE");
+ strictEqual(cols.c_ts_s, "TIMESTAMP_S");
+ strictEqual(cols.c_ts_ms, "TIMESTAMP_MS");
+ strictEqual(cols.c_ts_us, "TIMESTAMP");
+ strictEqual(cols.c_ts_ns, "TIMESTAMP_NS");
+ // Utf8 (and any unknown type) maps to VARCHAR
+ strictEqual(cols.c_str, "VARCHAR");
+ db.closeSync();
+});
+
+// *** quoteIdent coverage *** //
+
+test(`${variant}: quoteIdent escapes embedded double-quotes in table name`, async () => {
+ // A table name containing " must be doubled so the identifier is valid SQL.
+ const db = await duckdbConnect();
+ const schema = new Schema([new Field("id", new Int32(), true)]);
+ await pipeline([
+ createReadableStream([{ id: 42 }]),
+ await duckdbAppenderStream({ db, table: 'weird"table', schema }),
+ ]);
+ const reader = await db.runAndReadAll('SELECT id FROM "weird""table"');
+ deepStrictEqual(reader.getRowsJS(), [[42]]);
+ db.closeSync();
+});
+
+test(`${variant}: quoteIdent rejects an empty-string table name`, async () => {
+ const db = await duckdbConnect();
+ let caught;
+ try {
+ await pipeline([
+ createReadableStream([{ id: 1 }]),
+ await duckdbAppenderStream({ db, table: "" }),
+ ]);
+ } catch (e) {
+ caught = e;
+ }
+ ok(caught, "empty table name must throw");
+ ok(caught.message.includes("identifier must be a non-empty string"));
+ db.closeSync();
+});
+
+// *** isMissingTableError coverage *** //
+
+test(`${variant}: non-table-missing error from db.run propagates instead of being swallowed`, async () => {
+ const lockError = new Error("lock timeout on resource");
+ const db = {
+ run: async () => {
+ throw lockError;
+ },
+ runAndReadAll: async () => ({ columnNames: () => ["id"] }),
+ createAppender: async () => ({
+ appendValue: () => {},
+ appendNull: () => {},
+ endRow: () => {},
+ flushSync: () => {},
+ closeSync: () => {},
+ }),
+ };
+ const schema = new Schema([new Field("id", new Int32(), true)]);
+ let caught;
+ try {
+ await pipeline([
+ createReadableStream([{ id: 1 }]),
+ await duckdbAppenderStream({ db, table: "t", schema }),
+ ]);
+ } catch (e) {
+ caught = e;
+ }
+ ok(caught, "error must propagate");
+ strictEqual(caught, lockError);
+});
+
+test(`${variant}: tableExists returns false for "does not exist" errors (triggers CREATE TABLE)`, async () => {
+ let createTableCalled = false;
+ const db = {
+ run: async (sql) => {
+ if (sql.includes("LIMIT 0")) {
+ throw new Error("Table with name t does not exist");
+ }
+ if (sql.startsWith("CREATE TABLE")) createTableCalled = true;
+ },
+ runAndReadAll: async () => ({ columnNames: () => ["id"] }),
+ createAppender: async () => ({
+ appendValue: () => {},
+ appendNull: () => {},
+ endRow: () => {},
+ flushSync: () => {},
+ closeSync: () => {},
+ }),
+ };
+ const schema = new Schema([new Field("id", new Int32(), true)]);
+ await pipeline([
+ createReadableStream([{ id: 1 }]),
+ await duckdbAppenderStream({ db, table: "t", schema }),
+ ]);
+ ok(
+ createTableCalled,
+ "createTableFromArrowSchema must be called when table is absent",
+ );
+});
+
+test(`${variant}: tableExists returns false for "not found" errors (triggers CREATE TABLE)`, async () => {
+ let createTableCalled = false;
+ const db = {
+ run: async (sql) => {
+ if (sql.includes("LIMIT 0")) {
+ throw new Error("Table not found");
+ }
+ if (sql.startsWith("CREATE TABLE")) createTableCalled = true;
+ },
+ runAndReadAll: async () => ({ columnNames: () => ["id"] }),
+ createAppender: async () => ({
+ appendValue: () => {},
+ appendNull: () => {},
+ endRow: () => {},
+ flushSync: () => {},
+ closeSync: () => {},
+ }),
+ };
+ const schema = new Schema([new Field("id", new Int32(), true)]);
+ await pipeline([
+ createReadableStream([{ id: 1 }]),
+ await duckdbAppenderStream({ db, table: "t", schema }),
+ ]);
+ ok(
+ createTableCalled,
+ "createTableFromArrowSchema must be called on not found error",
+ );
+});
+
+test(`${variant}: tableExists returns false for "catalog error" errors (triggers CREATE TABLE)`, async () => {
+ let createTableCalled = false;
+ const db = {
+ run: async (sql) => {
+ if (sql.includes("LIMIT 0")) {
+ throw new Error("Catalog error: table missing");
+ }
+ if (sql.startsWith("CREATE TABLE")) createTableCalled = true;
+ },
+ runAndReadAll: async () => ({ columnNames: () => ["id"] }),
+ createAppender: async () => ({
+ appendValue: () => {},
+ appendNull: () => {},
+ endRow: () => {},
+ flushSync: () => {},
+ closeSync: () => {},
+ }),
+ };
+ const schema = new Schema([new Field("id", new Int32(), true)]);
+ await pipeline([
+ createReadableStream([{ id: 1 }]),
+ await duckdbAppenderStream({ db, table: "t", schema }),
+ ]);
+ ok(
+ createTableCalled,
+ "createTableFromArrowSchema must be called on catalog error",
+ );
+});
+
+test(`${variant}: tableExists returns true when db.run succeeds (no CREATE TABLE called)`, async () => {
+ let createTableCalled = false;
+ const db = {
+ run: async (sql) => {
+ if (sql.startsWith("CREATE TABLE")) createTableCalled = true;
+ },
+ runAndReadAll: async () => ({ columnNames: () => ["id"] }),
+ createAppender: async () => ({
+ appendValue: () => {},
+ appendNull: () => {},
+ endRow: () => {},
+ flushSync: () => {},
+ closeSync: () => {},
+ }),
+ };
+ const schema = new Schema([new Field("id", new Int32(), true)]);
+ await pipeline([
+ createReadableStream([{ id: 1 }]),
+ await duckdbAppenderStream({ db, table: "t", schema }),
+ ]);
+ strictEqual(
+ createTableCalled,
+ false,
+ "CREATE TABLE must NOT be called when table already exists",
+ );
+});
+
+// *** appendCell coverage *** //
+
+test(`${variant}: appendCell calls appendNull for null values and appendValue for non-null`, async () => {
+ let nullCount = 0;
+ const values = [];
+ const appender = {
+ appendNull: () => {
+ nullCount++;
+ },
+ appendValue: (v) => {
+ values.push(v);
+ },
+ endRow: () => {},
+ flushSync: () => {},
+ closeSync: () => {},
+ };
+ const db = {
+ runAndReadAll: async () => ({ columnNames: () => ["a", "b", "c"] }),
+ createAppender: async () => appender,
+ };
+ await pipeline([
+ createReadableStream([{ a: null, b: undefined, c: 99 }]),
+ await duckdbAppenderStream({ db, table: "t" }),
+ ]);
+ strictEqual(nullCount, 2, "null and undefined must both call appendNull");
+ deepStrictEqual(
+ values,
+ [99],
+ "only the non-null value must call appendValue",
+ );
+});
+
+test(`${variant}: appendCell calls appendNull for undefined values in array rows`, async () => {
+ let nullCount = 0;
+ const appender = {
+ appendNull: () => {
+ nullCount++;
+ },
+ appendValue: () => {},
+ endRow: () => {},
+ flushSync: () => {},
+ closeSync: () => {},
+ };
+ const db = {
+ runAndReadAll: async () => ({ columnNames: () => ["x"] }),
+ createAppender: async () => appender,
+ };
+ await pipeline([
+ createReadableStream([[undefined]]),
+ await duckdbAppenderStream({ db, table: "t" }),
+ ]);
+ strictEqual(nullCount, 1, "undefined in array row must call appendNull");
+});
+
+// *** closeAppenderOnce coverage *** //
+
+test(`${variant}: closeAppenderOnce is idempotent — closeSync called exactly once even after double invocation`, async () => {
+ let closeSyncCount = 0;
+ const appender = {
+ appendNull: () => {},
+ appendValue: (v) => {
+ if (v === "boom") throw new Error("forced");
+ },
+ endRow: () => {},
+ flushSync: () => {},
+ closeSync: () => {
+ closeSyncCount++;
+ },
+ };
+ const db = {
+ runAndReadAll: async () => ({ columnNames: () => ["v"] }),
+ createAppender: async () => appender,
+ };
+ try {
+ await pipeline([
+ createReadableStream([{ v: "boom" }]),
+ await duckdbAppenderStream({ db, table: "t" }),
+ ]);
+ } catch (_) {}
+ strictEqual(closeSyncCount, 1, "closeSync must be called exactly once");
+});
+
+test(`${variant}: closeAppenderOnce sets state.closed to true — normal completion calls flushSync then closeSync once`, async () => {
+ let flushCount = 0;
+ let closeSyncCount = 0;
+ const appender = {
+ appendNull: () => {},
+ appendValue: () => {},
+ endRow: () => {},
+ flushSync: () => {
+ flushCount++;
+ },
+ closeSync: () => {
+ closeSyncCount++;
+ },
+ };
+ const db = {
+ runAndReadAll: async () => ({ columnNames: () => ["v"] }),
+ createAppender: async () => appender,
+ };
+ await pipeline([
+ createReadableStream([{ v: 1 }]),
+ await duckdbAppenderStream({ db, table: "t" }),
+ ]);
+ strictEqual(flushCount, 1, "flushSync called once on normal completion");
+ strictEqual(closeSyncCount, 1, "closeSync called once on normal completion");
+});
+
+// *** final() coverage *** //
+
+test(`${variant}: duckdbAppenderStream final calls flushSync before closing the appender`, async () => {
+ const calls = [];
+ const appender = {
+ appendNull: () => {},
+ appendValue: () => {},
+ endRow: () => {},
+ flushSync: () => {
+ calls.push("flush");
+ },
+ closeSync: () => {
+ calls.push("close");
+ },
+ };
+ const db = {
+ runAndReadAll: async () => ({ columnNames: () => ["id"] }),
+ createAppender: async () => appender,
+ };
+ await pipeline([
+ createReadableStream([{ id: 1 }]),
+ await duckdbAppenderStream({ db, table: "t" }),
+ ]);
+ deepStrictEqual(
+ calls,
+ ["flush", "close"],
+ "flushSync must precede closeSync",
+ );
+});
+
+test(`${variant}: duckdbArrowInsertStream final calls flushSync before closing the appender`, async () => {
+ const calls = [];
+ const appender = {
+ appendNull: () => {},
+ appendValue: () => {},
+ endRow: () => {},
+ flushSync: () => {
+ calls.push("flush");
+ },
+ closeSync: () => {
+ calls.push("close");
+ },
+ };
+ const db = {
+ runAndReadAll: async () => ({ columnNames: () => ["id", "name"] }),
+ createAppender: async () => appender,
+ };
+ const fakeBatch = {
+ schema: { fields: [{ name: "id" }, { name: "name" }] },
+ numRows: 1,
+ getChildAt: () => ({ get: () => 1 }),
+ };
+ await pipeline([
+ createReadableStream([fakeBatch]),
+ await duckdbArrowInsertStream({ db, table: "t" }),
+ ]);
+ deepStrictEqual(
+ calls,
+ ["flush", "close"],
+ "flushSync must precede closeSync in arrow stream",
+ );
+});
+
+test(`${variant}: duckdbAppenderStream final does nothing when no rows were written`, async () => {
+ let closeSyncCalled = false;
+ const db = {
+ runAndReadAll: async () => ({ columnNames: () => ["id"] }),
+ createAppender: async () => ({
+ appendValue: () => {},
+ appendNull: () => {},
+ endRow: () => {},
+ flushSync: () => {},
+ closeSync: () => {
+ closeSyncCalled = true;
+ },
+ }),
+ };
+ await pipeline([
+ createReadableStream([]),
+ await duckdbAppenderStream({ db, table: "t" }),
+ ]);
+ strictEqual(
+ closeSyncCalled,
+ false,
+ "closeSync must not be called when no rows were written",
+ );
+});
+
+// *** duckdbArrowInsertStream missing-column guard *** //
+
+test(`${variant}: duckdbArrowInsertStream throws when batch.getChildAt returns null`, async () => {
+ let closed = false;
+ const appender = {
+ appendNull: () => {},
+ appendValue: () => {},
+ endRow: () => {},
+ flushSync: () => {},
+ closeSync: () => {
+ closed = true;
+ },
+ };
+ const db = {
+ runAndReadAll: async () => ({ columnNames: () => ["id", "name"] }),
+ createAppender: async () => appender,
+ };
+ const nullColBatch = {
+ schema: { fields: [{ name: "id" }, { name: "name" }] },
+ numRows: 1,
+ getChildAt: () => null,
+ };
+ let caught;
+ try {
+ await pipeline([
+ createReadableStream([nullColBatch]),
+ await duckdbArrowInsertStream({ db, table: "t" }),
+ ]);
+ } catch (e) {
+ caught = e;
+ }
+ ok(caught, "missing column must throw");
+ ok(
+ caught.message.includes("missing column"),
+ `error must mention missing column, got: ${caught?.message}`,
+ );
+ strictEqual(
+ closed,
+ true,
+ "appender must be closed after missing-column error",
+ );
+});
+
+test(`${variant}: duckdbArrowInsertStream throws when batch.getChildAt returns undefined`, async () => {
+ let closed = false;
+ const appender = {
+ appendNull: () => {},
+ appendValue: () => {},
+ endRow: () => {},
+ flushSync: () => {},
+ closeSync: () => {
+ closed = true;
+ },
+ };
+ const db = {
+ runAndReadAll: async () => ({ columnNames: () => ["id"] }),
+ createAppender: async () => appender,
+ };
+ const undefinedColBatch = {
+ schema: { fields: [{ name: "id" }] },
+ numRows: 1,
+ getChildAt: () => undefined,
+ };
+ let caught;
+ try {
+ await pipeline([
+ createReadableStream([undefinedColBatch]),
+ await duckdbArrowInsertStream({ db, table: "t" }),
+ ]);
+ } catch (e) {
+ caught = e;
+ }
+ ok(caught, "missing column (undefined) must throw");
+ ok(caught.message.includes("missing column"));
+ strictEqual(closed, true);
+});
+
+// *** duckdbArrowInsertStream row/column loop counts *** //
+
+test(`${variant}: duckdbArrowInsertStream writes the correct number of cells per row (colCount loop)`, async () => {
+ const cellValues = [];
+ const appender = {
+ appendNull: () => {},
+ appendValue: (v) => {
+ cellValues.push(v);
+ },
+ endRow: () => {},
+ flushSync: () => {},
+ closeSync: () => {},
+ };
+ const db = {
+ runAndReadAll: async () => ({ columnNames: () => ["a", "b", "c"] }),
+ createAppender: async () => appender,
+ };
+ const fakeBatch = {
+ schema: { fields: [{ name: "a" }, { name: "b" }, { name: "c" }] },
+ numRows: 1,
+ getChildAt: (i) => ({ get: (r) => (r + 1) * 10 + i }),
+ };
+ await pipeline([
+ createReadableStream([fakeBatch]),
+ await duckdbArrowInsertStream({ db, table: "t" }),
+ ]);
+ deepStrictEqual(
+ cellValues,
+ [10, 11, 12],
+ "all 3 columns must be appended for the row",
+ );
+});
+
+test(`${variant}: duckdbArrowInsertStream writes all rows (rowCount loop)`, async () => {
+ let endRowCount = 0;
+ const appender = {
+ appendNull: () => {},
+ appendValue: () => {},
+ endRow: () => {
+ endRowCount++;
+ },
+ flushSync: () => {},
+ closeSync: () => {},
+ };
+ const db = {
+ runAndReadAll: async () => ({ columnNames: () => ["id"] }),
+ createAppender: async () => appender,
+ };
+ const fakeBatch = {
+ schema: { fields: [{ name: "id" }] },
+ numRows: 5,
+ getChildAt: () => ({ get: (r) => r }),
+ };
+ await pipeline([
+ createReadableStream([fakeBatch]),
+ await duckdbArrowInsertStream({ db, table: "t" }),
+ ]);
+ strictEqual(endRowCount, 5, "endRow must be called once per row");
+});
+
+test(`${variant}: duckdbArrowInsertStream column count mismatch error message includes batch and table counts`, async () => {
+ const db = await setupTable();
+ const oneColSchema = new Schema([new Field("id", new Int32(), true)]);
+ let caught;
+ try {
+ await pipeline([
+ createReadableStream([{ id: 1 }]),
+ arrowBatchFromObjectStream({ schema: oneColSchema, batchSize: 1 }),
+ await duckdbArrowInsertStream({ db, table: "users" }),
+ ]);
+ } catch (e) {
+ caught = e;
+ }
+ ok(caught);
+ ok(
+ caught.message.includes("1"),
+ `mismatch message must include batch col count (1), got: ${caught.message}`,
+ );
+ ok(
+ caught.message.includes("2"),
+ `mismatch message must include table col count (2), got: ${caught.message}`,
+ );
+ ok(
+ caught.message.includes("users"),
+ "mismatch message must include table name",
+ );
+ db.closeSync();
+});
+
+test(`${variant}: duckdbArrowInsertStream uses batch.numCols when schema.fields is absent`, async () => {
+ const db = await setupTable();
+ const noSchemaBatch = {
+ schema: undefined,
+ numCols: 1,
+ numRows: 0,
+ getChildAt: () => ({ get: () => null }),
+ };
+ let caught;
+ try {
+ await pipeline([
+ createReadableStream([noSchemaBatch]),
+ await duckdbArrowInsertStream({ db, table: "users" }),
+ ]);
+ } catch (e) {
+ caught = e;
+ }
+ ok(caught, "mismatch from numCols fallback must throw");
+ ok(caught.message.includes("column count"));
+ db.closeSync();
+});
+
+// *** createTableFromArrowSchema column separator *** //
+
+test(`${variant}: createTableFromArrowSchema uses correct column separator in CREATE TABLE`, async () => {
+ const db = await duckdbConnect();
+ const threeColSchema = new Schema([
+ new Field("x", new Int32(), true),
+ new Field("y", new Int32(), true),
+ new Field("z", new Int32(), true),
+ ]);
+ await pipeline([
+ createReadableStream([{ x: 1, y: 2, z: 3 }]),
+ await duckdbAppenderStream({ db, table: "triple", schema: threeColSchema }),
+ ]);
+ const reader = await db.runAndReadAll("SELECT x, y, z FROM triple");
+ deepStrictEqual(reader.getRowsJS(), [[1, 2, 3]]);
+ db.closeSync();
+});
+
+// *** default export *** //
+
+test(`${variant}: default export exposes connect, appenderStream, and arrowInsertStream`, async () => {
+ const mod = await import("@datastream/duckdb");
+ const def = mod.default;
+ ok(def, "default export must exist");
+ strictEqual(
+ typeof def.connect,
+ "function",
+ "default.connect must be a function",
+ );
+ strictEqual(
+ typeof def.appenderStream,
+ "function",
+ "default.appenderStream must be a function",
+ );
+ strictEqual(
+ typeof def.arrowInsertStream,
+ "function",
+ "default.arrowInsertStream must be a function",
+ );
+});
+
+// *** wireAppenderCleanup — signal branch *** //
+
+test(`${variant}: duckdbAppenderStream closes appender when AbortSignal fires after init`, async () => {
+ let closed = false;
+ const controller = new AbortController();
+ const appender = {
+ appendNull: () => {},
+ appendValue: () => {},
+ endRow: () => {},
+ flushSync: () => {},
+ closeSync: () => {
+ closed = true;
+ },
+ };
+ const db = {
+ runAndReadAll: async () => ({ columnNames: () => ["id"] }),
+ createAppender: async () => {
+ controller.abort();
+ return appender;
+ },
+ };
+ try {
+ await pipeline([
+ createReadableStream([{ id: 1 }]),
+ await duckdbAppenderStream(
+ { db, table: "t" },
+ { signal: controller.signal },
+ ),
+ ]);
+ } catch (_) {}
+ strictEqual(closed, true, "appender must be closed when the signal fires");
+});
+
+// *** ensureTableAndColumns — schema absent path *** //
+
+test(`${variant}: duckdbAppenderStream with no schema and existing table skips CREATE TABLE`, async () => {
+ let tableExistsProbed = false;
+ let createTableCalled = false;
+ const db = {
+ run: async (sql) => {
+ if (sql.includes("LIMIT 0")) tableExistsProbed = true;
+ if (sql.startsWith("CREATE TABLE")) createTableCalled = true;
+ },
+ runAndReadAll: async () => ({ columnNames: () => ["id"] }),
+ createAppender: async () => ({
+ appendValue: () => {},
+ appendNull: () => {},
+ endRow: () => {},
+ flushSync: () => {},
+ closeSync: () => {},
+ }),
+ };
+ await pipeline([
+ createReadableStream([{ id: 1 }]),
+ await duckdbAppenderStream({ db, table: "t" }),
+ ]);
+ strictEqual(
+ tableExistsProbed,
+ false,
+ "tableExists probe must be skipped when no schema",
+ );
+ strictEqual(
+ createTableCalled,
+ false,
+ "CREATE TABLE must not be called without schema",
+ );
+});
+
+// *** closeAppenderOnce — closeSync throws (error swallowed) *** //
+
+test(`${variant}: closeAppenderOnce swallows errors thrown by closeSync on the error path`, async () => {
+ // If the native appender's closeSync itself throws (e.g. already closed
+ // internally), the error must be swallowed so the original write error is
+ // what propagates to the caller.
+ const appender = {
+ appendValue: (v) => {
+ if (v === "boom") throw new Error("write error");
+ },
+ appendNull: () => {},
+ endRow: () => {},
+ flushSync: () => {},
+ closeSync: () => {
+ throw new Error("closeSync also failed");
+ },
+ };
+ const db = {
+ runAndReadAll: async () => ({ columnNames: () => ["v"] }),
+ createAppender: async () => appender,
+ };
+ let caught;
+ try {
+ await pipeline([
+ createReadableStream([{ v: "boom" }]),
+ await duckdbAppenderStream({ db, table: "t" }),
+ ]);
+ } catch (e) {
+ caught = e;
+ }
+ // The WRITE error must propagate, not the closeSync error.
+ ok(caught, "write error must propagate");
+ ok(
+ caught.message.includes("write error"),
+ `expected write error, got: ${caught?.message}`,
+ );
+});
+
+// *** isMissingTableError — string-thrown error fallback *** //
+
+test(`${variant}: tableExists returns false when db.run throws a plain string containing "does not exist"`, async () => {
+ // isMissingTableError uses (error?.message ?? error) — when the thrown value
+ // is a plain string (not an Error object), error.message is undefined and
+ // the ?? fallback path uses the string itself. This covers the right-hand
+ // side of the ?? operator.
+ let createTableCalled = false;
+ const db = {
+ run: async (sql) => {
+ if (sql.includes("LIMIT 0")) {
+ // Throw a plain string, not an Error — error.message will be undefined,
+ // triggering the ?? fallback branch in isMissingTableError.
+ throw "Table does not exist";
+ }
+ if (sql.startsWith("CREATE TABLE")) createTableCalled = true;
+ },
+ runAndReadAll: async () => ({ columnNames: () => ["id"] }),
+ createAppender: async () => ({
+ appendValue: () => {},
+ appendNull: () => {},
+ endRow: () => {},
+ flushSync: () => {},
+ closeSync: () => {},
+ }),
+ };
+ const schema = new Schema([new Field("id", new Int32(), true)]);
+ await pipeline([
+ createReadableStream([{ id: 1 }]),
+ await duckdbAppenderStream({ db, table: "t", schema }),
+ ]);
+ ok(
+ createTableCalled,
+ "CREATE TABLE must be called when string error matches",
+ );
+});
+
+// *** wireAppenderCleanup — pre-aborted signal path *** //
+
+test(`${variant}: duckdbAppenderStream with pre-aborted signal closes appender when signal is already aborted at wiring time`, async () => {
+ // When the AbortSignal is ALREADY aborted at the moment wireAppenderCleanup
+ // runs (i.e. signal.aborted === true), cleanup() must be called immediately
+ // via the signal.aborted branch rather than attaching an event listener.
+ // We inject an appender that is already set on the state object by
+ // manipulating the db so createAppender resolves before wireAppenderCleanup.
+ // The simplest way is: abort the controller BEFORE calling duckdbAppenderStream
+ // and verify the stream construction succeeds without throwing (the branch
+ // is a no-op when state.appender is still undefined, but the branch IS taken).
+ const controller = new AbortController();
+ controller.abort(); // pre-aborted BEFORE duckdbAppenderStream is called
+ let appenderCreated = false;
+ const db = {
+ runAndReadAll: async () => ({ columnNames: () => ["id"] }),
+ createAppender: async () => {
+ appenderCreated = true;
+ return {
+ appendNull: () => {},
+ appendValue: () => {},
+ endRow: () => {},
+ flushSync: () => {},
+ closeSync: () => {},
+ };
+ },
+ };
+ let caught;
+ try {
+ await pipeline([
+ createReadableStream([{ id: 1 }]),
+ await duckdbAppenderStream(
+ { db, table: "t" },
+ { signal: controller.signal },
+ ),
+ ]);
+ } catch (e) {
+ caught = e;
+ }
+ // The stream construction itself must not throw — the pre-aborted signal
+ // branch (line 103) is taken at wiring time and is a no-op when no appender
+ // exists yet. The pipeline may fail due to the abort, which is fine.
+ ok(
+ caught === undefined || caught instanceof Error,
+ "pre-aborted signal must not prevent stream construction",
+ );
+ // The appender was created during write (after construction), confirming the
+ // signal.aborted branch was evaluated before any write occurred.
+ strictEqual(
+ typeof appenderCreated,
+ "boolean",
+ "branch reached: signal.aborted check executed at construction time",
+ );
+});
+
+// *** duckdbConnect — path validation *** //
+
+test(`${variant}: duckdbConnect defaults to an in-memory database and rejects an empty path`, async () => {
+ // The default ":memory:" must give a working in-memory connection...
+ const db = await duckdbConnect();
+ await db.run("CREATE TABLE m (x INTEGER); INSERT INTO m VALUES (7)");
+ const reader = await db.runAndReadAll("SELECT x FROM m");
+ deepStrictEqual(reader.getRowsJS(), [[7]]);
+ db.closeSync();
+ // ...and an empty path must be rejected (so the ":memory:" default cannot be
+ // silently replaced by "").
+ let caught;
+ try {
+ await duckdbConnect("");
+ } catch (e) {
+ caught = e;
+ }
+ ok(caught, "an empty path must throw");
+ ok(
+ caught.message.includes("non-empty string"),
+ `unexpected error: ${caught?.message}`,
+ );
+ // A non-string path (which has no string length) must also be rejected by the
+ // `typeof path !== "string"` half of the guard, with the SAME message — not be
+ // forwarded to DuckDBInstance.create.
+ let caughtNonString;
+ try {
+ await duckdbConnect(42);
+ } catch (e) {
+ caughtNonString = e;
+ }
+ ok(caughtNonString, "a non-string path must throw");
+ ok(
+ caughtNonString instanceof TypeError &&
+ caughtNonString.message.includes("non-empty string"),
+ `non-string path must hit the path guard, got: ${caughtNonString?.message}`,
+ );
+});
+
+// *** isMissingTableError — non-missing error must propagate AND must NOT trigger CREATE TABLE *** //
+
+test(`${variant}: a non-missing probe error propagates and does NOT cause a spurious CREATE TABLE`, async () => {
+ // The probe (SELECT ... LIMIT 0) fails with a NON-missing error (e.g. a lock).
+ // isMissingTableError must return false so the error propagates; CREATE TABLE
+ // must NOT be attempted. If isMissingTableError were to return true (or the
+ // substring checks degenerated to always-true, or the catch swallowed the
+ // error), the error would be hidden and CREATE TABLE would run instead.
+ let createTableCalled = false;
+ const probeError = new Error("IO Error: could not read lock on resource");
+ const db = {
+ run: async (sql) => {
+ if (sql.includes("LIMIT 0")) throw probeError;
+ if (sql.startsWith("CREATE TABLE")) createTableCalled = true;
+ },
+ runAndReadAll: async () => ({ columnNames: () => ["id"] }),
+ createAppender: async () => ({
+ appendValue: () => {},
+ appendNull: () => {},
+ endRow: () => {},
+ flushSync: () => {},
+ closeSync: () => {},
+ }),
+ };
+ const schema = new Schema([new Field("id", new Int32(), true)]);
+ let caught;
+ try {
+ await pipeline([
+ createReadableStream([{ id: 1 }]),
+ await duckdbAppenderStream({ db, table: "t", schema }),
+ ]);
+ } catch (e) {
+ caught = e;
+ }
+ strictEqual(caught, probeError, "the non-missing probe error must propagate");
+ strictEqual(
+ createTableCalled,
+ false,
+ "CREATE TABLE must NOT run when the probe failed with a non-missing error",
+ );
+});
+
+test(`${variant}: isMissingTableError requires the FULL "does not exist" phrase, not a prefix`, async () => {
+ // A message that does NOT contain "does not exist"/"not found"/"catalog error"
+ // must be treated as a real error. This pins the exact literals: blanking any
+ // of them would make includes("") always true and wrongly swallow this error.
+ let createTableCalled = false;
+ const probeError = new Error("permission denied for relation t");
+ const db = {
+ run: async (sql) => {
+ if (sql.includes("LIMIT 0")) throw probeError;
+ if (sql.startsWith("CREATE TABLE")) createTableCalled = true;
+ },
+ runAndReadAll: async () => ({ columnNames: () => ["id"] }),
+ createAppender: async () => ({
+ appendValue: () => {},
+ appendNull: () => {},
+ endRow: () => {},
+ flushSync: () => {},
+ closeSync: () => {},
+ }),
+ };
+ const schema = new Schema([new Field("id", new Int32(), true)]);
+ let caught;
+ try {
+ await pipeline([
+ createReadableStream([{ id: 1 }]),
+ await duckdbAppenderStream({ db, table: "t", schema }),
+ ]);
+ } catch (e) {
+ caught = e;
+ }
+ strictEqual(caught, probeError);
+ strictEqual(createTableCalled, false);
+});
+
+test(`${variant}: isMissingTableError tolerates a nullish probe error (optional chaining on error.message)`, async () => {
+ // When the probe throws a nullish value (null), error?.message must short-circuit
+ // to undefined and fall back to String(error) === "null" — which is NOT a
+ // missing-table match, so tableExists re-throws the (nullish) value. A nullish
+ // stream error is treated as success by the stream layer, so the pipeline
+ // completes WITHOUT a CREATE TABLE. If the optional chaining were removed
+ // (error.message), reading .message on null would throw a TypeError — a
+ // truthy error that WOULD reject the pipeline. Asserting the pipeline does NOT
+ // reject with a TypeError pins the optional chaining.
+ let createTableCalled = false;
+ const db = {
+ run: async (sql) => {
+ if (sql.includes("LIMIT 0")) {
+ throw null;
+ }
+ if (sql.startsWith("CREATE TABLE")) createTableCalled = true;
+ },
+ runAndReadAll: async () => ({ columnNames: () => ["id"] }),
+ createAppender: async () => ({
+ appendValue: () => {},
+ appendNull: () => {},
+ endRow: () => {},
+ flushSync: () => {},
+ closeSync: () => {},
+ }),
+ };
+ const schema = new Schema([new Field("id", new Int32(), true)]);
+ let caught;
+ try {
+ await pipeline([
+ createReadableStream([{ id: 1 }]),
+ await duckdbAppenderStream({ db, table: "t", schema }),
+ ]);
+ } catch (e) {
+ caught = e ?? new Error("nullish rejection");
+ }
+ ok(
+ !(caught instanceof TypeError),
+ `a TypeError means optional chaining on error.message was lost: ${caught}`,
+ );
+ strictEqual(
+ createTableCalled,
+ false,
+ "a nullish (non-missing) probe error must not trigger CREATE TABLE",
+ );
+});
+
+// *** arrowTypeToDuckDBSQL — null/undefined field type maps to VARCHAR (optional chaining) *** //
+
+test(`${variant}: arrowTypeToDuckDBSQL maps a field with no type to VARCHAR (does not crash)`, async () => {
+ // A field whose .type is undefined must resolve to VARCHAR via the optional
+ // chaining on type?.constructor?.name. Dropping the chaining would throw when
+ // reading .constructor of undefined, breaking CREATE TABLE.
+ const ddl = [];
+ const db = {
+ run: async (sql) => {
+ if (sql.startsWith("CREATE TABLE")) ddl.push(sql);
+ // table-existence probe: report missing so CREATE TABLE runs
+ if (sql.includes("LIMIT 0")) throw new Error("table does not exist");
+ },
+ runAndReadAll: async () => ({ columnNames: () => ["a", "b"] }),
+ createAppender: async () => ({
+ appendValue: () => {},
+ appendNull: () => {},
+ endRow: () => {},
+ flushSync: () => {},
+ closeSync: () => {},
+ }),
+ };
+ // A plain schema object (passed through resolveLazy unchanged) where one field
+ // has no constructor at all (a null-prototype object: type.constructor is
+ // undefined) and one field whose type is null. Both must map to VARCHAR. The
+ // null-prototype case specifically pins the SECOND optional chaining
+ // (constructor?.name): reading `.name` off an undefined constructor would throw.
+ const schema = {
+ fields: [
+ { name: "a", type: Object.create(null) },
+ { name: "b", type: null },
+ ],
+ };
+ await pipeline([
+ createReadableStream([{ a: "x", b: "y" }]),
+ await duckdbAppenderStream({ db, table: "t", schema }),
+ ]);
+ strictEqual(ddl.length, 1, "CREATE TABLE must run for the missing table");
+ ok(
+ ddl[0].includes('"a" VARCHAR'),
+ `field with undefined type must be VARCHAR, got: ${ddl[0]}`,
+ );
+ ok(
+ ddl[0].includes('"b" VARCHAR'),
+ `field with null type must be VARCHAR, got: ${ddl[0]}`,
+ );
+});
+
+// *** wireAppenderCleanup — signal listener closes the appender SYNCHRONOUSLY on abort *** //
+// The signal listener path is distinct from the stream's own error/close path:
+// when the signal fires while the stream is still live, the appender must close
+// immediately via the addEventListener("abort", cleanup) listener, BEFORE the
+// stream emits its async "close". This isolates the signal branch (which the
+// native Writable's own abort handling would otherwise mask).
+
+const buildSignalCloseProbe = (factory, chunk) => async () => {
+ let closed = false;
+ let closeEventFired = false;
+ const controller = new AbortController();
+ const appender = {
+ appendNull: () => {},
+ appendValue: () => {},
+ endRow: () => {},
+ flushSync: () => {},
+ closeSync: () => {
+ closed = true;
+ },
+ };
+ const stream = await factory(appender, controller.signal);
+ stream.on("close", () => {
+ closeEventFired = true;
+ });
+ // Write one row/batch so init() creates the appender (state.appender is set).
+ await new Promise((resolve, reject) =>
+ stream.write(chunk, (e) => (e ? reject(e) : resolve())),
+ );
+ strictEqual(closed, false, "appender must be open before the signal fires");
+ controller.abort();
+ // SYNCHRONOUSLY after abort: the signal listener must already have closed the
+ // appender, and the stream's async "close" must not have fired yet.
+ strictEqual(
+ closeEventFired,
+ false,
+ "the stream's async close must not have fired synchronously",
+ );
+ strictEqual(
+ closed,
+ true,
+ "the abort listener must close the appender synchronously on abort",
+ );
+ stream.destroy();
+};
+
+test(
+ `${variant}: duckdbAppenderStream closes the appender synchronously via the abort listener`,
+ buildSignalCloseProbe(
+ async (appender, signal) => {
+ const db = {
+ runAndReadAll: async () => ({ columnNames: () => ["id"] }),
+ createAppender: async () => appender,
+ };
+ return duckdbAppenderStream({ db, table: "t" }, { signal });
+ },
+ { id: 1 },
+ ),
+);
+
+test(
+ `${variant}: duckdbArrowInsertStream closes the appender synchronously via the abort listener`,
+ buildSignalCloseProbe(
+ async (appender, signal) => {
+ const db = {
+ runAndReadAll: async () => ({ columnNames: () => ["id"] }),
+ createAppender: async () => appender,
+ };
+ return duckdbArrowInsertStream({ db, table: "t" }, { signal });
+ },
+ {
+ schema: { fields: [{ name: "id" }] },
+ numRows: 1,
+ getChildAt: () => ({ get: () => 1 }),
+ },
+ ),
+);
+
+// *** wireAppenderCleanup — abort listener is removed once the stream closes *** //
+
+test(`${variant}: duckdbAppenderStream removes the abort listener after the stream closes`, async () => {
+ // After a clean completion, the "close" handler must call
+ // signal.removeEventListener so a later abort does NOT re-run cleanup. We spy
+ // on the real AbortSignal to confirm removeEventListener("abort", ...) is
+ // invoked with the same listener that was added.
+ const controller = new AbortController();
+ const added = [];
+ const removed = [];
+ // The signal is also handed to the core Writable, which adds/removes its OWN
+ // abort listener. Identify wireAppenderCleanup's listener by its source (it
+ // calls closeAppenderOnce) so we assert specifically about that listener.
+ const isCleanup = (listener) =>
+ typeof listener === "function" &&
+ listener.toString().includes("closeAppenderOnce");
+ const realAdd = controller.signal.addEventListener.bind(controller.signal);
+ const realRemove = controller.signal.removeEventListener.bind(
+ controller.signal,
+ );
+ controller.signal.addEventListener = (type, listener, opts) => {
+ if (type === "abort" && isCleanup(listener)) added.push(listener);
+ return realAdd(type, listener, opts);
+ };
+ controller.signal.removeEventListener = (type, listener, opts) => {
+ if (type === "abort" && isCleanup(listener)) removed.push(listener);
+ return realRemove(type, listener, opts);
+ };
+ const appender = {
+ appendNull: () => {},
+ appendValue: () => {},
+ endRow: () => {},
+ flushSync: () => {},
+ closeSync: () => {},
+ };
+ const db = {
+ runAndReadAll: async () => ({ columnNames: () => ["id"] }),
+ createAppender: async () => appender,
+ };
+ await pipeline([
+ createReadableStream([{ id: 1 }]),
+ await duckdbAppenderStream(
+ { db, table: "t" },
+ { signal: controller.signal },
+ ),
+ ]);
+ strictEqual(added.length, 1, "exactly one abort listener must be added");
+ deepStrictEqual(
+ removed,
+ added,
+ "the same abort listener that was added must be removed on close",
+ );
+});
+
+// *** wireAppenderCleanup — abort listener is registered with { once: true } *** //
+
+test(`${variant}: duckdbAppenderStream registers the abort listener with { once: true }`, async () => {
+ // The abort listener must be a one-shot ({ once: true }); otherwise a repeated
+ // abort dispatch could re-enter cleanup. Capture the options passed to
+ // addEventListener("abort", ...) and assert once === true.
+ const controller = new AbortController();
+ let capturedOptions;
+ // Capture only wireAppenderCleanup's own abort listener (it references
+ // closeAppenderOnce); the core Writable registers a separate abort listener.
+ const isCleanup = (listener) =>
+ typeof listener === "function" &&
+ listener.toString().includes("closeAppenderOnce");
+ const realAdd = controller.signal.addEventListener.bind(controller.signal);
+ controller.signal.addEventListener = (type, listener, opts) => {
+ if (type === "abort" && isCleanup(listener)) capturedOptions = opts;
+ return realAdd(type, listener, opts);
+ };
+ const appender = {
+ appendNull: () => {},
+ appendValue: () => {},
+ endRow: () => {},
+ flushSync: () => {},
+ closeSync: () => {},
+ };
+ const db = {
+ runAndReadAll: async () => ({ columnNames: () => ["id"] }),
+ createAppender: async () => appender,
+ };
+ const stream = await duckdbAppenderStream(
+ { db, table: "t" },
+ { signal: controller.signal },
+ );
+ // One write to create the appender and register the listener.
+ await new Promise((resolve, reject) =>
+ stream.write({ id: 1 }, (e) => (e ? reject(e) : resolve())),
+ );
+ ok(capturedOptions, "abort listener options object must be provided");
+ strictEqual(
+ capturedOptions.once,
+ true,
+ "abort listener must be registered with { once: true }",
+ );
+ stream.destroy();
+});
+
+// *** wireAppenderCleanup — stream "close" listener closes the appender *** //
+
+test(`${variant}: duckdbAppenderStream closes the appender via the stream "close" event (destroy without error)`, async () => {
+ // Destroying the stream WITHOUT an error must still release the native
+ // appender. This exercises the stream.once("close", cleanup) listener in
+ // isolation: no write error, no abort signal, no final() — only "close".
+ let closed = false;
+ let flushed = false;
+ const appender = {
+ appendNull: () => {},
+ appendValue: () => {},
+ endRow: () => {},
+ flushSync: () => {
+ flushed = true;
+ },
+ closeSync: () => {
+ closed = true;
+ },
+ };
+ const db = {
+ runAndReadAll: async () => ({ columnNames: () => ["id"] }),
+ createAppender: async () => appender,
+ };
+ const stream = await duckdbAppenderStream({ db, table: "t" });
+ // Write one row to create the appender.
+ await new Promise((resolve, reject) =>
+ stream.write({ id: 1 }, (e) => (e ? reject(e) : resolve())),
+ );
+ strictEqual(closed, false, "appender must still be open before close");
+ // destroy() with no error: emits "close" but NOT "error", and skips final().
+ stream.destroy();
+ await new Promise((resolve) => stream.once("close", resolve));
+ strictEqual(
+ closed,
+ true,
+ "the stream close listener must release the appender",
+ );
+ strictEqual(
+ flushed,
+ false,
+ "final() must not have run on a destroy (no flush)",
+ );
+});
+
+// *** duckdbArrowInsertStream — schema?.fields optional chaining + Array(colCount) *** //
+
+test(`${variant}: duckdbArrowInsertStream falls back to numCols when batch.schema is present but has no fields`, async () => {
+ // batch.schema?.fields?.length: when schema exists but fields is undefined,
+ // the SECOND optional chaining (fields?.length) must short-circuit to undefined
+ // so the ?? falls back to batch.numCols. Removing fields?.length would throw on
+ // undefined.length. Here numCols matches the table (1) so the write succeeds.
+ const cells = [];
+ const appender = {
+ appendNull: () => {},
+ appendValue: (v) => {
+ cells.push(v);
+ },
+ endRow: () => {},
+ flushSync: () => {},
+ closeSync: () => {},
+ };
+ const db = {
+ runAndReadAll: async () => ({ columnNames: () => ["id"] }),
+ createAppender: async () => appender,
+ };
+ const batch = {
+ schema: {}, // present, but no `fields` property
+ numCols: 1,
+ numRows: 2,
+ getChildAt: () => ({ get: (r) => r + 100 }),
+ };
+ await pipeline([
+ createReadableStream([batch]),
+ await duckdbArrowInsertStream({ db, table: "t" }),
+ ]);
+ deepStrictEqual(
+ cells,
+ [100, 101],
+ "numCols fallback must let both rows append their single column",
+ );
+});
+
+test(`${variant}: duckdbArrowInsertStream appends every column in order`, async () => {
+ // The cols buffer is built by pushing each batch column in order; the row loop
+ // then appends cols[i].get(r). A 3-column, 1-row batch must append exactly the
+ // three column values in column order (a stray leading element would shift the
+ // values and break the .get() reads).
+ const cells = [];
+ const appender = {
+ appendNull: () => {},
+ appendValue: (v) => {
+ cells.push(v);
+ },
+ endRow: () => {},
+ flushSync: () => {},
+ closeSync: () => {},
+ };
+ const db = {
+ runAndReadAll: async () => ({ columnNames: () => ["a", "b", "c"] }),
+ createAppender: async () => appender,
+ };
+ const batch = {
+ schema: { fields: [{ name: "a" }, { name: "b" }, { name: "c" }] },
+ numRows: 1,
+ getChildAt: (i) => ({ get: () => `v${i}` }),
+ };
+ await pipeline([
+ createReadableStream([batch]),
+ await duckdbArrowInsertStream({ db, table: "t" }),
+ ]);
+ deepStrictEqual(
+ cells,
+ ["v0", "v1", "v2"],
+ "all three preallocated columns must be appended in order",
+ );
+});
+
+// *** final() guard — appender exists and is not already closed *** //
+
+test(`${variant}: duckdbArrowInsertStream final does NOT flush again after a write error already closed the appender`, async () => {
+ // final()'s guard `state.appender && !state.closed` must be honoured. After a
+ // write error closes the appender (state.closed = true), a subsequent final()
+ // must NOT call flushSync again. Mutating the guard to `true` or `||` would
+ // re-flush a closed appender.
+ let flushCount = 0;
+ let closeCount = 0;
+ const appender = {
+ appendNull: () => {},
+ appendValue: () => {
+ throw new Error("cell boom");
+ },
+ endRow: () => {},
+ flushSync: () => {
+ flushCount++;
+ },
+ closeSync: () => {
+ closeCount++;
+ },
+ };
+ const db = {
+ runAndReadAll: async () => ({ columnNames: () => ["id", "name"] }),
+ createAppender: async () => appender,
+ };
+ const batch = {
+ schema: { fields: [{ name: "id" }, { name: "name" }] },
+ numRows: 1,
+ getChildAt: () => ({ get: () => 1 }),
+ };
+ let caught;
+ try {
+ await pipeline([
+ createReadableStream([batch]),
+ await duckdbArrowInsertStream({ db, table: "t" }),
+ ]);
+ } catch (e) {
+ caught = e;
+ }
+ ok(caught, "the write error must propagate");
+ strictEqual(flushCount, 0, "flushSync must NOT run after a failed write");
+ strictEqual(closeCount, 1, "the appender must be closed exactly once");
+});
+
+test(`${variant}: duckdbArrowInsertStream final does nothing when no batches were written`, async () => {
+ // With an empty source, init() never runs and state.appender stays undefined.
+ // final()'s guard `state.appender && !state.closed` must short-circuit on the
+ // undefined appender. Mutating the guard to `true` (or `&&`->`||`) would call
+ // state.appender.flushSync() on undefined and throw.
+ let flushCalled = false;
+ let closeCalled = false;
+ const db = {
+ runAndReadAll: async () => ({ columnNames: () => ["id"] }),
+ createAppender: async () => ({
+ appendValue: () => {},
+ appendNull: () => {},
+ endRow: () => {},
+ flushSync: () => {
+ flushCalled = true;
+ },
+ closeSync: () => {
+ closeCalled = true;
+ },
+ }),
+ };
+ let caught;
+ try {
+ await pipeline([
+ createReadableStream([]),
+ await duckdbArrowInsertStream({ db, table: "t" }),
+ ]);
+ } catch (e) {
+ caught = e;
+ }
+ strictEqual(caught, undefined, "empty arrow stream must complete cleanly");
+ strictEqual(flushCalled, false, "flushSync must not run for an empty stream");
+ strictEqual(closeCalled, false, "closeSync must not run for an empty stream");
+});
diff --git a/packages/duckdb/index.tst.ts b/packages/duckdb/index.tst.ts
new file mode 100644
index 0000000..a2b1193
--- /dev/null
+++ b/packages/duckdb/index.tst.ts
@@ -0,0 +1,50 @@
+///
+///
+import {
+ duckdbAppenderStream,
+ duckdbArrowInsertStream,
+ duckdbConnect,
+} from "@datastream/duckdb";
+import type { Schema } from "apache-arrow";
+import { describe, expect, test } from "tstyche";
+
+const db: unknown = {};
+const schema = {} as Schema;
+
+describe("duckdbConnect", () => {
+ test("accepts no args", () => {
+ expect(duckdbConnect()).type.not.toBeAssignableTo();
+ });
+
+ test("accepts path and options", () => {
+ expect(
+ duckdbConnect(":memory:", { access_mode: "READ_WRITE" }),
+ ).type.not.toBeAssignableTo();
+ });
+
+ test("returns a Promise", () => {
+ expect(duckdbConnect()).type.toBe>();
+ });
+});
+
+describe("duckdbAppenderStream", () => {
+ test("requires db and table", () => {
+ expect(
+ duckdbAppenderStream({ db, table: "t" }),
+ ).type.not.toBeAssignableTo();
+ });
+
+ test("accepts schema", () => {
+ expect(
+ duckdbAppenderStream({ db, table: "t", schema }),
+ ).type.not.toBeAssignableTo();
+ });
+});
+
+describe("duckdbArrowInsertStream", () => {
+ test("requires db and table", () => {
+ expect(
+ duckdbArrowInsertStream({ db, table: "t" }),
+ ).type.not.toBeAssignableTo();
+ });
+});
diff --git a/packages/duckdb/index.web.js b/packages/duckdb/index.web.js
new file mode 100644
index 0000000..b500d0b
--- /dev/null
+++ b/packages/duckdb/index.web.js
@@ -0,0 +1,186 @@
+// Copyright 2026 will Farrell, and datastream contributors.
+// SPDX-License-Identifier: MIT
+import { createWritableStream, resolveLazy } from "@datastream/core";
+
+export const duckdbConnect = async (..._args) => {
+ const { AsyncDuckDB, ConsoleLogger, getJsDelivrBundles, selectBundle } =
+ await import("@duckdb/duckdb-wasm");
+ const bundle = await selectBundle(getJsDelivrBundles());
+ const worker = new Worker(bundle.mainWorker);
+ const db = new AsyncDuckDB(new ConsoleLogger(), worker);
+ await db.instantiate(bundle.mainModule, bundle.pthreadWorker);
+ const connection = await db.connect();
+ connection.__duckdb = db;
+ return connection;
+};
+
+// DuckDB has no parameter binding for identifiers, so table/column names are
+// interpolated into SQL. Double the embedded quotes and require a non-empty
+// string so a crafted name can't break out of the quoted identifier.
+const quoteIdent = (name) => {
+ if (typeof name !== "string" || name.length === 0) {
+ throw new TypeError("duckdb: identifier must be a non-empty string");
+ }
+ return `"${name.replaceAll('"', '""')}"`;
+};
+
+// A failed existence probe should only be read as "table does not exist" when
+// the error is a missing-table/catalog error. Any other failure (lock,
+// permission, column read error, ...) must propagate so it is not masked by a
+// confusing downstream "table already exists" from CREATE TABLE.
+const isMissingTableError = (error) => {
+ const message = String(error?.message ?? error).toLowerCase();
+ return (
+ message.includes("does not exist") ||
+ message.includes("not found") ||
+ message.includes("catalog error")
+ );
+};
+
+const tableExists = async (db, table) => {
+ try {
+ await db.query(`SELECT 1 FROM ${quoteIdent(table)} LIMIT 0`);
+ return true;
+ } catch (error) {
+ if (isMissingTableError(error)) return false;
+ throw error;
+ }
+};
+
+const fetchColumnNames = async (db, table) => {
+ const result = await db.query(`SELECT * FROM ${quoteIdent(table)} LIMIT 0`);
+ return result.schema.fields.map((f) => f.name);
+};
+
+const arrowTypeToDuckDBSQL = (type) => {
+ const name = type?.constructor?.name;
+ switch (name) {
+ case "Bool":
+ return "BOOLEAN";
+ case "Int8":
+ return "TINYINT";
+ case "Int16":
+ return "SMALLINT";
+ case "Int32":
+ return "INTEGER";
+ case "Int64":
+ return "BIGINT";
+ case "Uint8":
+ return "UTINYINT";
+ case "Uint16":
+ return "USMALLINT";
+ case "Uint32":
+ return "UINTEGER";
+ case "Uint64":
+ return "UBIGINT";
+ case "Float32":
+ return "REAL";
+ case "Float64":
+ return "DOUBLE";
+ case "Date_":
+ return "DATE";
+ case "TimestampSecond":
+ return "TIMESTAMP_S";
+ case "TimestampMillisecond":
+ return "TIMESTAMP_MS";
+ case "TimestampMicrosecond":
+ return "TIMESTAMP";
+ case "TimestampNanosecond":
+ return "TIMESTAMP_NS";
+ default:
+ return "VARCHAR";
+ }
+};
+
+const createTableFromArrowSchema = async (db, table, schema) => {
+ const cols = schema.fields
+ .map((f) => `${quoteIdent(f.name)} ${arrowTypeToDuckDBSQL(f.type)}`)
+ .join(", ");
+ await db.query(`CREATE TABLE ${quoteIdent(table)} (${cols})`);
+};
+
+const ensureTableAndColumns = async (db, table, schema) => {
+ if (schema && !(await tableExists(db, table))) {
+ await createTableFromArrowSchema(db, table, schema);
+ }
+ // Always derive the column order from the table's PHYSICAL layout so node and
+ // web agree: a provided schema whose field order differs from the physical
+ // column order must not change which value lands in which column.
+ return fetchColumnNames(db, table);
+};
+
+const buildInsertSQL = (table, columnNames) => {
+ const cols = columnNames.map((n) => quoteIdent(n)).join(", ");
+ const params = columnNames.map(() => "?").join(", ");
+ return `INSERT INTO ${quoteIdent(table)} (${cols}) VALUES (${params})`;
+};
+
+export const duckdbAppenderStream = async (
+ { db, table, schema },
+ streamOptions = {},
+) => {
+ let prepared;
+ let columnNames;
+
+ const init = async () => {
+ const resolvedSchema = resolveLazy(schema);
+ columnNames = await ensureTableAndColumns(db, table, resolvedSchema);
+ prepared = await db.prepare(buildInsertSQL(table, columnNames));
+ };
+
+ const write = async (row) => {
+ if (!prepared) await init();
+ const isArray = Array.isArray(row);
+ const values = new Array(columnNames.length);
+ for (let i = 0, l = columnNames.length; i < l; i++) {
+ values[i] = isArray ? row[i] : row[columnNames[i]];
+ }
+ await prepared.send(...values);
+ };
+ const final = async () => {
+ if (prepared) await prepared.close();
+ };
+
+ return createWritableStream(write, final, streamOptions);
+};
+
+export const duckdbArrowInsertStream = async (
+ { db, table, schema },
+ streamOptions = {},
+) => {
+ let initialized = false;
+ let columnNames;
+ const batches = [];
+
+ const init = async () => {
+ const resolvedSchema = resolveLazy(schema);
+ columnNames = await ensureTableAndColumns(db, table, resolvedSchema);
+ initialized = true;
+ };
+
+ const { tableFromIPC, tableToIPC, Table } = await import("apache-arrow");
+
+ const write = async (batch) => {
+ if (!initialized) await init();
+ // Accumulate the RecordBatch objects themselves. Serializing each batch as
+ // its own complete IPC stream and byte-concatenating them would produce
+ // multiple EOS markers; tableFromIPC stops at the first, silently dropping
+ // every batch after the first. Build one Table from all batches instead.
+ batches.push(batch);
+ };
+ const final = async () => {
+ if (!batches.length) return;
+ const ipc = tableToIPC(new Table(batches), "stream");
+ const arrowTable = tableFromIPC(ipc);
+ await db.insertArrowTable(arrowTable, { name: table, create: false });
+ void columnNames;
+ };
+
+ return createWritableStream(write, final, streamOptions);
+};
+
+export default {
+ connect: duckdbConnect,
+ appenderStream: duckdbAppenderStream,
+ arrowInsertStream: duckdbArrowInsertStream,
+};
diff --git a/packages/duckdb/package.json b/packages/duckdb/package.json
new file mode 100644
index 0000000..bdcf9e3
--- /dev/null
+++ b/packages/duckdb/package.json
@@ -0,0 +1,91 @@
+{
+ "name": "@datastream/duckdb",
+ "version": "0.5.0",
+ "description": "DuckDB writable streams (copy-from) for Node and browser",
+ "type": "module",
+ "engines": {
+ "node": ">=24"
+ },
+ "engineStrict": true,
+ "publishConfig": {
+ "access": "public"
+ },
+ "main": "./index.node.mjs",
+ "module": "./index.web.mjs",
+ "exports": {
+ ".": {
+ "node": {
+ "import": {
+ "types": "./index.d.ts",
+ "default": "./index.node.mjs"
+ }
+ },
+ "import": {
+ "types": "./index.d.ts",
+ "default": "./index.web.mjs"
+ }
+ },
+ "./webstream": {
+ "types": "./index.d.ts",
+ "default": "./index.web.mjs"
+ }
+ },
+ "types": "index.d.ts",
+ "files": [
+ "*.mjs",
+ "*.map",
+ "*.d.ts"
+ ],
+ "scripts": {
+ "test": "npm run test:unit",
+ "test:unit": "node --test",
+ "test:perf": "node --test index.perf.js",
+ "test:mutation": "cd ../.. && MUTATE_PACKAGE=\"$(basename \"$OLDPWD\")\" stryker run"
+ },
+ "license": "MIT",
+ "keywords": [
+ "duckdb",
+ "sql",
+ "writable",
+ "Web Stream API",
+ "Node Stream API"
+ ],
+ "author": {
+ "name": "datastream contributors",
+ "url": "https://github.com/willfarrell/datastream/graphs/contributors"
+ },
+ "repository": {
+ "type": "git",
+ "url": "github:willfarrell/datastream",
+ "directory": "packages/duckdb"
+ },
+ "bugs": {
+ "url": "https://github.com/willfarrell/datastream/issues"
+ },
+ "homepage": "https://datastream.js.org",
+ "dependencies": {
+ "@datastream/core": "0.5.0"
+ },
+ "peerDependencies": {
+ "@duckdb/duckdb-wasm": "^1.33.1-dev45.0",
+ "@duckdb/node-api": "^1.5.3-r.1",
+ "apache-arrow": "21.1.0"
+ },
+ "peerDependenciesMeta": {
+ "@duckdb/duckdb-wasm": {
+ "optional": true
+ },
+ "@duckdb/node-api": {
+ "optional": true
+ },
+ "apache-arrow": {
+ "optional": true
+ }
+ },
+ "devDependencies": {
+ "@datastream/arrow": "0.5.0",
+ "@duckdb/duckdb-wasm": "1.33.1-dev45.0",
+ "@duckdb/node-api": "1.5.3-r.1",
+ "apache-arrow": "21.1.0"
+ }
+}
diff --git a/packages/kafka/README.md b/packages/kafka/README.md
new file mode 100644
index 0000000..0e6eadf
--- /dev/null
+++ b/packages/kafka/README.md
@@ -0,0 +1,52 @@
+
+ <datastream> `kafka`
+
+ Kafka producer and consumer streams.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+You can read the documentation at: https://datastream.js.org
+
+
+
+## Install
+
+To install datastream you can use NPM:
+
+```bash
+npm install --save @datastream/kafka
+```
+
+
+## Documentation and examples
+
+For documentation and examples, refer to the main [datastream monorepo on GitHub](https://github.com/willfarrell/datastream) or [datastream official website](https://datastream.js.org).
+
+
+## Contributing
+
+Everyone is very welcome to contribute to this repository. Feel free to [raise issues](https://github.com/willfarrell/datastream/issues) or to [submit Pull Requests](https://github.com/willfarrell/datastream/pulls).
+
+
+## License
+
+Licensed under [MIT License](LICENSE). Copyright (c) 2026 [will Farrell](https://github.com/willfarrell), and [datastream contributors](https://github.com/willfarrell/datastream/graphs/contributors).
\ No newline at end of file
diff --git a/packages/kafka/index.d.ts b/packages/kafka/index.d.ts
new file mode 100644
index 0000000..6af7217
--- /dev/null
+++ b/packages/kafka/index.d.ts
@@ -0,0 +1,82 @@
+// Copyright 2026 will Farrell, and datastream contributors.
+// SPDX-License-Identifier: MIT
+import type {
+ DatastreamReadable,
+ DatastreamWritable,
+ StreamOptions,
+} from "@datastream/core";
+
+export interface KafkaConnection {
+ kafka: unknown;
+ producer: unknown | null;
+ consumer: unknown | null;
+ disconnect: () => Promise;
+}
+
+export function kafkaConnect(options?: {
+ brokers?: string[];
+ clientId?: string;
+ ssl?: unknown;
+ sasl?: unknown;
+ groupId?: string;
+ /** Pass `false` to skip opening a producer. */
+ producer?: Record | false;
+ consumer?: Record;
+ /** Injectable Kafka constructor; defaults to a lazy `import("kafkajs")`. */
+ Kafka?: new (
+ options: Record,
+ ) => unknown;
+ [key: string]: unknown;
+}): Promise;
+
+export interface KafkaMessage {
+ value: Uint8Array | string;
+ key?: Uint8Array | string;
+ partition?: number;
+ headers?: Record;
+ timestamp?: string;
+ [key: string]: unknown;
+}
+
+export function kafkaProduceStream(
+ options: {
+ producer: unknown;
+ topic: string;
+ batchSize?: number;
+ acks?: number;
+ compression?: number;
+ timeout?: number;
+ },
+ streamOptions?: StreamOptions,
+): Promise>;
+
+export interface KafkaConsumedMessage {
+ topic: string;
+ partition: number;
+ offset: string;
+ key: Uint8Array | null;
+ value: Uint8Array | null;
+ headers: Record;
+ timestamp: string;
+}
+
+export function kafkaConsumeStream(
+ options: {
+ consumer: unknown;
+ topics: string | string[];
+ fromBeginning?: boolean;
+ autoCommit?: boolean;
+ partitionsConsumedConcurrently?: number;
+ signal?: AbortSignal;
+ },
+ streamOptions?: StreamOptions,
+): Promise<
+ DatastreamReadable & { stop: () => Promise }
+>;
+
+declare const _default: {
+ connect: typeof kafkaConnect;
+ produceStream: typeof kafkaProduceStream;
+ consumeStream: typeof kafkaConsumeStream;
+};
+export default _default;
diff --git a/packages/kafka/index.fuzz.js b/packages/kafka/index.fuzz.js
new file mode 100644
index 0000000..0c81f19
--- /dev/null
+++ b/packages/kafka/index.fuzz.js
@@ -0,0 +1,326 @@
+// Copyright 2026 will Farrell, and datastream contributors.
+// SPDX-License-Identifier: MIT
+import test from "node:test";
+import { streamToArray } from "@datastream/core";
+import {
+ kafkaConnect,
+ kafkaConsumeStream,
+ kafkaProduceStream,
+} from "@datastream/kafka";
+import fc from "fast-check";
+
+const catchError = (input, e) => {
+ const expectedErrors = [
+ "kafkaProduceStream: producer required",
+ "kafkaProduceStream: topic required",
+ "kafkaProduceStream: batchSize must be >= 1",
+ "kafkaConsumeStream: consumer required",
+ "kafkaConsumeStream: topics required",
+ // Node.js stream protocol: null is the EOF sentinel and cannot be written
+ "May not write null values to stream",
+ ];
+ // Also swallow normalizeMessage TypeErrors (chunk type errors)
+ if (expectedErrors.includes(e.message)) {
+ return;
+ }
+ if (e instanceof TypeError && e.message.startsWith("kafkaProduceStream:")) {
+ return;
+ }
+ // Node.js writable stream rejects null with ERR_STREAM_NULL_VALUES
+ if (e.code === "ERR_STREAM_NULL_VALUES") {
+ return;
+ }
+ console.error(input, e);
+ throw e;
+};
+
+// ---------------------------------------------------------------------------
+// Minimal fake Kafka factory
+// ---------------------------------------------------------------------------
+
+const makeFakeKafka = () => {
+ const producerMock = {
+ connect: async () => {},
+ disconnect: async () => {},
+ send: async () => {},
+ };
+
+ const consumerMock = {
+ _runResolve: null,
+ connect: async () => {},
+ disconnect: async () => {},
+ subscribe: async () => {},
+ stop: async () => {
+ if (consumerMock._runResolve) consumerMock._runResolve();
+ },
+ run: async () =>
+ new Promise((resolve) => {
+ consumerMock._runResolve = resolve;
+ }),
+ };
+
+ const Kafka = function (opts) {
+ this.opts = opts;
+ this.producer = () => producerMock;
+ this.consumer = () => consumerMock;
+ };
+
+ return { Kafka, producerMock, consumerMock };
+};
+
+// ---------------------------------------------------------------------------
+// fuzz: kafkaConnect
+// ---------------------------------------------------------------------------
+
+test("fuzz kafkaConnect w/ random options", async () => {
+ await fc.assert(
+ fc.asyncProperty(
+ fc.record({
+ brokers: fc.option(
+ fc.array(fc.string({ minLength: 1, maxLength: 50 }), {
+ minLength: 1,
+ maxLength: 3,
+ }),
+ ),
+ clientId: fc.option(fc.string({ minLength: 0, maxLength: 50 })),
+ groupId: fc.option(fc.string({ minLength: 0, maxLength: 50 })),
+ ssl: fc.option(fc.boolean()),
+ producer: fc.option(fc.oneof(fc.constant(false), fc.constant({}))),
+ }),
+ async (options) => {
+ try {
+ const { Kafka } = makeFakeKafka();
+ const conn = await kafkaConnect({ ...options, Kafka });
+ await conn.disconnect();
+ } catch (e) {
+ catchError(options, e);
+ }
+ },
+ ),
+ {
+ numRuns: 1_000,
+ verbose: 2,
+ examples: [],
+ },
+ );
+});
+
+// ---------------------------------------------------------------------------
+// fuzz: kafkaProduceStream options
+// ---------------------------------------------------------------------------
+
+test("fuzz kafkaProduceStream w/ random options", async () => {
+ await fc.assert(
+ fc.asyncProperty(
+ fc.record({
+ topic: fc.option(fc.string({ minLength: 0, maxLength: 50 })),
+ batchSize: fc.option(fc.integer({ min: -5, max: 200 })),
+ acks: fc.option(fc.integer({ min: -1, max: 1 })),
+ compression: fc.option(fc.integer({ min: 0, max: 4 })),
+ timeout: fc.option(fc.integer({ min: 0, max: 30_000 })),
+ }),
+ async (options) => {
+ try {
+ const { producerMock } = makeFakeKafka();
+ const stream = await kafkaProduceStream({
+ producer: producerMock,
+ ...options,
+ });
+ stream.end();
+ await new Promise((resolve, reject) => {
+ stream.on("finish", resolve);
+ stream.on("error", reject);
+ });
+ } catch (e) {
+ catchError(options, e);
+ }
+ },
+ ),
+ {
+ numRuns: 1_000,
+ verbose: 2,
+ examples: [],
+ },
+ );
+});
+
+// ---------------------------------------------------------------------------
+// fuzz: kafkaProduceStream w/ random messages
+// ---------------------------------------------------------------------------
+
+test("fuzz kafkaProduceStream w/ random messages", async () => {
+ await fc.assert(
+ fc.asyncProperty(
+ fc.array(
+ fc.oneof(
+ fc.string({ minLength: 0, maxLength: 100 }),
+ fc.record({
+ value: fc.string({ minLength: 0, maxLength: 100 }),
+ key: fc.option(fc.string({ minLength: 0, maxLength: 50 })),
+ }),
+ // invalid types to exercise normalizeMessage error path
+ fc.integer(),
+ fc.boolean(),
+ // null is excluded: it is the Node.js stream EOF sentinel and
+ // writing null to a Writable is a stream protocol error, not
+ // something kafkaProduceStream is expected to handle.
+ ),
+ { minLength: 1, maxLength: 50 },
+ ),
+ async (messages) => {
+ try {
+ const { producerMock } = makeFakeKafka();
+ const stream = await kafkaProduceStream({
+ producer: producerMock,
+ topic: "fuzz-topic",
+ });
+ await new Promise((resolve, reject) => {
+ stream.on("error", (e) => {
+ try {
+ catchError(messages, e);
+ resolve();
+ } catch (err) {
+ reject(err);
+ }
+ });
+ stream.on("finish", resolve);
+ for (const msg of messages) {
+ stream.write(msg);
+ }
+ stream.end();
+ });
+ } catch (e) {
+ catchError(messages, e);
+ }
+ },
+ ),
+ {
+ numRuns: 1_000,
+ verbose: 2,
+ examples: [],
+ },
+ );
+});
+
+// ---------------------------------------------------------------------------
+// fuzz: kafkaConsumeStream options
+// ---------------------------------------------------------------------------
+
+test("fuzz kafkaConsumeStream w/ random options", async () => {
+ await fc.assert(
+ fc.asyncProperty(
+ fc.record({
+ topics: fc.option(
+ fc.oneof(
+ fc.string({ minLength: 1, maxLength: 50 }),
+ fc.array(fc.string({ minLength: 1, maxLength: 50 }), {
+ minLength: 1,
+ maxLength: 3,
+ }),
+ fc.constant([]),
+ ),
+ ),
+ fromBeginning: fc.option(fc.boolean()),
+ autoCommit: fc.option(fc.boolean()),
+ partitionsConsumedConcurrently: fc.option(
+ fc.integer({ min: 1, max: 8 }),
+ ),
+ }),
+ async (options) => {
+ try {
+ const { consumerMock } = makeFakeKafka();
+ const stream = await kafkaConsumeStream({
+ consumer: consumerMock,
+ ...options,
+ });
+ const closePromise = new Promise((resolve) =>
+ stream.once("close", resolve),
+ );
+ stream.destroy();
+ await closePromise;
+ } catch (e) {
+ catchError(options, e);
+ }
+ },
+ ),
+ {
+ numRuns: 1_000,
+ verbose: 2,
+ examples: [],
+ },
+ );
+});
+
+// ---------------------------------------------------------------------------
+// fuzz: kafkaConsumeStream message delivery w/ random message payloads
+// ---------------------------------------------------------------------------
+
+test("fuzz kafkaConsumeStream w/ random message payloads", async () => {
+ await fc.assert(
+ fc.asyncProperty(
+ fc.array(
+ fc.record({
+ topic: fc.string({ minLength: 1, maxLength: 50 }),
+ partition: fc.integer({ min: 0, max: 10 }),
+ offset: fc.nat().map(String),
+ key: fc.option(fc.string({ minLength: 0, maxLength: 50 })),
+ value: fc.option(fc.string({ minLength: 0, maxLength: 200 })),
+ timestamp: fc.nat().map(String),
+ }),
+ { minLength: 1, maxLength: 100 },
+ ),
+ async (messages) => {
+ try {
+ let eachMessageFn;
+ const consumerMock = {
+ _runResolve: null,
+ connect: async () => {},
+ disconnect: async () => {},
+ subscribe: async () => {},
+ stop: async () => {
+ if (consumerMock._runResolve) consumerMock._runResolve();
+ },
+ run: async ({ eachMessage }) => {
+ eachMessageFn = eachMessage;
+ return new Promise((resolve) => {
+ consumerMock._runResolve = resolve;
+ });
+ },
+ };
+
+ const stream = await kafkaConsumeStream(
+ { consumer: consumerMock, topics: "fuzz-topic" },
+ { highWaterMark: messages.length + 1 },
+ );
+
+ const delivery = (async () => {
+ for (const msg of messages) {
+ await eachMessageFn({
+ topic: msg.topic,
+ partition: msg.partition,
+ message: {
+ offset: msg.offset,
+ key: msg.key,
+ value: msg.value,
+ headers: {},
+ timestamp: msg.timestamp,
+ },
+ });
+ }
+ await stream.stop();
+ })();
+
+ await streamToArray(stream);
+ await delivery;
+ } catch (e) {
+ catchError(messages, e);
+ }
+ },
+ ),
+ {
+ numRuns: 1_000,
+ verbose: 2,
+ examples: [],
+ },
+ );
+});
diff --git a/packages/kafka/index.node.js b/packages/kafka/index.node.js
new file mode 100644
index 0000000..ac3dbd7
--- /dev/null
+++ b/packages/kafka/index.node.js
@@ -0,0 +1,271 @@
+// Copyright 2026 will Farrell, and datastream contributors.
+// SPDX-License-Identifier: MIT
+import { Readable } from "node:stream";
+import { createWritableStream } from "@datastream/core";
+
+export const kafkaConnect = async ({
+ brokers,
+ clientId,
+ ssl,
+ sasl,
+ groupId,
+ producer: producerOptions,
+ consumer: consumerOptions,
+ // Injectable Kafka constructor (defaults to kafkajs). Lets callers/tests
+ // supply a stub without reaching for a real broker; falls back to the lazy
+ // dynamic import so the production path is unchanged.
+ Kafka,
+ ...kafkaOptions
+} = {}) => {
+ Kafka ??= (await import("kafkajs")).Kafka;
+ const kafka = new Kafka({ brokers, clientId, ssl, sasl, ...kafkaOptions });
+ // Open a producer only if it wasn't explicitly disabled. Open a consumer
+ // only when a groupId is provided. Either or both may be null.
+ const producer =
+ producerOptions === false ? null : kafka.producer(producerOptions ?? {});
+ const consumer = groupId
+ ? kafka.consumer({ groupId, ...(consumerOptions ?? {}) })
+ : null;
+ // Connect under a guard: if the second connect fails, the first is already
+ // connected (open socket + background metadata/heartbeat timers) with no
+ // disconnect handle escaping to the caller. Tear down whatever connected
+ // before rethrowing so the error path leaks nothing.
+ try {
+ if (producer) await producer.connect();
+ if (consumer) await consumer.connect();
+ } catch (err) {
+ await producer?.disconnect().catch(() => {});
+ await consumer?.disconnect().catch(() => {});
+ throw err;
+ }
+ return {
+ kafka,
+ producer,
+ consumer,
+ disconnect: async () => {
+ if (producer) await producer.disconnect();
+ if (consumer) await consumer.disconnect();
+ },
+ };
+};
+
+const normalizeMessage = (chunk) => {
+ if (chunk instanceof Uint8Array || typeof chunk === "string") {
+ return { value: chunk };
+ }
+ if (chunk && typeof chunk === "object" && "value" in chunk) {
+ return chunk;
+ }
+ // Note: `chunk` is never null here — Node.js Writable streams reject null
+ // with ERR_STREAM_NULL_VALUES before the write callback fires — so we report
+ // `typeof chunk` directly without a dead `chunk === null` branch.
+ throw new TypeError(
+ `kafkaProduceStream: chunk must be Uint8Array, string, or { value, ... } object (got ${typeof chunk})`,
+ );
+};
+
+export const kafkaProduceStream = async (
+ {
+ producer,
+ topic,
+ batchSize = 100,
+ acks = -1,
+ compression,
+ timeout: requestTimeout,
+ } = {},
+ streamOptions = {},
+) => {
+ if (!producer) throw new TypeError("kafkaProduceStream: producer required");
+ if (!topic) throw new TypeError("kafkaProduceStream: topic required");
+ if (!(batchSize >= 1)) {
+ throw new TypeError("kafkaProduceStream: batchSize must be >= 1");
+ }
+
+ let batch = [];
+ const flush = async () => {
+ if (!batch.length) return;
+ // Snapshot then start a fresh batch *before* the send. Two reasons:
+ // 1. The snapshot stays addressable on the error path so callers can
+ // re-queue via `err.failedMessages` instead of losing the batch.
+ // 2. If kafkajs mutates `messages` (or holds a reference), we don't want
+ // our next write() to interleave with what's in flight.
+ const sending = batch;
+ batch = [];
+ try {
+ await producer.send({
+ topic,
+ messages: sending,
+ acks,
+ compression,
+ timeout: requestTimeout,
+ });
+ } catch (err) {
+ err.failedMessages = sending;
+ throw err;
+ }
+ };
+ const write = async (chunk) => {
+ batch.push(normalizeMessage(chunk));
+ if (batch.length >= batchSize) await flush();
+ };
+ const final = async () => {
+ await flush();
+ };
+ const stream = createWritableStream(write, final, streamOptions);
+ // Node's final() runs only on a graceful end(), never on destroy() or an
+ // AbortSignal-triggered teardown. Without this, a partial batch buffered
+ // below batchSize would be silently dropped on abort — no send, no error.
+ // Surface the un-sent batch on the teardown error (mirroring flush()'s
+ // err.failedMessages contract) so callers can recover/retry it instead of
+ // losing it. We wrap the default Writable destroy rather than replacing it.
+ const originalDestroy = stream._destroy.bind(stream);
+ stream._destroy = (err, cb) => {
+ if (batch.length) {
+ // The stream is being torn down: no further write()/final() can run, so
+ // `batch` is never read again. Hand the buffered messages straight to the
+ // error (mirroring flush()'s err.failedMessages contract) without a dead
+ // reassignment.
+ err ??= new Error("kafkaProduceStream: destroyed with a buffered batch");
+ err.failedMessages = batch;
+ }
+ originalDestroy(err, cb);
+ };
+ return stream;
+};
+
+export const kafkaConsumeStream = async (
+ {
+ consumer,
+ topics,
+ fromBeginning = false,
+ autoCommit = true,
+ partitionsConsumedConcurrently = 1,
+ signal,
+ },
+ streamOptions = {},
+) => {
+ if (!consumer) throw new TypeError("kafkaConsumeStream: consumer required");
+ if (!topics || (Array.isArray(topics) && !topics.length)) {
+ throw new TypeError("kafkaConsumeStream: topics required");
+ }
+
+ const topicList = Array.isArray(topics) ? topics : [topics];
+ for (const topic of topicList) {
+ await consumer.subscribe({ topic, fromBeginning });
+ }
+
+ // Backpressure: kafkajs awaits each eachMessage callback before fetching the
+ // next message on the same partition (and per-partition concurrency caps
+ // fan-in). We construct a Node Readable and let `.push` return false when
+ // the buffer is full; we then await the next `_read` (consumer pulled) before
+ // returning from eachMessage. That suspends kafkajs's loop end-to-end so
+ // backpressure reaches the broker instead of bursting through.
+ // With partitionsConsumedConcurrently > 1, several eachMessage callbacks can
+ // be parked on backpressure at the same time. Track every waiting resolver
+ // (not just the latest) and release them all on the next `_read`; a single
+ // slot would drop all but the last waiter and hang those partition loops.
+ const readResolvers = new Set();
+ const waitForRead = () =>
+ new Promise((resolve) => {
+ readResolvers.add(resolve);
+ });
+ const releaseReaders = () => {
+ // Snapshot then clear before resolving so a resolver that synchronously
+ // re-parks lands in a fresh Set. Iterating an empty Set is already a no-op,
+ // so no explicit size guard is needed.
+ const pending = [...readResolvers];
+ readResolvers.clear();
+ for (const resolve of pending) resolve();
+ };
+
+ let stopped = false;
+ let runPromise;
+ // Memoize consumer.stop() so every teardown path (explicit stop(), destroy(),
+ // abort) shares ONE invocation. kafkajs's consumer.stop() is not guaranteed
+ // safe to call twice concurrently, and stop()+later-destroy() previously
+ // called it twice. Best-effort: swallow errors, run at most once.
+ let consumerStopPromise;
+ const stopConsumerOnce = () => {
+ consumerStopPromise ??= Promise.resolve()
+ .then(() => consumer.stop())
+ .catch(() => {});
+ return consumerStopPromise;
+ };
+
+ const stream = new Readable({
+ objectMode: true,
+ highWaterMark: streamOptions.highWaterMark ?? 100,
+ read() {
+ releaseReaders();
+ },
+ destroy(err, cb) {
+ stopped = true;
+ // Drop the abort listener: a destroyed stream never needs to react to
+ // the signal again, and on long-lived/shared signals an un-removed
+ // listener accumulates per stream.
+ if (signal) signal.removeEventListener("abort", stop);
+ // Release any eachMessage callbacks parked on backpressure first, so
+ // they observe `stopped` and return. consumer.stop() waits for in-flight
+ // callbacks to settle; without this release it would wait on a parked
+ // callback that itself can only resume once `_read` fires — a circular
+ // wait that deadlocks. Symmetric with stop().
+ releaseReaders();
+ // Best-effort consumer.stop on destroy, memoized so a prior stop() (or
+ // a concurrent abort) does not trigger a second consumer.stop().
+ stopConsumerOnce().then(() => cb(err));
+ },
+ });
+
+ runPromise = consumer.run({
+ autoCommit,
+ partitionsConsumedConcurrently,
+ eachMessage: async ({ topic, partition, message }) => {
+ if (stopped) return;
+ const wantsMore = stream.push({
+ topic,
+ partition,
+ offset: message.offset,
+ key: message.key,
+ value: message.value,
+ headers: message.headers,
+ timestamp: message.timestamp,
+ });
+ if (!wantsMore) await waitForRead();
+ },
+ });
+
+ const stop = async () => {
+ // No early-out on a repeat call is needed: every step below is idempotent —
+ // consumer.stop() is memoized via stopConsumerOnce(), removeEventListener is
+ // a no-op once removed, stream.push(null) is a no-op after EOF, and
+ // releaseReaders() is a no-op with no parked readers. Setting `stopped`
+ // first still makes parked eachMessage callbacks observe it and return.
+ stopped = true;
+ // Detach from the signal on every normal termination. `{ once: true }`
+ // only fires-and-removes when the signal actually aborts; for a normal
+ // stop()/drain the listener would otherwise linger forever on a
+ // long-lived/shared signal, accumulating one listener per consume stream.
+ // `stop` is the exact handler reference, so this removes cleanly.
+ if (signal) signal.removeEventListener("abort", stop);
+ await stopConsumerOnce();
+ stream.push(null);
+ await runPromise.catch(() => {});
+ // Unblock any pending eachMessage awaits so they can observe `stopped`
+ // and return.
+ releaseReaders();
+ };
+
+ if (signal) {
+ if (signal.aborted) await stop();
+ else signal.addEventListener("abort", stop);
+ }
+
+ stream.stop = stop;
+ return stream;
+};
+
+export default {
+ connect: kafkaConnect,
+ produceStream: kafkaProduceStream,
+ consumeStream: kafkaConsumeStream,
+};
diff --git a/packages/kafka/index.perf.js b/packages/kafka/index.perf.js
new file mode 100644
index 0000000..3f6901f
--- /dev/null
+++ b/packages/kafka/index.perf.js
@@ -0,0 +1,228 @@
+// Copyright 2026 will Farrell, and datastream contributors.
+// SPDX-License-Identifier: MIT
+import test from "node:test";
+import { createReadableStream, streamToArray } from "@datastream/core";
+import {
+ kafkaConnect,
+ kafkaConsumeStream,
+ kafkaProduceStream,
+} from "@datastream/kafka";
+import { Bench } from "tinybench";
+
+const time = Number(process.env.BENCH_TIME ?? 5_000);
+
+// ---------------------------------------------------------------------------
+// Fake Kafka factory (trimmed — no spy counters needed for perf)
+// ---------------------------------------------------------------------------
+
+const makeFakeKafka = ({ run } = {}) => {
+ const producerMock = {
+ connect: async () => {},
+ disconnect: async () => {},
+ send: async () => {},
+ };
+
+ const consumerMock = {
+ _runResolve: null,
+ connect: async () => {},
+ disconnect: async () => {},
+ subscribe: async () => {},
+ stop: async () => {
+ if (consumerMock._runResolve) consumerMock._runResolve();
+ },
+ run:
+ run ??
+ (async () =>
+ new Promise((resolve) => {
+ consumerMock._runResolve = resolve;
+ })),
+ };
+
+ const Kafka = function (opts) {
+ this.opts = opts;
+ this.producer = () => producerMock;
+ this.consumer = () => consumerMock;
+ };
+
+ return { Kafka, producerMock, consumerMock };
+};
+
+// ---------------------------------------------------------------------------
+// perf: kafkaProduceStream
+// ---------------------------------------------------------------------------
+
+test("perf: kafkaProduceStream", async () => {
+ const bench = new Bench({ name: "kafkaProduceStream", time });
+
+ const MSG_COUNT = 10_000;
+ const messages = Array.from({ length: MSG_COUNT }, (_, i) => ({
+ value: `message-${i}`,
+ key: `key-${i}`,
+ }));
+
+ bench.add(`produce ${MSG_COUNT} messages (batchSize default)`, async () => {
+ const { Kafka } = makeFakeKafka();
+ const { producer } = await kafkaConnect({ Kafka });
+ const stream = await kafkaProduceStream({ producer, topic: "perf-topic" });
+ const readable = createReadableStream(messages);
+ const writeAll = new Promise((resolve, reject) => {
+ readable.on("data", (chunk) => {
+ stream.write(chunk);
+ });
+ readable.on("end", () => {
+ stream.end();
+ });
+ stream.on("finish", resolve);
+ stream.on("error", reject);
+ });
+ await writeAll;
+ });
+
+ bench.add(`produce ${MSG_COUNT} messages (batchSize 1000)`, async () => {
+ const { Kafka } = makeFakeKafka();
+ const { producer } = await kafkaConnect({ Kafka });
+ const stream = await kafkaProduceStream({
+ producer,
+ topic: "perf-topic",
+ batchSize: 1_000,
+ });
+ const readable = createReadableStream(messages);
+ const writeAll = new Promise((resolve, reject) => {
+ readable.on("data", (chunk) => {
+ stream.write(chunk);
+ });
+ readable.on("end", () => {
+ stream.end();
+ });
+ stream.on("finish", resolve);
+ stream.on("error", reject);
+ });
+ await writeAll;
+ });
+
+ bench.add(`produce ${MSG_COUNT} string messages`, async () => {
+ const { Kafka } = makeFakeKafka();
+ const { producer } = await kafkaConnect({ Kafka });
+ const stream = await kafkaProduceStream({ producer, topic: "perf-topic" });
+ const strMessages = Array.from({ length: MSG_COUNT }, (_, i) => `msg-${i}`);
+ const readable = createReadableStream(strMessages);
+ const writeAll = new Promise((resolve, reject) => {
+ readable.on("data", (chunk) => {
+ stream.write(chunk);
+ });
+ readable.on("end", () => {
+ stream.end();
+ });
+ stream.on("finish", resolve);
+ stream.on("error", reject);
+ });
+ await writeAll;
+ });
+
+ await bench.run();
+ console.log(`\n${bench.name}`);
+ console.table(bench.table());
+});
+
+// ---------------------------------------------------------------------------
+// perf: kafkaConsumeStream
+// ---------------------------------------------------------------------------
+
+test("perf: kafkaConsumeStream", async () => {
+ const bench = new Bench({ name: "kafkaConsumeStream", time });
+
+ const MSG_COUNT = 10_000;
+
+ bench.add(`consume ${MSG_COUNT} messages`, async () => {
+ let eachMessageFn;
+ const consumerMock = {
+ _runResolve: null,
+ connect: async () => {},
+ disconnect: async () => {},
+ subscribe: async () => {},
+ stop: async () => {
+ if (consumerMock._runResolve) consumerMock._runResolve();
+ },
+ run: async ({ eachMessage }) => {
+ eachMessageFn = eachMessage;
+ return new Promise((resolve) => {
+ consumerMock._runResolve = resolve;
+ });
+ },
+ };
+
+ const stream = await kafkaConsumeStream(
+ { consumer: consumerMock, topics: "perf-topic" },
+ { highWaterMark: MSG_COUNT },
+ );
+
+ // Drive messages then stop
+ const delivery = (async () => {
+ for (let i = 0; i < MSG_COUNT; i++) {
+ await eachMessageFn({
+ topic: "perf-topic",
+ partition: 0,
+ message: {
+ offset: String(i),
+ key: `key-${i}`,
+ value: `value-${i}`,
+ headers: {},
+ timestamp: String(Date.now()),
+ },
+ });
+ }
+ await stream.stop();
+ })();
+
+ await streamToArray(stream);
+ await delivery;
+ });
+
+ bench.add(`consume ${MSG_COUNT} messages (highWaterMark 100)`, async () => {
+ let eachMessageFn;
+ const consumerMock = {
+ _runResolve: null,
+ connect: async () => {},
+ disconnect: async () => {},
+ subscribe: async () => {},
+ stop: async () => {
+ if (consumerMock._runResolve) consumerMock._runResolve();
+ },
+ run: async ({ eachMessage }) => {
+ eachMessageFn = eachMessage;
+ return new Promise((resolve) => {
+ consumerMock._runResolve = resolve;
+ });
+ },
+ };
+
+ const stream = await kafkaConsumeStream(
+ { consumer: consumerMock, topics: "perf-topic" },
+ { highWaterMark: 100 },
+ );
+
+ const delivery = (async () => {
+ for (let i = 0; i < MSG_COUNT; i++) {
+ await eachMessageFn({
+ topic: "perf-topic",
+ partition: 0,
+ message: {
+ offset: String(i),
+ key: `key-${i}`,
+ value: `value-${i}`,
+ headers: {},
+ timestamp: String(Date.now()),
+ },
+ });
+ }
+ await stream.stop();
+ })();
+
+ await streamToArray(stream);
+ await delivery;
+ });
+
+ await bench.run();
+ console.log(`\n${bench.name}`);
+ console.table(bench.table());
+});
diff --git a/packages/kafka/index.test.js b/packages/kafka/index.test.js
new file mode 100644
index 0000000..ae4eb1b
--- /dev/null
+++ b/packages/kafka/index.test.js
@@ -0,0 +1,1596 @@
+// Copyright 2026 will Farrell, and datastream contributors.
+// SPDX-License-Identifier: MIT
+import { deepStrictEqual, ok, rejects, strictEqual } from "node:assert";
+import test from "node:test";
+import { streamToArray } from "@datastream/core";
+
+import kafkaDefault, {
+ kafkaConnect,
+ kafkaConsumeStream,
+ kafkaProduceStream,
+} from "@datastream/kafka";
+
+// ---------------------------------------------------------------------------
+// Fake Kafka factory helpers
+// ---------------------------------------------------------------------------
+
+/** Build a simple fake kafkajs-like Kafka constructor. */
+const makeFakeKafka = ({
+ connectProducer = async () => {},
+ disconnectProducer = async () => {},
+ sendMessages = async () => {},
+ connectConsumer = async () => {},
+ disconnectConsumer = async () => {},
+ subscribe = async () => {},
+ // run: caller can override; default drives one message then resolves
+ run,
+} = {}) => {
+ const producerMock = {
+ connectCalled: 0,
+ disconnectCalled: 0,
+ sendArgs: [],
+ connect: async () => {
+ producerMock.connectCalled++;
+ return connectProducer();
+ },
+ disconnect: async () => {
+ producerMock.disconnectCalled++;
+ return disconnectProducer();
+ },
+ send: async (opts) => {
+ producerMock.sendArgs.push(opts);
+ return sendMessages(opts);
+ },
+ };
+
+ const consumerMock = {
+ connectCalled: 0,
+ disconnectCalled: 0,
+ subscribeCalls: [],
+ stopCalled: 0,
+ _runResolve: null,
+ connect: async () => {
+ consumerMock.connectCalled++;
+ return connectConsumer();
+ },
+ disconnect: async () => {
+ consumerMock.disconnectCalled++;
+ return disconnectConsumer();
+ },
+ subscribe: async (opts) => {
+ consumerMock.subscribeCalls.push(opts);
+ return subscribe(opts);
+ },
+ stop: async () => {
+ consumerMock.stopCalled++;
+ if (consumerMock._runResolve) consumerMock._runResolve();
+ },
+ run:
+ run ??
+ (async () => {
+ // Return a promise that resolves when stop() is called
+ return new Promise((resolve) => {
+ consumerMock._runResolve = resolve;
+ });
+ }),
+ };
+
+ const Kafka = function (opts) {
+ this.opts = opts;
+ this.producer = (opts) => {
+ producerMock.producerOpts = opts;
+ return producerMock;
+ };
+ this.consumer = (opts) => {
+ consumerMock.consumerOpts = opts;
+ return consumerMock;
+ };
+ };
+
+ return { Kafka, producerMock, consumerMock };
+};
+
+// ---------------------------------------------------------------------------
+// kafkaConnect
+// ---------------------------------------------------------------------------
+
+test("kafkaConnect: returns kafka, producer, consumer, disconnect", async () => {
+ const { Kafka, producerMock, consumerMock } = makeFakeKafka();
+ const result = await kafkaConnect({ groupId: "g1", Kafka });
+ ok(result.kafka, "has kafka");
+ ok(result.producer === producerMock, "has producer");
+ ok(result.consumer === consumerMock, "has consumer");
+ ok(typeof result.disconnect === "function", "has disconnect");
+});
+
+test("kafkaConnect: passes brokers/clientId/ssl/sasl to Kafka constructor", async () => {
+ let capturedOpts;
+ const FakeKafka = function (opts) {
+ capturedOpts = opts;
+ this.producer = () => ({
+ connect: async () => {},
+ disconnect: async () => {},
+ });
+ this.consumer = () => ({
+ connect: async () => {},
+ disconnect: async () => {},
+ });
+ };
+ await kafkaConnect({
+ brokers: ["b1"],
+ clientId: "cid",
+ ssl: true,
+ sasl: { mechanism: "plain" },
+ groupId: "g1",
+ Kafka: FakeKafka,
+ });
+ deepStrictEqual(capturedOpts.brokers, ["b1"]);
+ strictEqual(capturedOpts.clientId, "cid");
+ strictEqual(capturedOpts.ssl, true);
+ deepStrictEqual(capturedOpts.sasl, { mechanism: "plain" });
+});
+
+test("kafkaConnect: producer is null when producerOptions === false", async () => {
+ const { Kafka } = makeFakeKafka();
+ const result = await kafkaConnect({ producer: false, Kafka });
+ strictEqual(result.producer, null, "producer should be null");
+});
+
+test("kafkaConnect: consumer is null when groupId is not provided", async () => {
+ const { Kafka } = makeFakeKafka();
+ const result = await kafkaConnect({ Kafka });
+ strictEqual(result.consumer, null, "consumer should be null");
+});
+
+test("kafkaConnect: producer connects when producerOptions is truthy", async () => {
+ const { Kafka, producerMock } = makeFakeKafka();
+ await kafkaConnect({ Kafka });
+ strictEqual(producerMock.connectCalled, 1, "producer.connect called once");
+});
+
+test("kafkaConnect: consumer connects when groupId is provided", async () => {
+ const { Kafka, consumerMock } = makeFakeKafka();
+ await kafkaConnect({ groupId: "g1", Kafka });
+ strictEqual(consumerMock.connectCalled, 1, "consumer.connect called once");
+});
+
+test("kafkaConnect: producer not connected when producer === false", async () => {
+ const { Kafka, producerMock } = makeFakeKafka();
+ await kafkaConnect({ producer: false, Kafka });
+ strictEqual(producerMock.connectCalled, 0, "producer.connect not called");
+});
+
+test("kafkaConnect: consumer not connected when no groupId", async () => {
+ const { Kafka, consumerMock } = makeFakeKafka();
+ await kafkaConnect({ Kafka });
+ strictEqual(consumerMock.connectCalled, 0, "consumer.connect not called");
+});
+
+test("kafkaConnect: disconnect() calls producer.disconnect when producer exists", async () => {
+ const { Kafka, producerMock } = makeFakeKafka();
+ const conn = await kafkaConnect({ Kafka });
+ await conn.disconnect();
+ strictEqual(producerMock.disconnectCalled, 1);
+});
+
+test("kafkaConnect: disconnect() calls consumer.disconnect when consumer exists", async () => {
+ const { Kafka, consumerMock } = makeFakeKafka();
+ const conn = await kafkaConnect({ groupId: "g1", Kafka });
+ await conn.disconnect();
+ strictEqual(consumerMock.disconnectCalled, 1);
+});
+
+test("kafkaConnect: disconnect() does not call producer.disconnect when producer is null", async () => {
+ const { Kafka, producerMock } = makeFakeKafka();
+ const conn = await kafkaConnect({ producer: false, Kafka });
+ await conn.disconnect();
+ strictEqual(producerMock.disconnectCalled, 0);
+});
+
+test("kafkaConnect: disconnect() does not call consumer.disconnect when consumer is null", async () => {
+ const { Kafka, consumerMock } = makeFakeKafka();
+ const conn = await kafkaConnect({ Kafka });
+ await conn.disconnect();
+ strictEqual(consumerMock.disconnectCalled, 0);
+});
+
+test("kafkaConnect: producer connect error triggers teardown and rethrows", async () => {
+ const { Kafka, producerMock } = makeFakeKafka({
+ connectProducer: async () => {
+ throw new Error("producer connect failed");
+ },
+ });
+ await rejects(async () => kafkaConnect({ Kafka }), /producer connect failed/);
+ strictEqual(producerMock.disconnectCalled, 1);
+});
+
+test("kafkaConnect: consumer connect error triggers teardown and rethrows", async () => {
+ const { Kafka, producerMock, consumerMock } = makeFakeKafka({
+ connectConsumer: async () => {
+ throw new Error("consumer connect failed");
+ },
+ });
+ await rejects(
+ async () => kafkaConnect({ groupId: "g1", Kafka }),
+ /consumer connect failed/,
+ );
+ strictEqual(producerMock.disconnectCalled, 1);
+ strictEqual(consumerMock.disconnectCalled, 1);
+});
+
+test("kafkaConnect: passes consumerOptions alongside groupId", async () => {
+ const { Kafka, consumerMock } = makeFakeKafka();
+ await kafkaConnect({
+ groupId: "g1",
+ consumer: { sessionTimeout: 5000 },
+ Kafka,
+ });
+ deepStrictEqual(consumerMock.consumerOpts, {
+ groupId: "g1",
+ sessionTimeout: 5000,
+ });
+});
+
+test("kafkaConnect: default exports connect/produceStream/consumeStream", () => {
+ ok(typeof kafkaDefault.connect === "function");
+ ok(typeof kafkaDefault.produceStream === "function");
+ ok(typeof kafkaDefault.consumeStream === "function");
+});
+
+// ---------------------------------------------------------------------------
+// kafkaProduceStream: validation
+// ---------------------------------------------------------------------------
+
+test("kafkaProduceStream: throws when producer is missing", async () => {
+ await rejects(
+ async () => kafkaProduceStream({ topic: "t" }),
+ /kafkaProduceStream: producer required/,
+ );
+});
+
+test("kafkaProduceStream: throws TypeError when producer is missing", async () => {
+ await rejects(async () => kafkaProduceStream({ topic: "t" }), TypeError);
+});
+
+test("kafkaProduceStream: throws when topic is missing", async () => {
+ const { producerMock } = makeFakeKafka();
+ await rejects(
+ async () => kafkaProduceStream({ producer: producerMock }),
+ /kafkaProduceStream: topic required/,
+ );
+});
+
+test("kafkaProduceStream: throws TypeError when topic is missing", async () => {
+ const { producerMock } = makeFakeKafka();
+ await rejects(
+ async () => kafkaProduceStream({ producer: producerMock }),
+ TypeError,
+ );
+});
+
+test("kafkaProduceStream: throws when batchSize is 0", async () => {
+ const { producerMock } = makeFakeKafka();
+ await rejects(
+ async () =>
+ kafkaProduceStream({ producer: producerMock, topic: "t", batchSize: 0 }),
+ /kafkaProduceStream: batchSize must be >= 1/,
+ );
+});
+
+test("kafkaProduceStream: throws TypeError when batchSize < 1", async () => {
+ const { producerMock } = makeFakeKafka();
+ await rejects(
+ async () =>
+ kafkaProduceStream({ producer: producerMock, topic: "t", batchSize: 0 }),
+ TypeError,
+ );
+});
+
+test("kafkaProduceStream: accepts batchSize === 1 without throwing", async () => {
+ const { producerMock } = makeFakeKafka();
+ const stream = await kafkaProduceStream({
+ producer: producerMock,
+ topic: "t",
+ batchSize: 1,
+ });
+ ok(stream, "stream created");
+ stream.end();
+ await new Promise((resolve) => stream.on("finish", resolve));
+});
+
+// ---------------------------------------------------------------------------
+// kafkaProduceStream: normalizeMessage
+// ---------------------------------------------------------------------------
+
+test("kafkaProduceStream: sends string chunk wrapped as { value }", async () => {
+ const { producerMock } = makeFakeKafka();
+ const stream = await kafkaProduceStream({
+ producer: producerMock,
+ topic: "t",
+ });
+ stream.write("hello");
+ stream.end();
+ await new Promise((resolve) => stream.on("finish", resolve));
+ strictEqual(producerMock.sendArgs.length, 1);
+ deepStrictEqual(producerMock.sendArgs[0].messages[0], { value: "hello" });
+});
+
+test("kafkaProduceStream: sends Uint8Array chunk wrapped as { value }", async () => {
+ const { producerMock } = makeFakeKafka();
+ const stream = await kafkaProduceStream({
+ producer: producerMock,
+ topic: "t",
+ });
+ const buf = new Uint8Array([1, 2, 3]);
+ stream.write(buf);
+ stream.end();
+ await new Promise((resolve) => stream.on("finish", resolve));
+ strictEqual(producerMock.sendArgs.length, 1);
+ deepStrictEqual(producerMock.sendArgs[0].messages[0], { value: buf });
+});
+
+test("kafkaProduceStream: passes through { value, key, headers } object unchanged", async () => {
+ const { producerMock } = makeFakeKafka();
+ const stream = await kafkaProduceStream({
+ producer: producerMock,
+ topic: "t",
+ });
+ const msg = { value: "v", key: "k", headers: { h: "1" } };
+ stream.write(msg);
+ stream.end();
+ await new Promise((resolve) => stream.on("finish", resolve));
+ deepStrictEqual(producerMock.sendArgs[0].messages[0], msg);
+});
+
+test("kafkaProduceStream: emits error on invalid chunk (boolean false — not Uint8Array/string/object-with-value)", async () => {
+ const { producerMock } = makeFakeKafka();
+ const stream = await kafkaProduceStream({
+ producer: producerMock,
+ topic: "t",
+ });
+ const errorPromise = new Promise((resolve) => stream.once("error", resolve));
+ stream.write(false);
+ const err = await errorPromise;
+ ok(err instanceof TypeError, "error is TypeError");
+ ok(err.message.includes("boolean"), "error message includes actual type");
+});
+
+test("kafkaProduceStream: error message includes actual type for non-null invalid chunk", async () => {
+ const { producerMock } = makeFakeKafka();
+ const stream = await kafkaProduceStream({
+ producer: producerMock,
+ topic: "t",
+ });
+ const errorPromise = new Promise((resolve) => stream.once("error", resolve));
+ stream.write(42);
+ const err = await errorPromise;
+ ok(err.message.includes("number"), "error message includes 'number'");
+});
+
+// ---------------------------------------------------------------------------
+// kafkaProduceStream: batching
+// ---------------------------------------------------------------------------
+
+test("kafkaProduceStream: batches messages and flushes at batchSize", async () => {
+ const { producerMock } = makeFakeKafka();
+ const stream = await kafkaProduceStream({
+ producer: producerMock,
+ topic: "t",
+ batchSize: 3,
+ });
+ for (let i = 0; i < 6; i++) stream.write(`msg${i}`);
+ stream.end();
+ await new Promise((resolve) => stream.on("finish", resolve));
+ // 2 batches of 3
+ strictEqual(producerMock.sendArgs.length, 2);
+ strictEqual(producerMock.sendArgs[0].messages.length, 3);
+ strictEqual(producerMock.sendArgs[1].messages.length, 3);
+});
+
+test("kafkaProduceStream: partial batch flushed on end", async () => {
+ const { producerMock } = makeFakeKafka();
+ const stream = await kafkaProduceStream({
+ producer: producerMock,
+ topic: "t",
+ batchSize: 10,
+ });
+ stream.write("a");
+ stream.write("b");
+ stream.end();
+ await new Promise((resolve) => stream.on("finish", resolve));
+ strictEqual(producerMock.sendArgs.length, 1);
+ strictEqual(producerMock.sendArgs[0].messages.length, 2);
+});
+
+test("kafkaProduceStream: empty stream sends no messages", async () => {
+ const { producerMock } = makeFakeKafka();
+ const stream = await kafkaProduceStream({
+ producer: producerMock,
+ topic: "t",
+ });
+ stream.end();
+ await new Promise((resolve) => stream.on("finish", resolve));
+ strictEqual(producerMock.sendArgs.length, 0);
+});
+
+test("kafkaProduceStream: sends with correct topic", async () => {
+ const { producerMock } = makeFakeKafka();
+ const stream = await kafkaProduceStream({
+ producer: producerMock,
+ topic: "my-topic",
+ });
+ stream.write("msg");
+ stream.end();
+ await new Promise((resolve) => stream.on("finish", resolve));
+ strictEqual(producerMock.sendArgs[0].topic, "my-topic");
+});
+
+test("kafkaProduceStream: sends with acks default -1", async () => {
+ const { producerMock } = makeFakeKafka();
+ const stream = await kafkaProduceStream({
+ producer: producerMock,
+ topic: "t",
+ });
+ stream.write("msg");
+ stream.end();
+ await new Promise((resolve) => stream.on("finish", resolve));
+ strictEqual(producerMock.sendArgs[0].acks, -1);
+});
+
+test("kafkaProduceStream: sends with custom acks value", async () => {
+ const { producerMock } = makeFakeKafka();
+ const stream = await kafkaProduceStream({
+ producer: producerMock,
+ topic: "t",
+ acks: 1,
+ });
+ stream.write("msg");
+ stream.end();
+ await new Promise((resolve) => stream.on("finish", resolve));
+ strictEqual(producerMock.sendArgs[0].acks, 1);
+});
+
+test("kafkaProduceStream: forwards compression to producer.send", async () => {
+ const { producerMock } = makeFakeKafka();
+ const stream = await kafkaProduceStream({
+ producer: producerMock,
+ topic: "t",
+ compression: 2,
+ });
+ stream.write("msg");
+ stream.end();
+ await new Promise((resolve) => stream.on("finish", resolve));
+ strictEqual(producerMock.sendArgs[0].compression, 2);
+});
+
+test("kafkaProduceStream: forwards timeout to producer.send", async () => {
+ const { producerMock } = makeFakeKafka();
+ const stream = await kafkaProduceStream({
+ producer: producerMock,
+ topic: "t",
+ timeout: 5000,
+ });
+ stream.write("msg");
+ stream.end();
+ await new Promise((resolve) => stream.on("finish", resolve));
+ strictEqual(producerMock.sendArgs[0].timeout, 5000);
+});
+
+// ---------------------------------------------------------------------------
+// kafkaProduceStream: send error attaches failedMessages
+// ---------------------------------------------------------------------------
+
+test("kafkaProduceStream: send error attaches failedMessages", async () => {
+ const sendErr = new Error("send failed");
+ const { producerMock } = makeFakeKafka({
+ sendMessages: async () => {
+ throw sendErr;
+ },
+ });
+ const stream = await kafkaProduceStream({
+ producer: producerMock,
+ topic: "t",
+ });
+ const errPromise = new Promise((resolve) => stream.once("error", resolve));
+ stream.write("msg");
+ stream.end();
+ const err = await errPromise;
+ ok(Array.isArray(err.failedMessages), "failedMessages is array");
+ strictEqual(err.failedMessages.length, 1);
+ strictEqual(err.failedMessages[0].value, "msg");
+});
+
+// ---------------------------------------------------------------------------
+// kafkaProduceStream: destroy with buffered batch
+// ---------------------------------------------------------------------------
+
+test("kafkaProduceStream: destroy with buffered batch attaches failedMessages to error", async () => {
+ const { producerMock } = makeFakeKafka();
+ const stream = await kafkaProduceStream({
+ producer: producerMock,
+ topic: "t",
+ batchSize: 100,
+ });
+ const errPromise = new Promise((resolve) => stream.once("error", resolve));
+ // Await both writes so they land in the batch before destroy
+ const w1Done = new Promise((resolve) => {
+ stream.write("msg1", resolve);
+ });
+ const w2Done = new Promise((resolve) => {
+ stream.write("msg2", resolve);
+ });
+ await w1Done;
+ await w2Done;
+ stream.destroy();
+ const err = await errPromise;
+ ok(
+ err.message.includes("destroyed with a buffered batch"),
+ `expected destroy error, got: ${err.message}`,
+ );
+ ok(Array.isArray(err.failedMessages), "failedMessages is array");
+ strictEqual(err.failedMessages.length, 2);
+});
+
+test("kafkaProduceStream: destroy with existing error attaches failedMessages", async () => {
+ const { producerMock } = makeFakeKafka();
+ const stream = await kafkaProduceStream({
+ producer: producerMock,
+ topic: "t",
+ batchSize: 100,
+ });
+ const errPromise = new Promise((resolve) => stream.once("error", resolve));
+ // Await write so msg lands in batch before destroy
+ const wDone = new Promise((resolve) => {
+ stream.write("msg", resolve);
+ });
+ await wDone;
+ const existingErr = new Error("existing error");
+ stream.destroy(existingErr);
+ const err = await errPromise;
+ strictEqual(err.message, "existing error");
+ ok(Array.isArray(err.failedMessages));
+ strictEqual(err.failedMessages.length, 1);
+});
+
+test("kafkaProduceStream: destroy with empty batch does not set failedMessages", async () => {
+ const { producerMock } = makeFakeKafka();
+ const stream = await kafkaProduceStream({
+ producer: producerMock,
+ topic: "t",
+ batchSize: 100,
+ });
+ // No writes — batch is empty
+ const closePromise = new Promise((resolve) => stream.on("close", resolve));
+ stream.destroy();
+ await closePromise;
+ // No error should have been emitted with failedMessages
+ // since batch was empty we never set failedMessages
+});
+
+// ---------------------------------------------------------------------------
+// kafkaConsumeStream: validation
+// ---------------------------------------------------------------------------
+
+test("kafkaConsumeStream: throws when consumer is missing", async () => {
+ await rejects(
+ async () => kafkaConsumeStream({ topics: "t" }),
+ /kafkaConsumeStream: consumer required/,
+ );
+});
+
+test("kafkaConsumeStream: throws TypeError when consumer is missing", async () => {
+ await rejects(async () => kafkaConsumeStream({ topics: "t" }), TypeError);
+});
+
+test("kafkaConsumeStream: throws when topics is missing", async () => {
+ const { consumerMock } = makeFakeKafka();
+ await rejects(
+ async () => kafkaConsumeStream({ consumer: consumerMock }),
+ /kafkaConsumeStream: topics required/,
+ );
+});
+
+test("kafkaConsumeStream: throws TypeError when topics is missing", async () => {
+ const { consumerMock } = makeFakeKafka();
+ await rejects(
+ async () => kafkaConsumeStream({ consumer: consumerMock }),
+ TypeError,
+ );
+});
+
+test("kafkaConsumeStream: throws when topics is an empty array", async () => {
+ const { consumerMock } = makeFakeKafka();
+ await rejects(
+ async () => kafkaConsumeStream({ consumer: consumerMock, topics: [] }),
+ /kafkaConsumeStream: topics required/,
+ );
+});
+
+// ---------------------------------------------------------------------------
+// kafkaConsumeStream: subscribe
+// ---------------------------------------------------------------------------
+
+test("kafkaConsumeStream: subscribes to a single string topic", async () => {
+ const { consumerMock } = makeFakeKafka();
+ const stream = await kafkaConsumeStream({
+ consumer: consumerMock,
+ topics: "my-topic",
+ });
+ // Subscribe happens during stream creation; assert then clean up
+ deepStrictEqual(consumerMock.subscribeCalls, [
+ { topic: "my-topic", fromBeginning: false },
+ ]);
+ const closePromise = new Promise((r) => stream.once("close", r));
+ stream.destroy();
+ await closePromise;
+});
+
+test("kafkaConsumeStream: subscribes to multiple topics in array", async () => {
+ const { consumerMock } = makeFakeKafka();
+ const stream = await kafkaConsumeStream({
+ consumer: consumerMock,
+ topics: ["topic-a", "topic-b"],
+ });
+ deepStrictEqual(consumerMock.subscribeCalls, [
+ { topic: "topic-a", fromBeginning: false },
+ { topic: "topic-b", fromBeginning: false },
+ ]);
+ const closePromise = new Promise((r) => stream.once("close", r));
+ stream.destroy();
+ await closePromise;
+});
+
+test("kafkaConsumeStream: passes fromBeginning=true to subscribe", async () => {
+ const { consumerMock } = makeFakeKafka();
+ const stream = await kafkaConsumeStream({
+ consumer: consumerMock,
+ topics: "t",
+ fromBeginning: true,
+ });
+ strictEqual(consumerMock.subscribeCalls[0].fromBeginning, true);
+ const closePromise = new Promise((r) => stream.once("close", r));
+ stream.destroy();
+ await closePromise;
+});
+
+// ---------------------------------------------------------------------------
+// kafkaConsumeStream: message delivery
+// ---------------------------------------------------------------------------
+
+/** Helper: build a fake consumer that delivers messages via run(). */
+const makeMessageConsumer = (_messages) => {
+ const consumerMock = {
+ subscribeCalls: [],
+ stopCalled: 0,
+ _eachMessage: null,
+ _runResolve: null,
+ connect: async () => {},
+ disconnect: async () => {},
+ subscribe: async (opts) => {
+ consumerMock.subscribeCalls.push(opts);
+ },
+ stop: async () => {
+ consumerMock.stopCalled++;
+ if (consumerMock._runResolve) consumerMock._runResolve();
+ },
+ run: async ({ eachMessage }) => {
+ consumerMock._eachMessage = eachMessage;
+ return new Promise((resolve) => {
+ consumerMock._runResolve = resolve;
+ });
+ },
+ };
+ return consumerMock;
+};
+
+test("kafkaConsumeStream: delivers messages from eachMessage to stream", async () => {
+ const msgs = [
+ {
+ topic: "t",
+ partition: 0,
+ message: {
+ offset: "0",
+ key: "k",
+ value: "v",
+ headers: {},
+ timestamp: "0",
+ },
+ },
+ {
+ topic: "t",
+ partition: 0,
+ message: {
+ offset: "1",
+ key: "k2",
+ value: "v2",
+ headers: {},
+ timestamp: "1",
+ },
+ },
+ ];
+ const consumer = makeMessageConsumer(msgs);
+ const stream = await kafkaConsumeStream({ consumer, topics: "t" });
+
+ // Deliver messages then stop
+ setTimeout(async () => {
+ for (const m of msgs) await consumer._eachMessage(m);
+ await stream.stop();
+ }, 0);
+
+ const received = await streamToArray(stream);
+ strictEqual(received.length, 2);
+ strictEqual(received[0].value, "v");
+ strictEqual(received[1].value, "v2");
+});
+
+test("kafkaConsumeStream: message object includes topic, partition, offset, key, value, headers, timestamp", async () => {
+ const consumer = makeMessageConsumer([]);
+ const stream = await kafkaConsumeStream({ consumer, topics: "t" });
+
+ setTimeout(async () => {
+ await consumer._eachMessage({
+ topic: "my-topic",
+ partition: 3,
+ message: {
+ offset: "42",
+ key: "mykey",
+ value: "myval",
+ headers: { x: "1" },
+ timestamp: "9999",
+ },
+ });
+ await stream.stop();
+ }, 0);
+
+ const [msg] = await streamToArray(stream);
+ strictEqual(msg.topic, "my-topic");
+ strictEqual(msg.partition, 3);
+ strictEqual(msg.offset, "42");
+ strictEqual(msg.key, "mykey");
+ strictEqual(msg.value, "myval");
+ deepStrictEqual(msg.headers, { x: "1" });
+ strictEqual(msg.timestamp, "9999");
+});
+
+test("kafkaConsumeStream: stop() ends the readable stream", async () => {
+ const consumer = makeMessageConsumer([]);
+ const stream = await kafkaConsumeStream({ consumer, topics: "t" });
+
+ const endedPromise = new Promise((resolve) => stream.once("end", resolve));
+ stream.resume();
+ setTimeout(() => stream.stop(), 0);
+ await endedPromise;
+});
+
+test("kafkaConsumeStream: stop() is idempotent (calling twice doesn't call consumer.stop twice)", async () => {
+ const consumer = makeMessageConsumer([]);
+ const stream = await kafkaConsumeStream({ consumer, topics: "t" });
+
+ await stream.stop();
+ await stream.stop(); // second call should be no-op
+ strictEqual(consumer.stopCalled, 1, "consumer.stop called only once");
+});
+
+test("kafkaConsumeStream: eachMessage after stopped is a no-op (does not push)", async () => {
+ const consumer = makeMessageConsumer([]);
+ const stream = await kafkaConsumeStream({ consumer, topics: "t" });
+
+ const receivedChunks = [];
+ stream.on("data", (chunk) => receivedChunks.push(chunk));
+
+ await stream.stop();
+ // After stop, eachMessage should return without pushing
+ await consumer._eachMessage({
+ topic: "t",
+ partition: 0,
+ message: {
+ offset: "0",
+ key: null,
+ value: "dropped",
+ headers: {},
+ timestamp: "0",
+ },
+ });
+
+ // Give event loop a tick to see if anything was pushed
+ await new Promise((resolve) => setTimeout(resolve, 10));
+ strictEqual(receivedChunks.length, 0, "no chunks after stop");
+});
+
+test("kafkaConsumeStream: passes autoCommit to consumer.run", async () => {
+ let capturedOpts;
+ const consumer = {
+ connect: async () => {},
+ disconnect: async () => {},
+ subscribe: async () => {},
+ stop: async () => {
+ if (consumer._runResolve) consumer._runResolve();
+ },
+ run: async (opts) => {
+ capturedOpts = opts;
+ return new Promise((resolve) => {
+ consumer._runResolve = resolve;
+ });
+ },
+ };
+ const stream = await kafkaConsumeStream({
+ consumer,
+ topics: "t",
+ autoCommit: false,
+ });
+ await stream.stop();
+ strictEqual(capturedOpts.autoCommit, false);
+ stream.destroy();
+});
+
+test("kafkaConsumeStream: passes partitionsConsumedConcurrently to consumer.run", async () => {
+ let capturedOpts;
+ const consumer = {
+ connect: async () => {},
+ disconnect: async () => {},
+ subscribe: async () => {},
+ stop: async () => {
+ if (consumer._runResolve) consumer._runResolve();
+ },
+ run: async (opts) => {
+ capturedOpts = opts;
+ return new Promise((resolve) => {
+ consumer._runResolve = resolve;
+ });
+ },
+ };
+ const stream = await kafkaConsumeStream({
+ consumer,
+ topics: "t",
+ partitionsConsumedConcurrently: 4,
+ });
+ await stream.stop();
+ strictEqual(capturedOpts.partitionsConsumedConcurrently, 4);
+ stream.destroy();
+});
+
+// ---------------------------------------------------------------------------
+// kafkaConsumeStream: abort signal
+// ---------------------------------------------------------------------------
+
+test("kafkaConsumeStream: already-aborted signal calls stop immediately", async () => {
+ const consumer = makeMessageConsumer([]);
+ const ac = new AbortController();
+ ac.abort();
+
+ const stream = await kafkaConsumeStream({
+ consumer,
+ topics: "t",
+ signal: ac.signal,
+ });
+ // Stream should be ended because signal was already aborted
+ const endedPromise = new Promise((resolve) => {
+ if (stream.readableEnded) return resolve();
+ stream.once("end", resolve);
+ });
+ stream.resume(); // drain to trigger end event
+ await endedPromise;
+});
+
+test("kafkaConsumeStream: abort signal triggers stop", async () => {
+ const consumer = makeMessageConsumer([]);
+ const ac = new AbortController();
+
+ const stream = await kafkaConsumeStream({
+ consumer,
+ topics: "t",
+ signal: ac.signal,
+ });
+ const endedPromise = new Promise((resolve) => stream.once("end", resolve));
+ stream.resume(); // start flowing
+ ac.abort();
+ await endedPromise;
+ strictEqual(consumer.stopCalled, 1);
+});
+
+test("kafkaConsumeStream: destroy() calls consumer.stop", async () => {
+ const consumer = makeMessageConsumer([]);
+ const stream = await kafkaConsumeStream({ consumer, topics: "t" });
+
+ const closePromise = new Promise((resolve) => stream.once("close", resolve));
+ stream.destroy();
+ await closePromise;
+ strictEqual(consumer.stopCalled, 1);
+});
+
+test("kafkaConsumeStream: destroy() removes abort listener (signal guard)", async () => {
+ const consumer = makeMessageConsumer([]);
+ const ac = new AbortController();
+
+ const stream = await kafkaConsumeStream({
+ consumer,
+ topics: "t",
+ signal: ac.signal,
+ });
+ const closePromise = new Promise((resolve) => stream.once("close", resolve));
+ stream.destroy();
+ await closePromise;
+
+ // Aborting after destroy should not call consumer.stop a second time
+ ac.abort();
+ await new Promise((resolve) => setTimeout(resolve, 10));
+ strictEqual(consumer.stopCalled, 1, "consumer.stop called only once");
+});
+
+test("kafkaConsumeStream: stop() removes abort listener so abort after stop is a no-op", async () => {
+ const consumer = makeMessageConsumer([]);
+ const ac = new AbortController();
+
+ const stream = await kafkaConsumeStream({
+ consumer,
+ topics: "t",
+ signal: ac.signal,
+ });
+ await stream.stop();
+
+ // Aborting after stop should not call consumer.stop again
+ ac.abort();
+ await new Promise((resolve) => setTimeout(resolve, 10));
+ strictEqual(consumer.stopCalled, 1);
+});
+
+// ---------------------------------------------------------------------------
+// kafkaConsumeStream: highWaterMark option
+// ---------------------------------------------------------------------------
+
+test("kafkaConsumeStream: respects highWaterMark streamOption", async () => {
+ const consumer = makeMessageConsumer([]);
+ const stream = await kafkaConsumeStream(
+ { consumer, topics: "t" },
+ { highWaterMark: 5 },
+ );
+ strictEqual(stream.readableHighWaterMark, 5);
+ await stream.stop();
+ stream.destroy();
+});
+
+// ---------------------------------------------------------------------------
+// kafkaConsumeStream: backpressure (wantsMore === false triggers waitForRead)
+// ---------------------------------------------------------------------------
+
+test("kafkaConsumeStream: backpressure suspends eachMessage until _read is called", async () => {
+ const consumer = makeMessageConsumer([]);
+ // Use a very small HWM so backpressure kicks in quickly
+ const stream = await kafkaConsumeStream(
+ { consumer, topics: "t" },
+ { highWaterMark: 1 },
+ );
+
+ let msg2Sent = false;
+ const deliveryDone = (async () => {
+ // Send first message - should go through
+ await consumer._eachMessage({
+ topic: "t",
+ partition: 0,
+ message: {
+ offset: "0",
+ key: null,
+ value: "v1",
+ headers: {},
+ timestamp: "0",
+ },
+ });
+ // Send second message - may block until stream reads first
+ await consumer._eachMessage({
+ topic: "t",
+ partition: 0,
+ message: {
+ offset: "1",
+ key: null,
+ value: "v2",
+ headers: {},
+ timestamp: "1",
+ },
+ });
+ msg2Sent = true;
+ await stream.stop();
+ })();
+
+ const received = await streamToArray(stream);
+ await deliveryDone;
+ ok(msg2Sent, "second message was eventually delivered");
+ strictEqual(received.length, 2);
+});
+
+// ---------------------------------------------------------------------------
+// kafkaConsumeStream: stopConsumerOnce memoization
+// ---------------------------------------------------------------------------
+
+test("kafkaConsumeStream: stopConsumerOnce is memoized (stop + destroy only calls consumer.stop once)", async () => {
+ const consumer = makeMessageConsumer([]);
+ const stream = await kafkaConsumeStream({ consumer, topics: "t" });
+
+ const closePromise = new Promise((resolve) => stream.once("close", resolve));
+ // Call stop() then destroy() — both trigger stopConsumerOnce
+ await stream.stop();
+ stream.destroy();
+ await closePromise;
+
+ strictEqual(consumer.stopCalled, 1, "consumer.stop called exactly once");
+});
+
+// ---------------------------------------------------------------------------
+// kafkaConnect: producerOptions passed to kafka.producer()
+// ---------------------------------------------------------------------------
+
+test("kafkaConnect: producerOptions are passed through to kafka.producer()", async () => {
+ let capturedProducerOpts;
+ const FakeKafka = function () {
+ this.producer = (opts) => {
+ capturedProducerOpts = opts;
+ return { connect: async () => {}, disconnect: async () => {} };
+ };
+ this.consumer = () => ({
+ connect: async () => {},
+ disconnect: async () => {},
+ });
+ };
+ const producerOptions = { transactionalId: "tx-1", idempotent: true };
+ await kafkaConnect({ producer: producerOptions, Kafka: FakeKafka });
+ deepStrictEqual(capturedProducerOpts, producerOptions);
+});
+
+test("kafkaConnect: producerOptions ?? {} default passes empty object to kafka.producer()", async () => {
+ let capturedProducerOpts;
+ const FakeKafka = function () {
+ this.producer = (opts) => {
+ capturedProducerOpts = opts;
+ return { connect: async () => {}, disconnect: async () => {} };
+ };
+ this.consumer = () => ({
+ connect: async () => {},
+ disconnect: async () => {},
+ });
+ };
+ // No producerOptions provided — should default to {}
+ await kafkaConnect({ Kafka: FakeKafka });
+ deepStrictEqual(capturedProducerOpts, {});
+});
+
+// ---------------------------------------------------------------------------
+// kafkaConnect: optional chaining in error teardown
+// ---------------------------------------------------------------------------
+
+test("kafkaConnect: consumer connect error with producer===false does not throw in teardown", async () => {
+ // producer is null; in the catch block, producer?.disconnect() must NOT throw
+ const FakeKafka = function () {
+ this.producer = () => ({
+ connect: async () => {},
+ disconnect: async () => {},
+ });
+ this.consumer = () => ({
+ connect: async () => {
+ throw new Error("consumer connect failed");
+ },
+ disconnect: async () => {},
+ });
+ };
+ // producer: false => producer is null => in catch block producer?.disconnect() is safe
+ await rejects(
+ async () =>
+ kafkaConnect({ producer: false, groupId: "g1", Kafka: FakeKafka }),
+ /consumer connect failed/,
+ "should rethrow consumer connect error",
+ );
+});
+
+// ---------------------------------------------------------------------------
+// kafkaProduceStream: null chunk error message specifics
+// ---------------------------------------------------------------------------
+
+test("kafkaProduceStream: error message includes type 'number' for numeric chunk", async () => {
+ const { producerMock } = makeFakeKafka();
+ const stream = await kafkaProduceStream({
+ producer: producerMock,
+ topic: "t",
+ });
+ const errPromise = new Promise((resolve) => stream.once("error", resolve));
+ stream.write(123);
+ const err = await errPromise;
+ ok(
+ err.message.includes("number"),
+ "error message includes 'number' (not empty string)",
+ );
+ ok(err.message.length > 10, "error message is not empty");
+});
+
+test("kafkaProduceStream: normalizeMessage: object without value property throws TypeError with type 'object'", async () => {
+ const { producerMock } = makeFakeKafka();
+ const stream = await kafkaProduceStream({
+ producer: producerMock,
+ topic: "t",
+ });
+ const errPromise = new Promise((resolve) => stream.once("error", resolve));
+ stream.write({ noValue: "here" });
+ const err = await errPromise;
+ ok(err instanceof TypeError, "should be TypeError");
+ ok(err.message.includes("object"), "message includes type 'object'");
+});
+
+// ---------------------------------------------------------------------------
+// kafkaProduceStream: batch reset is correct after flush
+// ---------------------------------------------------------------------------
+
+test("kafkaProduceStream: after batch flush, next messages go into a fresh batch", async () => {
+ const { producerMock } = makeFakeKafka();
+ const stream = await kafkaProduceStream({
+ producer: producerMock,
+ topic: "t",
+ batchSize: 2,
+ });
+ // 4 messages = 2 full batches
+ stream.write("a");
+ stream.write("b");
+ stream.write("c");
+ stream.write("d");
+ stream.end();
+ await new Promise((resolve) => stream.on("finish", resolve));
+ strictEqual(producerMock.sendArgs.length, 2, "two separate flushes");
+ // First batch: a, b
+ strictEqual(producerMock.sendArgs[0].messages[0].value, "a");
+ strictEqual(producerMock.sendArgs[0].messages[1].value, "b");
+ // Second batch: c, d (not ["Stryker was here", "c", "d"])
+ strictEqual(producerMock.sendArgs[1].messages.length, 2);
+ strictEqual(producerMock.sendArgs[1].messages[0].value, "c");
+ strictEqual(producerMock.sendArgs[1].messages[1].value, "d");
+});
+
+// ---------------------------------------------------------------------------
+// kafkaConsumeStream: autoCommit default true is passed to consumer.run
+// ---------------------------------------------------------------------------
+
+test("kafkaConsumeStream: autoCommit defaults to true and is passed to consumer.run", async () => {
+ let capturedOpts;
+ const consumer = {
+ connect: async () => {},
+ disconnect: async () => {},
+ subscribe: async () => {},
+ stop: async () => {
+ if (consumer._runResolve) consumer._runResolve();
+ },
+ run: async (opts) => {
+ capturedOpts = opts;
+ return new Promise((resolve) => {
+ consumer._runResolve = resolve;
+ });
+ },
+ };
+ const stream = await kafkaConsumeStream({ consumer, topics: "t" });
+ // Default autoCommit should be true
+ strictEqual(capturedOpts.autoCommit, true);
+ const closePromise = new Promise((r) => stream.once("close", r));
+ stream.destroy();
+ await closePromise;
+});
+
+// ---------------------------------------------------------------------------
+// kafkaConsumeStream: destroy sets stopped=true so eachMessage is a no-op
+// ---------------------------------------------------------------------------
+
+test("kafkaConsumeStream: destroy() sets stopped=true so eachMessage after destroy is a no-op", async () => {
+ const consumer = makeMessageConsumer([]);
+ const stream = await kafkaConsumeStream({ consumer, topics: "t" });
+
+ const closePromise = new Promise((resolve) => stream.once("close", resolve));
+ stream.destroy();
+ await closePromise;
+
+ // Try delivering a message after destroy — should be a no-op (stopped===true)
+ if (consumer._eachMessage) {
+ const _chunksPushed = [];
+ // The stream is already destroyed so push won't add data; just verify no throw
+ await consumer._eachMessage({
+ topic: "t",
+ partition: 0,
+ message: {
+ offset: "99",
+ key: null,
+ value: "late",
+ headers: {},
+ timestamp: "0",
+ },
+ });
+ }
+ await new Promise((resolve) => setTimeout(resolve, 10));
+});
+
+// ---------------------------------------------------------------------------
+// kafkaConsumeStream: abort event listener uses "abort" event name
+// ---------------------------------------------------------------------------
+
+test("kafkaConsumeStream: abort event listener is on 'abort' event (not '')", async () => {
+ const consumer = makeMessageConsumer([]);
+ const listeners = [];
+ const mockSignal = {
+ aborted: false,
+ addEventListener: (event, fn) => {
+ listeners.push({ event, fn });
+ },
+ removeEventListener: (event, fn) => {
+ const idx = listeners.findIndex((l) => l.event === event && l.fn === fn);
+ if (idx !== -1) listeners.splice(idx, 1);
+ },
+ };
+
+ const stream = await kafkaConsumeStream({
+ consumer,
+ topics: "t",
+ signal: mockSignal,
+ });
+ // Listener was registered on 'abort' event
+ strictEqual(listeners.length, 1, "one listener added");
+ strictEqual(listeners[0].event, "abort", "listener is on 'abort' event");
+
+ // stop() removes it
+ await stream.stop();
+ strictEqual(listeners.length, 0, "listener removed after stop");
+ stream.destroy();
+});
+
+test("kafkaConsumeStream: destroy() removes 'abort' listener (correct event name)", async () => {
+ const consumer = makeMessageConsumer([]);
+ const listeners = [];
+ const mockSignal = {
+ aborted: false,
+ addEventListener: (event, fn) => {
+ listeners.push({ event, fn });
+ },
+ removeEventListener: (event, fn) => {
+ const idx = listeners.findIndex((l) => l.event === event && l.fn === fn);
+ if (idx !== -1) listeners.splice(idx, 1);
+ },
+ };
+
+ const stream = await kafkaConsumeStream({
+ consumer,
+ topics: "t",
+ signal: mockSignal,
+ });
+ strictEqual(listeners.length, 1);
+
+ const closePromise = new Promise((resolve) => stream.once("close", resolve));
+ stream.destroy();
+ await closePromise;
+
+ strictEqual(listeners.length, 0, "listener removed on destroy");
+});
+
+// ---------------------------------------------------------------------------
+// kafkaConsumeStream: stop() correctly handles already-stopped idempotency
+// ---------------------------------------------------------------------------
+
+test("kafkaConsumeStream: stop() when not stopped pushes null to end stream", async () => {
+ const consumer = makeMessageConsumer([]);
+ const stream = await kafkaConsumeStream({ consumer, topics: "t" });
+ stream.resume();
+
+ const endPromise = new Promise((resolve) => stream.once("end", resolve));
+ await stream.stop();
+ await endPromise;
+ // Second call is no-op
+ await stream.stop();
+ strictEqual(consumer.stopCalled, 1);
+});
+
+// ---------------------------------------------------------------------------
+// kafkaConsumeStream: wantsMore backpressure - eachMessage completes when wantsMore=true
+// ---------------------------------------------------------------------------
+
+test("kafkaConsumeStream: wantsMore=true means eachMessage does NOT call waitForRead", async () => {
+ // With large HWM, push() returns true (wantsMore), so waitForRead is NOT called
+ const consumer = makeMessageConsumer([]);
+ const stream = await kafkaConsumeStream(
+ { consumer, topics: "t" },
+ { highWaterMark: 100 },
+ );
+
+ let delivered = false;
+ const delivery = (async () => {
+ await consumer._eachMessage({
+ topic: "t",
+ partition: 0,
+ message: {
+ offset: "0",
+ key: null,
+ value: "v",
+ headers: {},
+ timestamp: "0",
+ },
+ });
+ delivered = true;
+ })();
+
+ // Give a tick; eachMessage should complete without blocking (no waitForRead)
+ await new Promise((resolve) => setTimeout(resolve, 5));
+ ok(delivered, "eachMessage completed without waiting for read");
+
+ await stream.stop();
+ await delivery;
+ stream.destroy();
+});
+
+// ---------------------------------------------------------------------------
+// kafkaConsumeStream: signal.aborted check prevents double-stop
+// ---------------------------------------------------------------------------
+
+test("kafkaConsumeStream: non-aborted signal does NOT call stop immediately", async () => {
+ const consumer = makeMessageConsumer([]);
+ const ac = new AbortController();
+
+ const stream = await kafkaConsumeStream({
+ consumer,
+ topics: "t",
+ signal: ac.signal,
+ });
+ // Consumer.stop should NOT have been called yet (signal is not aborted)
+ strictEqual(consumer.stopCalled, 0, "stop not called for non-aborted signal");
+
+ await stream.stop();
+ stream.destroy();
+});
+
+test("kafkaConsumeStream: non-aborted signal registers abort listener (not stop immediately)", async () => {
+ const consumer = makeMessageConsumer([]);
+ const listeners = [];
+ const mockSignal = {
+ aborted: false,
+ addEventListener: (event, fn) => listeners.push({ event, fn }),
+ removeEventListener: (_event, fn) => {
+ const idx = listeners.findIndex((l) => l.fn === fn);
+ if (idx !== -1) listeners.splice(idx, 1);
+ },
+ };
+
+ const stream = await kafkaConsumeStream({
+ consumer,
+ topics: "t",
+ signal: mockSignal,
+ });
+ // Should have added listener (not called stop)
+ strictEqual(consumer.stopCalled, 0);
+ strictEqual(listeners.length, 1);
+ strictEqual(listeners[0].event, "abort");
+ await stream.stop();
+ stream.destroy();
+});
+
+// ---------------------------------------------------------------------------
+// kafkaConnect: dynamic import fallback (Kafka not injected)
+// ---------------------------------------------------------------------------
+
+test("kafkaConnect: uses dynamic import when Kafka is not provided (no connect)", async () => {
+ // Call without injecting Kafka — exercises the `Kafka ??= (await import('kafkajs')).Kafka` branch.
+ // Pass producer:false and omit groupId so neither producer nor consumer is
+ // created, meaning connect() is never called and no broker is needed.
+ const result = await kafkaConnect({ producer: false });
+ strictEqual(result.producer, null, "producer is null");
+ strictEqual(result.consumer, null, "consumer is null");
+ ok(result.kafka, "kafka instance created via dynamic import");
+ ok(typeof result.disconnect === "function");
+ await result.disconnect();
+});
+
+// ---------------------------------------------------------------------------
+// kafkaConnect: disconnect() throws during error teardown (catch handlers)
+// ---------------------------------------------------------------------------
+
+test("kafkaConnect: producer.disconnect() throwing in catch block is swallowed", async () => {
+ const { Kafka } = makeFakeKafka({
+ connectProducer: async () => {
+ throw new Error("producer connect failed");
+ },
+ disconnectProducer: async () => {
+ throw new Error("producer disconnect also failed");
+ },
+ });
+ // Should still rethrow the original connect error, not the disconnect error
+ await rejects(async () => kafkaConnect({ Kafka }), /producer connect failed/);
+});
+
+test("kafkaConnect: consumer.disconnect() throwing in catch block is swallowed", async () => {
+ const { Kafka } = makeFakeKafka({
+ connectConsumer: async () => {
+ throw new Error("consumer connect failed");
+ },
+ disconnectConsumer: async () => {
+ throw new Error("consumer disconnect also failed");
+ },
+ });
+ // Should rethrow the consumer connect error despite disconnect throwing
+ await rejects(
+ async () => kafkaConnect({ groupId: "g1", Kafka }),
+ /consumer connect failed/,
+ );
+});
+
+// ---------------------------------------------------------------------------
+// kafkaConsumeStream: consumer.stop() throwing is swallowed by stopConsumerOnce
+// ---------------------------------------------------------------------------
+
+test("kafkaConsumeStream: consumer.stop() throwing is swallowed (stopConsumerOnce catch)", async () => {
+ // Build a consumer whose stop() rejects — this exercises the .catch(() => {})
+ // in stopConsumerOnce, which must not propagate the error.
+ const consumer = {
+ connect: async () => {},
+ disconnect: async () => {},
+ subscribe: async () => {},
+ stopCalled: 0,
+ _runResolve: null,
+ stop: async () => {
+ consumer.stopCalled++;
+ if (consumer._runResolve) consumer._runResolve();
+ throw new Error("consumer.stop exploded");
+ },
+ run: async () =>
+ new Promise((resolve) => {
+ consumer._runResolve = resolve;
+ }),
+ };
+
+ const stream = await kafkaConsumeStream({ consumer, topics: "t" });
+ stream.resume();
+ // stop() must not throw even though consumer.stop() does
+ await stream.stop();
+ strictEqual(consumer.stopCalled, 1);
+});
+
+// ---------------------------------------------------------------------------
+// kafkaConsumeStream: runPromise rejection is swallowed (anonymous_22)
+// ---------------------------------------------------------------------------
+
+// ---------------------------------------------------------------------------
+// kafkaConsumeStream: precise backpressure contract
+// - when the buffer is FULL (push returns false / wantsMore=false) eachMessage
+// MUST suspend on waitForRead() until the next _read releases it.
+// - when the buffer has ROOM (push returns true / wantsMore=true) eachMessage
+// MUST NOT suspend.
+// These pin down `if (!wantsMore) await waitForRead()` and waitForRead()'s
+// Promise so the BooleanLiteral / ConditionalExpression / ArrowFunction mutants
+// all fail.
+// ---------------------------------------------------------------------------
+
+const microtick = () => new Promise((resolve) => setImmediate(resolve));
+
+test("kafkaConsumeStream: eachMessage SUSPENDS while buffer is full, resumes on read", async () => {
+ const consumer = makeMessageConsumer([]);
+ // HWM 1 => first push fills the buffer and returns false (wantsMore=false).
+ const stream = await kafkaConsumeStream(
+ { consumer, topics: "t" },
+ { highWaterMark: 1 },
+ );
+
+ let settled = false;
+ const p = consumer
+ ._eachMessage({
+ topic: "t",
+ partition: 0,
+ message: {
+ offset: "0",
+ key: null,
+ value: "v1",
+ headers: {},
+ timestamp: "0",
+ },
+ })
+ .then(() => {
+ settled = true;
+ });
+
+ // eachMessage must still be parked on waitForRead() — nothing has read yet.
+ await microtick();
+ strictEqual(
+ settled,
+ false,
+ "eachMessage should be suspended while buffer full",
+ );
+
+ // Reading one item triggers _read -> releaseReaders -> resolves waitForRead.
+ const item = stream.read();
+ strictEqual(item.value, "v1");
+ await p;
+ strictEqual(settled, true, "eachMessage resumes after _read");
+
+ await stream.stop();
+ stream.destroy();
+});
+
+test("kafkaConsumeStream: eachMessage does NOT suspend while buffer has room", async () => {
+ const consumer = makeMessageConsumer([]);
+ // Large HWM => push returns true (wantsMore=true) => no waitForRead().
+ const stream = await kafkaConsumeStream(
+ { consumer, topics: "t" },
+ { highWaterMark: 100 },
+ );
+
+ let settled = false;
+ const p = consumer
+ ._eachMessage({
+ topic: "t",
+ partition: 0,
+ message: {
+ offset: "0",
+ key: null,
+ value: "v1",
+ headers: {},
+ timestamp: "0",
+ },
+ })
+ .then(() => {
+ settled = true;
+ });
+
+ // Drain MICROTASKS only (no setImmediate / I/O turn). The stream's internal
+ // _read() — which would release a wrongly-parked waiter — is scheduled on a
+ // macrotask, so it has NOT run yet. With correct code (wantsMore=true => no
+ // waitForRead) eachMessage resolves purely via microtasks. With a mutant that
+ // always waits (`if (true)`) or inverts the guard, eachMessage is still parked
+ // here because only a macrotask _read could release it.
+ for (let i = 0; i < 20; i++) await Promise.resolve();
+ strictEqual(
+ settled,
+ true,
+ "eachMessage should complete via microtasks (no waitForRead) when buffer has room",
+ );
+ await p;
+
+ await stream.stop();
+ stream.destroy();
+});
+
+// ---------------------------------------------------------------------------
+// kafkaConsumeStream: stop() idempotency guard (if (stopped) return) prevents a
+// second stream.push(null), which would emit ERR_STREAM_PUSH_AFTER_EOF.
+// ---------------------------------------------------------------------------
+
+test("kafkaConsumeStream: second stop() does not push null again / emit an error", async () => {
+ const consumer = makeMessageConsumer([]);
+ const stream = await kafkaConsumeStream({ consumer, topics: "t" });
+ stream.resume();
+
+ let errored = null;
+ stream.on("error", (e) => {
+ errored = e;
+ });
+
+ const endPromise = new Promise((resolve) => stream.once("end", resolve));
+ await stream.stop();
+ await endPromise;
+ // Second stop() must early-return; without the `if (stopped) return` guard it
+ // would call stream.push(null) again after EOF and emit an error event.
+ await stream.stop();
+ await new Promise((resolve) => setTimeout(resolve, 10));
+ strictEqual(errored, null, "no error from a redundant second stop()");
+ strictEqual(consumer.stopCalled, 1);
+});
+
+test("kafkaConsumeStream: runPromise rejection is swallowed by stop()", async () => {
+ // Build a consumer whose run() promise rejects — exercises the
+ // runPromise.catch(() => {}) in stop(), which must swallow the error.
+ const consumer = {
+ connect: async () => {},
+ disconnect: async () => {},
+ subscribe: async () => {},
+ stopCalled: 0,
+ _runResolve: null,
+ _runReject: null,
+ stop: async () => {
+ consumer.stopCalled++;
+ if (consumer._runReject) consumer._runReject(new Error("run rejected"));
+ },
+ run: async () =>
+ new Promise((_resolve, reject) => {
+ consumer._runReject = reject;
+ }),
+ };
+
+ const stream = await kafkaConsumeStream({ consumer, topics: "t" });
+ stream.resume();
+ // stop() must not throw even though runPromise rejects
+ await stream.stop();
+ strictEqual(consumer.stopCalled, 1);
+});
diff --git a/packages/kafka/index.tst.ts b/packages/kafka/index.tst.ts
new file mode 100644
index 0000000..c19800c
--- /dev/null
+++ b/packages/kafka/index.tst.ts
@@ -0,0 +1,71 @@
+///
+///
+import type { KafkaConnection } from "@datastream/kafka";
+import {
+ kafkaConnect,
+ kafkaConsumeStream,
+ kafkaProduceStream,
+} from "@datastream/kafka";
+import { describe, expect, test } from "tstyche";
+
+const producer: unknown = {};
+const consumer: unknown = {};
+
+describe("kafkaConnect", () => {
+ test("accepts no args", () => {
+ expect(kafkaConnect()).type.not.toBeAssignableTo();
+ });
+
+ test("accepts broker config", () => {
+ expect(
+ kafkaConnect({
+ brokers: ["localhost:9092"],
+ clientId: "c",
+ groupId: "g",
+ }),
+ ).type.not.toBeAssignableTo();
+ });
+
+ test("accepts producer: false", () => {
+ expect(
+ kafkaConnect({ producer: false }),
+ ).type.not.toBeAssignableTo();
+ });
+
+ test("resolves a KafkaConnection", () => {
+ expect(kafkaConnect()).type.toBe>();
+ });
+});
+
+describe("kafkaProduceStream", () => {
+ test("requires producer and topic", () => {
+ expect(
+ kafkaProduceStream({ producer, topic: "t" }),
+ ).type.not.toBeAssignableTo();
+ });
+
+ test("accepts batching options", () => {
+ expect(
+ kafkaProduceStream({ producer, topic: "t", batchSize: 50, acks: -1 }),
+ ).type.not.toBeAssignableTo();
+ });
+});
+
+describe("kafkaConsumeStream", () => {
+ test("requires consumer and topics", () => {
+ expect(
+ kafkaConsumeStream({ consumer, topics: "t" }),
+ ).type.not.toBeAssignableTo();
+ });
+
+ test("accepts an array of topics and a signal", () => {
+ expect(
+ kafkaConsumeStream({
+ consumer,
+ topics: ["a", "b"],
+ fromBeginning: true,
+ signal: new AbortController().signal,
+ }),
+ ).type.not.toBeAssignableTo();
+ });
+});
diff --git a/packages/kafka/index.web.js b/packages/kafka/index.web.js
new file mode 100644
index 0000000..2251365
--- /dev/null
+++ b/packages/kafka/index.web.js
@@ -0,0 +1,24 @@
+// Copyright 2026 will Farrell, and datastream contributors.
+// SPDX-License-Identifier: MIT
+
+// @datastream/kafka wraps kafkajs, which speaks the Kafka wire protocol over raw
+// TCP sockets — unavailable in the browser. There is no Web Streams equivalent,
+// so the browser/`webstream` export resolves to these stubs: importing the
+// package stays side-effect free (safe for bundlers and SSR), but calling any
+// export fails loudly instead of silently returning from an empty module. Use
+// this package from Node.js.
+const unsupported = (name) => () => {
+ throw new Error(
+ `${name} is not supported in the browser: @datastream/kafka requires Node.js (kafkajs over TCP).`,
+ );
+};
+
+export const kafkaConnect = unsupported("kafkaConnect");
+export const kafkaProduceStream = unsupported("kafkaProduceStream");
+export const kafkaConsumeStream = unsupported("kafkaConsumeStream");
+
+export default {
+ connect: kafkaConnect,
+ produceStream: kafkaProduceStream,
+ consumeStream: kafkaConsumeStream,
+};
diff --git a/packages/kafka/package.json b/packages/kafka/package.json
new file mode 100644
index 0000000..3bee628
--- /dev/null
+++ b/packages/kafka/package.json
@@ -0,0 +1,81 @@
+{
+ "name": "@datastream/kafka",
+ "version": "0.5.0",
+ "description": "Kafka producer and consumer streams (Node, via kafkajs)",
+ "type": "module",
+ "engines": {
+ "node": ">=24"
+ },
+ "engineStrict": true,
+ "publishConfig": {
+ "access": "public"
+ },
+ "main": "./index.node.mjs",
+ "module": "./index.web.mjs",
+ "exports": {
+ ".": {
+ "node": {
+ "import": {
+ "types": "./index.d.ts",
+ "default": "./index.node.mjs"
+ }
+ },
+ "import": {
+ "types": "./index.d.ts",
+ "default": "./index.web.mjs"
+ }
+ },
+ "./webstream": {
+ "types": "./index.d.ts",
+ "default": "./index.web.mjs"
+ }
+ },
+ "types": "index.d.ts",
+ "files": [
+ "*.mjs",
+ "*.map",
+ "*.d.ts"
+ ],
+ "scripts": {
+ "test": "npm run test:unit",
+ "test:unit": "node --test",
+ "test:perf": "node --test index.perf.js",
+ "test:mutation": "cd ../.. && MUTATE_PACKAGE=\"$(basename \"$OLDPWD\")\" stryker run"
+ },
+ "license": "MIT",
+ "keywords": [
+ "kafka",
+ "kafkajs",
+ "msk",
+ "streaming",
+ "Web Stream API",
+ "Node Stream API"
+ ],
+ "author": {
+ "name": "datastream contributors",
+ "url": "https://github.com/willfarrell/datastream/graphs/contributors"
+ },
+ "repository": {
+ "type": "git",
+ "url": "github:willfarrell/datastream",
+ "directory": "packages/kafka"
+ },
+ "bugs": {
+ "url": "https://github.com/willfarrell/datastream/issues"
+ },
+ "homepage": "https://datastream.js.org",
+ "dependencies": {
+ "@datastream/core": "0.5.0"
+ },
+ "peerDependencies": {
+ "kafkajs": "^2.0.0"
+ },
+ "peerDependenciesMeta": {
+ "kafkajs": {
+ "optional": true
+ }
+ },
+ "devDependencies": {
+ "kafkajs": "^2.0.0"
+ }
+}
diff --git a/packages/protobuf/README.md b/packages/protobuf/README.md
new file mode 100644
index 0000000..32a67dc
--- /dev/null
+++ b/packages/protobuf/README.md
@@ -0,0 +1,52 @@
+
+ <datastream> `protobuf`
+
+ Protobuf encode/decode and length-prefix framing streams.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+You can read the documentation at: https://datastream.js.org
+
+
+
+## Install
+
+To install datastream you can use NPM:
+
+```bash
+npm install --save @datastream/protobuf
+```
+
+
+## Documentation and examples
+
+For documentation and examples, refer to the main [datastream monorepo on GitHub](https://github.com/willfarrell/datastream) or [datastream official website](https://datastream.js.org).
+
+
+## Contributing
+
+Everyone is very welcome to contribute to this repository. Feel free to [raise issues](https://github.com/willfarrell/datastream/issues) or to [submit Pull Requests](https://github.com/willfarrell/datastream/pulls).
+
+
+## License
+
+Licensed under [MIT License](LICENSE). Copyright (c) 2026 [will Farrell](https://github.com/willfarrell), and [datastream contributors](https://github.com/willfarrell/datastream/graphs/contributors).
\ No newline at end of file
diff --git a/packages/protobuf/_old.js b/packages/protobuf/_old.js
new file mode 100644
index 0000000..e69de29
diff --git a/packages/protobuf/index.d.ts b/packages/protobuf/index.d.ts
new file mode 100644
index 0000000..057fac4
--- /dev/null
+++ b/packages/protobuf/index.d.ts
@@ -0,0 +1,50 @@
+// Copyright 2026 will Farrell, and datastream contributors.
+// SPDX-License-Identifier: MIT
+import type { DatastreamTransform, StreamOptions } from "@datastream/core";
+
+export interface ProtobufType {
+ encode(message: unknown): { finish(): Uint8Array };
+ decode(buffer: Uint8Array): unknown;
+ create(message: unknown): unknown;
+}
+
+// Type can be:
+// - a static ProtobufType value
+// - a sync function that takes the current chunk and returns a Type
+// - an async function returning a Promise
+// When a static value is passed, it's cached so the hot path doesn't recompute.
+export type ProtobufTypeInput =
+ | ProtobufType
+ | ((chunk: unknown) => ProtobufType | Promise);
+
+export function protobufEncodeStream(
+ options: { Type: ProtobufTypeInput },
+ streamOptions?: StreamOptions,
+): DatastreamTransform;
+
+export function protobufDecodeStream(
+ options: {
+ Type: ProtobufTypeInput;
+ /** Extract the protobuf payload bytes from each chunk. Default: identity. */
+ payload?: (chunk: C) => Uint8Array;
+ /**
+ * Caps the CUMULATIVE encoded INPUT bytes processed across the whole
+ * stream. This is a coarse input-volume guard, NOT a bound on decoded
+ * output memory: protobuf can expand a small encoded message into a much
+ * larger in-memory object graph (packed/repeated/nested fields), so the
+ * decoded objects may exceed this value.
+ */
+ maxOutputSize?: number;
+ },
+ streamOptions?: StreamOptions,
+): DatastreamTransform;
+
+export function protobufLengthPrefixFrameStream(
+ options?: Record,
+ streamOptions?: StreamOptions,
+): DatastreamTransform;
+
+export function protobufLengthPrefixUnframeStream(
+ options?: { maxMessageSize?: number },
+ streamOptions?: StreamOptions,
+): DatastreamTransform;
diff --git a/packages/protobuf/index.fuzz.js b/packages/protobuf/index.fuzz.js
new file mode 100644
index 0000000..e2b10b9
--- /dev/null
+++ b/packages/protobuf/index.fuzz.js
@@ -0,0 +1,234 @@
+// Copyright 2026 will Farrell, and datastream contributors.
+// SPDX-License-Identifier: MIT
+import test from "node:test";
+import {
+ createReadableStream,
+ pipejoin,
+ pipeline,
+ streamToArray,
+} from "@datastream/core";
+import {
+ protobufDecodeStream,
+ protobufEncodeStream,
+ protobufLengthPrefixFrameStream,
+ protobufLengthPrefixUnframeStream,
+} from "@datastream/protobuf";
+import fc from "fast-check";
+import protobuf from "protobufjs";
+
+const Type = new protobuf.Type("Msg")
+ .add(new protobuf.Field("id", 1, "int32"))
+ .add(new protobuf.Field("name", 2, "string"));
+
+const catchError = (input, e) => {
+ if (
+ e.message.includes("maxMessageSize") ||
+ e.message.includes("maxOutputSize") ||
+ e.message.includes("incomplete message") ||
+ /invalid wire type/i.test(e.message) ||
+ /invalid tag/i.test(e.message) ||
+ /invalid varint/i.test(e.message) ||
+ /invalid end group/i.test(e.message) ||
+ /index out of range/i.test(e.message) ||
+ /max depth exceeded/i.test(e.message) ||
+ /illegal/i.test(e.message)
+ ) {
+ return;
+ }
+ console.error(input, e);
+ throw e;
+};
+
+// *** protobufEncodeStream + protobufDecodeStream round-trip *** //
+test("fuzz encode→decode round-trip with random {id, name}", async () => {
+ await fc.assert(
+ fc.asyncProperty(
+ fc.array(
+ fc.record({
+ id: fc.integer({ min: -2147483648, max: 2147483647 }),
+ name: fc.string(),
+ }),
+ { minLength: 1 },
+ ),
+ async (input) => {
+ try {
+ const encoded = await streamToArray(
+ pipejoin([
+ createReadableStream(input),
+ protobufEncodeStream({ Type }),
+ ]),
+ );
+ const decoded = await streamToArray(
+ pipejoin([
+ createReadableStream(encoded),
+ protobufDecodeStream({ Type }),
+ ]),
+ );
+ for (let i = 0; i < input.length; i++) {
+ const got = decoded[i];
+ const want = input[i];
+ if (got.id !== want.id || got.name !== want.name) {
+ throw new Error(
+ `Round-trip mismatch at ${i}: got ${JSON.stringify(got)}, want ${JSON.stringify(want)}`,
+ );
+ }
+ }
+ } catch (e) {
+ catchError(input, e);
+ }
+ },
+ ),
+ { numRuns: 1_000, verbose: 2, examples: [] },
+ );
+});
+
+// *** protobufDecodeStream with random bytes *** //
+test("fuzz protobufDecodeStream with random byte inputs", async () => {
+ await fc.assert(
+ fc.asyncProperty(
+ fc.array(fc.uint8Array({ minLength: 0, maxLength: 64 }), {
+ minLength: 1,
+ }),
+ async (chunks) => {
+ try {
+ await pipeline([
+ createReadableStream(chunks),
+ protobufDecodeStream({ Type }),
+ ]);
+ } catch (e) {
+ catchError(chunks, e);
+ }
+ },
+ ),
+ { numRuns: 1_000, verbose: 2, examples: [] },
+ );
+});
+
+// *** protobufDecodeStream maxOutputSize guard *** //
+test("fuzz protobufDecodeStream with maxOutputSize", async () => {
+ await fc.assert(
+ fc.asyncProperty(
+ fc.array(
+ fc.record({
+ id: fc.integer({ min: 0, max: 100 }),
+ name: fc.string({ maxLength: 32 }),
+ }),
+ { minLength: 1, maxLength: 10 },
+ ),
+ fc.integer({ min: 1, max: 512 }),
+ async (input, maxOutputSize) => {
+ try {
+ const encoded = await streamToArray(
+ pipejoin([
+ createReadableStream(input),
+ protobufEncodeStream({ Type }),
+ ]),
+ );
+ await pipeline([
+ createReadableStream(encoded),
+ protobufDecodeStream({ Type, maxOutputSize }),
+ ]);
+ } catch (e) {
+ catchError(input, e);
+ }
+ },
+ ),
+ { numRuns: 1_000, verbose: 2, examples: [] },
+ );
+});
+
+// *** protobufLengthPrefixUnframeStream with random byte chunks *** //
+test("fuzz protobufLengthPrefixUnframeStream with random byte chunks", async () => {
+ await fc.assert(
+ fc.asyncProperty(
+ fc.array(fc.uint8Array({ minLength: 0, maxLength: 64 }), {
+ minLength: 1,
+ }),
+ async (chunks) => {
+ try {
+ await pipeline([
+ createReadableStream(chunks),
+ protobufLengthPrefixUnframeStream(),
+ ]);
+ } catch (e) {
+ catchError(chunks, e);
+ }
+ },
+ ),
+ { numRuns: 1_000, verbose: 2, examples: [] },
+ );
+});
+
+// *** protobufLengthPrefixUnframeStream maxMessageSize guard *** //
+test("fuzz protobufLengthPrefixUnframeStream with maxMessageSize", async () => {
+ await fc.assert(
+ fc.asyncProperty(
+ fc.array(fc.uint8Array({ minLength: 1, maxLength: 64 }), {
+ minLength: 1,
+ maxLength: 8,
+ }),
+ fc.integer({ min: 1, max: 128 }),
+ async (chunks, maxMessageSize) => {
+ try {
+ await pipeline([
+ createReadableStream(chunks),
+ protobufLengthPrefixUnframeStream({ maxMessageSize }),
+ ]);
+ } catch (e) {
+ catchError(chunks, e);
+ }
+ },
+ ),
+ { numRuns: 1_000, verbose: 2, examples: [] },
+ );
+});
+
+// *** frame→unframe round-trip with random payloads *** //
+test("fuzz frame→unframe round-trip with random payloads", async () => {
+ await fc.assert(
+ fc.asyncProperty(
+ fc.array(fc.uint8Array({ minLength: 0, maxLength: 128 }), {
+ minLength: 1,
+ maxLength: 16,
+ }),
+ async (payloads) => {
+ try {
+ const framed = await streamToArray(
+ pipejoin([
+ createReadableStream(payloads),
+ protobufLengthPrefixFrameStream(),
+ ]),
+ );
+ const unframed = await streamToArray(
+ pipejoin([
+ createReadableStream(framed),
+ protobufLengthPrefixUnframeStream(),
+ ]),
+ );
+ if (unframed.length !== payloads.length) {
+ throw new Error(
+ `Length mismatch: got ${unframed.length}, want ${payloads.length}`,
+ );
+ }
+ for (let i = 0; i < payloads.length; i++) {
+ const got = unframed[i];
+ const want = payloads[i];
+ if (got.length !== want.length) {
+ throw new Error(
+ `Payload length mismatch at ${i}: got ${got.length}, want ${want.length}`,
+ );
+ }
+ for (let j = 0; j < want.length; j++) {
+ if (got[j] !== want[j]) {
+ throw new Error(`Byte mismatch at ${i}[${j}]`);
+ }
+ }
+ }
+ } catch (e) {
+ catchError(payloads, e);
+ }
+ },
+ ),
+ { numRuns: 1_000, verbose: 2, examples: [] },
+ );
+});
diff --git a/packages/protobuf/index.js b/packages/protobuf/index.js
new file mode 100644
index 0000000..4828131
--- /dev/null
+++ b/packages/protobuf/index.js
@@ -0,0 +1,169 @@
+// Copyright 2026 will Farrell, and datastream contributors.
+// SPDX-License-Identifier: MIT
+import { createTransformStream } from "@datastream/core";
+
+// Resolve a ProtobufTypeInput once: a static Type is returned as-is (the hot
+// path skips recomputation), while a function is invoked per chunk and may
+// return either a Type or a Promise.
+const makeResolveType = (Type) => {
+ if (typeof Type === "function") {
+ return (chunk) => Type(chunk);
+ }
+ return () => Type;
+};
+
+export const protobufEncodeStream = ({ Type } = {}, streamOptions = {}) => {
+ const resolveType = makeResolveType(Type);
+ const transform = async (chunk, enqueue) => {
+ const type = await resolveType(chunk);
+ enqueue(type.encode(type.create(chunk)).finish());
+ };
+ return createTransformStream(transform, streamOptions);
+};
+
+export const protobufDecodeStream = (
+ { Type, payload, maxOutputSize = Number.POSITIVE_INFINITY } = {},
+ streamOptions = {},
+) => {
+ const resolveType = makeResolveType(Type);
+ const getPayload = payload ?? ((chunk) => chunk);
+ let inputSize = 0;
+ const transform = async (chunk, enqueue) => {
+ const bytes = getPayload(chunk);
+ // Default ceiling is Infinity, so the guard is the sole gate and the
+ // comparison stays load-bearing (no redundant null check to mutate away).
+ inputSize += bytes.length;
+ if (inputSize > maxOutputSize) {
+ throw new Error(
+ `Protobuf decode input exceeds maxOutputSize (${maxOutputSize} bytes)`,
+ );
+ }
+ const type = await resolveType(chunk);
+ enqueue(type.decode(bytes));
+ };
+ return createTransformStream(transform, streamOptions);
+};
+
+// Base-128 varint, matching the protobuf length-delimited wire format. Uses
+// arithmetic (not bitwise) so lengths beyond 2^31 encode/decode correctly.
+const encodeVarint = (value) => {
+ const bytes = [];
+ let v = value;
+ while (v > 0x7f) {
+ bytes.push((v % 0x80) | 0x80);
+ v = Math.floor(v / 0x80);
+ }
+ bytes.push(v);
+ return Uint8Array.from(bytes);
+};
+
+export const protobufLengthPrefixFrameStream = (
+ _options = {},
+ streamOptions = {},
+) => {
+ const transform = (chunk, enqueue) => {
+ const prefix = encodeVarint(chunk.length);
+ const framed = new Uint8Array(prefix.length + chunk.length);
+ framed.set(prefix, 0);
+ framed.set(chunk, prefix.length);
+ enqueue(framed);
+ };
+ return createTransformStream(transform, streamOptions);
+};
+
+export const protobufLengthPrefixUnframeStream = (
+ { maxMessageSize = Number.POSITIVE_INFINITY } = {},
+ streamOptions = {},
+) => {
+ // Growable ring-free byte buffer: `buffer` is the backing store (capacity),
+ // `start` is the first unconsumed byte and `end` is one past the last buffered
+ // byte. readMessage advances `start` instead of re-slicing per message, and
+ // append() writes into spare tail capacity — compacting/doubling only when the
+ // chunk doesn't fit. The old `concat([buffer, chunk])` per chunk was O(n²) both
+ // across many small messages (per-message re-slice) and across one large
+ // message spanning many chunks (full re-copy each append); this is amortized
+ // O(n) for both.
+ let buffer = new Uint8Array(0);
+ let start = 0;
+ let end = 0;
+
+ const append = (chunk) => {
+ if (buffer.length - end >= chunk.length) {
+ // Fits in the existing tail capacity — no copy of prior bytes.
+ buffer.set(chunk, end);
+ end += chunk.length;
+ return;
+ }
+ // Doesn't fit at the tail. Reclaim the consumed prefix [0, start); grow
+ // (doubling) only when even the reclaimed space is insufficient.
+ const used = end - start;
+ const capacity = Math.max(used + chunk.length, buffer.length * 2);
+ if (capacity > buffer.length) {
+ const next = new Uint8Array(capacity);
+ next.set(buffer.subarray(start, end), 0);
+ buffer = next;
+ } else {
+ buffer.copyWithin(0, start, end);
+ }
+ start = 0;
+ end = used;
+ buffer.set(chunk, end);
+ end += chunk.length;
+ };
+
+ // Pull one complete length-prefixed message off the front of the buffered
+ // region [start, end), or return null when the bytes don't yet hold a full
+ // prefix+message.
+ const readMessage = () => {
+ let length = 0;
+ let scale = 1;
+ let offset = start;
+ let complete = false;
+ // offset only ever advances by 1 from start, so it lands on `end` exactly;
+ // `!==` (rather than `<`) avoids a phantom read one past the end being
+ // indistinguishable from the real terminating-byte case.
+ while (offset !== end) {
+ const byte = buffer[offset];
+ length += (byte & 0x7f) * scale;
+ offset += 1;
+ if ((byte & 0x80) === 0) {
+ complete = true;
+ break;
+ }
+ scale *= 0x80;
+ }
+ if (!complete) {
+ return null;
+ }
+ if (length > maxMessageSize) {
+ throw new Error(
+ `Protobuf message exceeds maxMessageSize (${maxMessageSize} bytes)`,
+ );
+ }
+ if (end - offset < length) {
+ return null;
+ }
+ const message = buffer.slice(offset, offset + length);
+ start = offset + length;
+ return message;
+ };
+
+ const transform = (chunk, enqueue) => {
+ append(chunk);
+ let message = readMessage();
+ while (message !== null) {
+ enqueue(message);
+ message = readMessage();
+ }
+ };
+
+ const flush = () => {
+ if (end - start > 0) {
+ throw new Error(
+ "Protobuf unframe stream ended with an incomplete message",
+ );
+ }
+ };
+
+ return createTransformStream(transform, flush, streamOptions);
+};
diff --git a/packages/protobuf/index.perf.js b/packages/protobuf/index.perf.js
new file mode 100644
index 0000000..ec92f39
--- /dev/null
+++ b/packages/protobuf/index.perf.js
@@ -0,0 +1,124 @@
+// Copyright 2026 will Farrell, and datastream contributors.
+// SPDX-License-Identifier: MIT
+import test from "node:test";
+import {
+ createReadableStream,
+ pipejoin,
+ streamToArray,
+} from "@datastream/core";
+import {
+ protobufDecodeStream,
+ protobufEncodeStream,
+ protobufLengthPrefixFrameStream,
+ protobufLengthPrefixUnframeStream,
+} from "@datastream/protobuf";
+import protobuf from "protobufjs";
+import { Bench } from "tinybench";
+
+// -- Data generators --
+
+const time = Number(process.env.BENCH_TIME ?? 5_000);
+const ITEMS = 10_000;
+
+const Type = new protobuf.Type("Msg")
+ .add(new protobuf.Field("id", 1, "int32"))
+ .add(new protobuf.Field("name", 2, "string"))
+ .add(new protobuf.Field("value", 3, "double"));
+
+const objects = Array.from({ length: ITEMS }, (_, i) => ({
+ id: i,
+ name: `item_${i}`,
+ value: i * 1.5,
+}));
+
+// Pre-encoded buffers for the decode/unframe benchmarks.
+const encoded = await streamToArray(
+ pipejoin([createReadableStream(objects), protobufEncodeStream({ Type })]),
+);
+const framed = await streamToArray(
+ pipejoin([createReadableStream(encoded), protobufLengthPrefixFrameStream()]),
+);
+
+// -- Tests --
+
+test("perf: protobufEncodeStream", async () => {
+ const bench = new Bench({ name: "protobufEncodeStream", time });
+
+ bench.add(`${ITEMS} objects`, async () => {
+ const streams = [
+ createReadableStream(objects),
+ protobufEncodeStream({ Type }),
+ ];
+ await streamToArray(pipejoin(streams));
+ });
+
+ await bench.run();
+ console.log(`\n${bench.name}`);
+ console.table(bench.table());
+});
+
+test("perf: protobufDecodeStream", async () => {
+ const bench = new Bench({ name: "protobufDecodeStream", time });
+
+ bench.add(`${ITEMS} messages`, async () => {
+ const streams = [
+ createReadableStream(encoded),
+ protobufDecodeStream({ Type }),
+ ];
+ await streamToArray(pipejoin(streams));
+ });
+
+ await bench.run();
+ console.log(`\n${bench.name}`);
+ console.table(bench.table());
+});
+
+test("perf: protobuf roundtrip (encode → decode)", async () => {
+ const bench = new Bench({ name: "protobuf roundtrip", time });
+
+ bench.add(`${ITEMS} objects`, async () => {
+ const streams = [
+ createReadableStream(objects),
+ protobufEncodeStream({ Type }),
+ protobufDecodeStream({ Type }),
+ ];
+ await streamToArray(pipejoin(streams));
+ });
+
+ await bench.run();
+ console.log(`\n${bench.name}`);
+ console.table(bench.table());
+});
+
+test("perf: protobuf length-prefix framing roundtrip", async () => {
+ const bench = new Bench({ name: "protobuf framing roundtrip", time });
+
+ bench.add(`${ITEMS} messages`, async () => {
+ const streams = [
+ createReadableStream(encoded),
+ protobufLengthPrefixFrameStream(),
+ protobufLengthPrefixUnframeStream(),
+ ];
+ await streamToArray(pipejoin(streams));
+ });
+
+ await bench.run();
+ console.log(`\n${bench.name}`);
+ console.table(bench.table());
+});
+
+test("perf: protobufLengthPrefixUnframeStream", async () => {
+ const bench = new Bench({ name: "protobufLengthPrefixUnframeStream", time });
+
+ bench.add(`${ITEMS} framed messages`, async () => {
+ const streams = [
+ createReadableStream(framed),
+ protobufLengthPrefixUnframeStream(),
+ ];
+ await streamToArray(pipejoin(streams));
+ });
+
+ await bench.run();
+ console.log(`\n${bench.name}`);
+ console.table(bench.table());
+});
diff --git a/packages/protobuf/index.test.js b/packages/protobuf/index.test.js
new file mode 100644
index 0000000..24f7591
--- /dev/null
+++ b/packages/protobuf/index.test.js
@@ -0,0 +1,290 @@
+// Copyright 2026 will Farrell, and datastream contributors.
+// SPDX-License-Identifier: MIT
+import { deepStrictEqual, ok, strictEqual } from "node:assert";
+import test from "node:test";
+import {
+ createReadableStream,
+ pipejoin,
+ pipeline,
+ streamToArray,
+} from "@datastream/core";
+import {
+ protobufDecodeStream,
+ protobufEncodeStream,
+ protobufLengthPrefixFrameStream,
+ protobufLengthPrefixUnframeStream,
+} from "@datastream/protobuf";
+import protobuf from "protobufjs";
+
+let variant = "unknown";
+for (const execArgv of process.execArgv) {
+ const flag = "--conditions=";
+ if (execArgv.includes("--conditions=")) {
+ variant = execArgv.replace(flag, "");
+ }
+}
+
+const Type = new protobuf.Type("Msg")
+ .add(new protobuf.Field("id", 1, "int32"))
+ .add(new protobuf.Field("name", 2, "string"));
+
+const messages = [
+ { id: 1, name: "alpha" },
+ { id: 2, name: "beta" },
+ { id: 3, name: "gamma" },
+];
+
+// A message whose encoded form is >127 bytes, forcing a multi-byte varint
+// length prefix (exercises the encodeVarint loop and split-prefix framing).
+const bigMessage = { id: 42, name: "x".repeat(200) };
+
+const toPlain = (m) => ({ id: m.id, name: m.name });
+
+const encodeAll = (input, options) =>
+ streamToArray(
+ pipejoin([createReadableStream(input), protobufEncodeStream(options)]),
+ );
+
+const concat = (chunks) => {
+ const total = chunks.reduce((sum, c) => sum + c.length, 0);
+ const out = new Uint8Array(total);
+ let offset = 0;
+ for (const c of chunks) {
+ out.set(c, offset);
+ offset += c.length;
+ }
+ return out;
+};
+
+// *** protobufEncodeStream *** //
+test(`${variant}: protobufEncodeStream encodes objects to bytes (static Type)`, async () => {
+ const encoded = await encodeAll(messages, { Type });
+ strictEqual(encoded.length, 3);
+ for (const bytes of encoded) {
+ strictEqual(bytes instanceof Uint8Array, true);
+ }
+ // Round-trips back to the originals.
+ deepStrictEqual(
+ encoded.map((b) => toPlain(Type.decode(b))),
+ messages,
+ );
+});
+
+test(`${variant}: protobufEncodeStream accepts a sync function Type`, async () => {
+ const encoded = await encodeAll(messages, { Type: () => Type });
+ deepStrictEqual(
+ encoded.map((b) => toPlain(Type.decode(b))),
+ messages,
+ );
+});
+
+test(`${variant}: protobufEncodeStream accepts an async function Type`, async () => {
+ const encoded = await encodeAll(messages, { Type: async () => Type });
+ deepStrictEqual(
+ encoded.map((b) => toPlain(Type.decode(b))),
+ messages,
+ );
+});
+
+test(`${variant}: protobufEncodeStream honors streamOptions`, async () => {
+ const encoded = await encodeAll(messages, { Type }, {});
+ const stream = protobufEncodeStream({ Type }, { highWaterMark: 1 });
+ strictEqual(typeof stream.pipe, "function");
+ strictEqual(encoded.length, 3);
+});
+
+test(`${variant}: protobufEncodeStream constructs with no arguments`, () => {
+ const stream = protobufEncodeStream();
+ strictEqual(typeof stream.pipe, "function");
+});
+
+// *** protobufDecodeStream *** //
+test(`${variant}: protobufDecodeStream decodes bytes to objects`, async () => {
+ const encoded = await encodeAll(messages, { Type });
+ const decoded = await streamToArray(
+ pipejoin([createReadableStream(encoded), protobufDecodeStream({ Type })]),
+ );
+ deepStrictEqual(decoded.map(toPlain), messages);
+});
+
+test(`${variant}: protobufDecodeStream extracts bytes via payload`, async () => {
+ const encoded = await encodeAll(messages, { Type });
+ const wrapped = encoded.map((data) => ({ data }));
+ const decoded = await streamToArray(
+ pipejoin([
+ createReadableStream(wrapped),
+ protobufDecodeStream({ Type, payload: (chunk) => chunk.data }),
+ ]),
+ );
+ deepStrictEqual(decoded.map(toPlain), messages);
+});
+
+test(`${variant}: protobufDecodeStream allows input within maxOutputSize`, async () => {
+ const encoded = await encodeAll(messages, { Type });
+ const decoded = await streamToArray(
+ pipejoin([
+ createReadableStream(encoded),
+ protobufDecodeStream({ Type, maxOutputSize: 1024 }),
+ ]),
+ );
+ deepStrictEqual(decoded.map(toPlain), messages);
+});
+
+test(`${variant}: protobufDecodeStream allows input exactly at maxOutputSize`, async () => {
+ const encoded = await encodeAll(messages, { Type });
+ // Cumulative input size equal to the ceiling must be accepted (boundary is
+ // strictly-greater, not greater-or-equal).
+ const exact = encoded.reduce((sum, b) => sum + b.length, 0);
+ const decoded = await streamToArray(
+ pipejoin([
+ createReadableStream(encoded),
+ protobufDecodeStream({ Type, maxOutputSize: exact }),
+ ]),
+ );
+ deepStrictEqual(decoded.map(toPlain), messages);
+});
+
+test(`${variant}: protobufDecodeStream throws when input exceeds maxOutputSize`, async () => {
+ const encoded = await encodeAll(messages, { Type });
+ try {
+ await pipeline([
+ createReadableStream(encoded),
+ protobufDecodeStream({ Type, maxOutputSize: 1 }),
+ ]);
+ throw new Error("Should have thrown");
+ } catch (e) {
+ ok(e.message.includes("maxOutputSize"));
+ }
+});
+
+test(`${variant}: protobufDecodeStream constructs with no arguments`, () => {
+ const stream = protobufDecodeStream();
+ strictEqual(typeof stream.pipe, "function");
+});
+
+// *** length-prefix framing *** //
+test(`${variant}: frame then unframe round-trips messages (one chunk each)`, async () => {
+ const encoded = await encodeAll(messages, { Type });
+ const frames = await streamToArray(
+ pipejoin([
+ createReadableStream(encoded),
+ protobufLengthPrefixFrameStream(),
+ ]),
+ );
+ strictEqual(frames.length, 3);
+ const unframed = await streamToArray(
+ pipejoin([
+ createReadableStream(frames),
+ protobufLengthPrefixUnframeStream(),
+ ]),
+ );
+ deepStrictEqual(
+ unframed.map((b) => toPlain(Type.decode(b))),
+ messages,
+ );
+});
+
+test(`${variant}: frame uses a single-byte varint prefix for a 127-byte message`, async () => {
+ // 127 (0x7f) is the largest value that fits in a single varint byte; the
+ // encodeVarint loop must stop at v > 0x7f (a >= boundary would spill into a
+ // second 0x80-continuation byte).
+ const body = new Uint8Array(127).fill(7);
+ const frames = await streamToArray(
+ pipejoin([createReadableStream([body]), protobufLengthPrefixFrameStream()]),
+ );
+ strictEqual(frames.length, 1);
+ strictEqual(frames[0].length, 128); // prefix(1) + body(127)
+ const unframed = await streamToArray(
+ pipejoin([
+ createReadableStream(frames),
+ protobufLengthPrefixUnframeStream(),
+ ]),
+ );
+ deepStrictEqual(unframed, [body]);
+});
+
+test(`${variant}: unframe allows a message exactly at maxMessageSize`, async () => {
+ // A message whose length equals the ceiling must pass (boundary is
+ // strictly-greater).
+ const body = new Uint8Array(50).fill(3);
+ const frames = await streamToArray(
+ pipejoin([createReadableStream([body]), protobufLengthPrefixFrameStream()]),
+ );
+ const unframed = await streamToArray(
+ pipejoin([
+ createReadableStream(frames),
+ protobufLengthPrefixUnframeStream({ maxMessageSize: 50 }),
+ ]),
+ );
+ deepStrictEqual(unframed, [body]);
+});
+
+test(`${variant}: unframe reassembles messages split across byte-sized chunks`, async () => {
+ const encoded = await encodeAll([bigMessage, ...messages], { Type });
+ const frames = await streamToArray(
+ pipejoin([
+ createReadableStream(encoded),
+ protobufLengthPrefixFrameStream(),
+ ]),
+ );
+ // One contiguous buffer, then feed it one byte at a time so that both the
+ // multi-byte length prefix and the message body straddle chunk boundaries.
+ const stream = concat(frames);
+ const byteChunks = Array.from(stream, (b) => Uint8Array.of(b));
+ const unframed = await streamToArray(
+ pipejoin([
+ createReadableStream(byteChunks),
+ protobufLengthPrefixUnframeStream({ maxMessageSize: 4096 }),
+ ]),
+ );
+ deepStrictEqual(
+ unframed.map((b) => toPlain(Type.decode(b))),
+ [bigMessage, ...messages],
+ );
+});
+
+test(`${variant}: unframe throws when a message exceeds maxMessageSize`, async () => {
+ const encoded = await encodeAll([bigMessage], { Type });
+ const frames = await streamToArray(
+ pipejoin([
+ createReadableStream(encoded),
+ protobufLengthPrefixFrameStream(),
+ ]),
+ );
+ try {
+ await pipeline([
+ createReadableStream(frames),
+ protobufLengthPrefixUnframeStream({ maxMessageSize: 8 }),
+ ]);
+ throw new Error("Should have thrown");
+ } catch (e) {
+ ok(e.message.includes("maxMessageSize"));
+ }
+});
+
+test(`${variant}: unframe throws when the stream ends mid-message`, async () => {
+ // Prefix declares 5 bytes but only 2 follow.
+ const truncated = Uint8Array.of(5, 1, 2);
+ try {
+ await pipeline([
+ createReadableStream([truncated]),
+ protobufLengthPrefixUnframeStream(),
+ ]);
+ throw new Error("Should have thrown");
+ } catch (e) {
+ ok(e.message.includes("incomplete message"));
+ }
+});
+
+test(`${variant}: frame honors streamOptions and constructs with no arguments`, async () => {
+ const stream = protobufLengthPrefixFrameStream(undefined, {});
+ strictEqual(typeof stream.pipe, "function");
+ const encoded = await encodeAll(messages, { Type });
+ const frames = await streamToArray(
+ pipejoin([
+ createReadableStream(encoded),
+ protobufLengthPrefixFrameStream({}, {}),
+ ]),
+ );
+ strictEqual(frames.length, 3);
+});
diff --git a/packages/protobuf/index.tst.ts b/packages/protobuf/index.tst.ts
new file mode 100644
index 0000000..4d3a1df
--- /dev/null
+++ b/packages/protobuf/index.tst.ts
@@ -0,0 +1,66 @@
+///
+///
+import type { ProtobufType, ProtobufTypeInput } from "@datastream/protobuf";
+import {
+ protobufDecodeStream,
+ protobufEncodeStream,
+ protobufLengthPrefixFrameStream,
+ protobufLengthPrefixUnframeStream,
+} from "@datastream/protobuf";
+import { describe, expect, test } from "tstyche";
+
+const Type: ProtobufType = {
+ encode: () => ({ finish: () => new Uint8Array() }),
+ decode: () => ({}),
+ create: () => ({}),
+};
+
+describe("ProtobufTypeInput", () => {
+ test("accepts a static Type", () => {
+ expect().type.toBeAssignableTo();
+ });
+
+ test("accepts a resolver function", () => {
+ expect<
+ (chunk: unknown) => ProtobufType
+ >().type.toBeAssignableTo();
+ });
+});
+
+describe("protobufEncodeStream", () => {
+ test("requires Type", () => {
+ expect(protobufEncodeStream({ Type })).type.not.toBeAssignableTo();
+ });
+});
+
+describe("protobufDecodeStream", () => {
+ test("requires Type", () => {
+ expect(protobufDecodeStream({ Type })).type.not.toBeAssignableTo();
+ });
+
+ test("accepts payload extractor and maxOutputSize", () => {
+ expect(
+ protobufDecodeStream<{ data: Uint8Array }>({
+ Type,
+ payload: (chunk) => chunk.data,
+ maxOutputSize: 1024,
+ }),
+ ).type.not.toBeAssignableTo();
+ });
+});
+
+describe("protobufLengthPrefixFrameStream", () => {
+ test("accepts no options", () => {
+ expect(
+ protobufLengthPrefixFrameStream(),
+ ).type.not.toBeAssignableTo();
+ });
+});
+
+describe("protobufLengthPrefixUnframeStream", () => {
+ test("accepts maxMessageSize", () => {
+ expect(
+ protobufLengthPrefixUnframeStream({ maxMessageSize: 1024 }),
+ ).type.not.toBeAssignableTo();
+ });
+});
diff --git a/packages/protobuf/package.json b/packages/protobuf/package.json
new file mode 100644
index 0000000..6f12238
--- /dev/null
+++ b/packages/protobuf/package.json
@@ -0,0 +1,81 @@
+{
+ "name": "@datastream/protobuf",
+ "version": "0.5.0",
+ "description": "Protobuf encode/decode and length-prefix framing transform streams",
+ "type": "module",
+ "engines": {
+ "node": ">=24"
+ },
+ "engineStrict": true,
+ "publishConfig": {
+ "access": "public"
+ },
+ "main": "./index.node.mjs",
+ "module": "./index.web.mjs",
+ "exports": {
+ ".": {
+ "node": {
+ "import": {
+ "types": "./index.d.ts",
+ "default": "./index.node.mjs"
+ }
+ },
+ "import": {
+ "types": "./index.d.ts",
+ "default": "./index.web.mjs"
+ }
+ },
+ "./webstream": {
+ "types": "./index.d.ts",
+ "default": "./index.web.mjs"
+ }
+ },
+ "types": "index.d.ts",
+ "files": [
+ "*.mjs",
+ "*.map",
+ "*.d.ts"
+ ],
+ "scripts": {
+ "test": "npm run test:unit",
+ "test:unit": "node --test",
+ "test:perf": "node --test index.perf.js",
+ "test:mutation": "cd ../.. && MUTATE_PACKAGE=\"$(basename \"$OLDPWD\")\" stryker run"
+ },
+ "license": "MIT",
+ "keywords": [
+ "protobuf",
+ "protobufjs",
+ "encode",
+ "decode",
+ "Web Stream API",
+ "Node Stream API"
+ ],
+ "author": {
+ "name": "datastream contributors",
+ "url": "https://github.com/willfarrell/datastream/graphs/contributors"
+ },
+ "repository": {
+ "type": "git",
+ "url": "github:willfarrell/datastream",
+ "directory": "packages/protobuf"
+ },
+ "bugs": {
+ "url": "https://github.com/willfarrell/datastream/issues"
+ },
+ "homepage": "https://datastream.js.org",
+ "dependencies": {
+ "@datastream/core": "0.5.0"
+ },
+ "devDependencies": {
+ "protobufjs": "^8.0.0"
+ },
+ "peerDependencies": {
+ "protobufjs": "^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "protobufjs": {
+ "optional": true
+ }
+ }
+}
diff --git a/packages/schema-registry/README.md b/packages/schema-registry/README.md
new file mode 100644
index 0000000..3c2a113
--- /dev/null
+++ b/packages/schema-registry/README.md
@@ -0,0 +1,52 @@
+
+ <datastream> `schema-registry`
+
+ Confluent and Glue Schema Registry framing streams.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+You can read the documentation at: https://datastream.js.org
+
+
+
+## Install
+
+To install datastream you can use NPM:
+
+```bash
+npm install --save @datastream/schema-registry
+```
+
+
+## Documentation and examples
+
+For documentation and examples, refer to the main [datastream monorepo on GitHub](https://github.com/willfarrell/datastream) or [datastream official website](https://datastream.js.org).
+
+
+## Contributing
+
+Everyone is very welcome to contribute to this repository. Feel free to [raise issues](https://github.com/willfarrell/datastream/issues) or to [submit Pull Requests](https://github.com/willfarrell/datastream/pulls).
+
+
+## License
+
+Licensed under [MIT License](LICENSE). Copyright (c) 2026 [will Farrell](https://github.com/willfarrell), and [datastream contributors](https://github.com/willfarrell/datastream/graphs/contributors).
\ No newline at end of file
diff --git a/packages/schema-registry/index.d.ts b/packages/schema-registry/index.d.ts
new file mode 100644
index 0000000..cff329c
--- /dev/null
+++ b/packages/schema-registry/index.d.ts
@@ -0,0 +1,54 @@
+// Copyright 2026 will Farrell, and datastream contributors.
+// SPDX-License-Identifier: MIT
+import type {
+ DatastreamTransform,
+ ResultStream,
+ StreamOptions,
+} from "@datastream/core";
+
+export interface ConfluentSchemaIdResult {
+ schemaId: number | null;
+}
+
+export interface ConfluentEnvelope {
+ schemaId: number;
+ payload: Uint8Array;
+}
+
+export interface GlueSchemaResult {
+ schemaVersionId: string | null;
+ compression: "none" | "zlib" | null;
+}
+
+export interface GlueEnvelope {
+ schemaVersionId: string;
+ compression: "none" | "zlib";
+ payload: Uint8Array;
+}
+
+export function confluentFrameStream(
+ options: { schemaId: number; resultKey?: string },
+ streamOptions?: StreamOptions,
+): DatastreamTransform &
+ ResultStream;
+
+export function confluentUnframeStream(
+ options?: { resultKey?: string },
+ streamOptions?: StreamOptions,
+): DatastreamTransform &
+ ResultStream;
+
+export function glueFrameStream(
+ options: {
+ schemaVersionId: string;
+ compression?: "none" | "zlib";
+ resultKey?: string;
+ },
+ streamOptions?: StreamOptions,
+): DatastreamTransform & ResultStream;
+
+export function glueUnframeStream(
+ options?: { maxDecompressedBytes?: number; resultKey?: string },
+ streamOptions?: StreamOptions,
+): DatastreamTransform &
+ ResultStream;
diff --git a/packages/schema-registry/index.fuzz.js b/packages/schema-registry/index.fuzz.js
new file mode 100644
index 0000000..653c114
--- /dev/null
+++ b/packages/schema-registry/index.fuzz.js
@@ -0,0 +1,242 @@
+// Copyright 2026 will Farrell, and datastream contributors.
+// SPDX-License-Identifier: MIT
+import test from "node:test";
+import {
+ createReadableStream,
+ pipejoin,
+ pipeline,
+ streamToArray,
+} from "@datastream/core";
+import {
+ confluentFrameStream,
+ confluentUnframeStream,
+ glueFrameStream,
+ glueUnframeStream,
+} from "@datastream/schema-registry";
+import fc from "fast-check";
+
+const catchError = (input, e) => {
+ const expectedErrors = [
+ // confluentUnframeStream validation
+ "confluentUnframeStream: missing 0x00 magic byte / frame is too short",
+ // glueUnframeStream validation
+ "glueUnframeStream: missing 0x03 magic byte / frame is too short",
+ // glueUnframeStream compression errors (dynamic message with hex byte)
+ "unsupported compression",
+ // glueUnframeStream decompressed size guard
+ "maxDecompressedBytes",
+ // glueFrameStream frame size guard
+ "maxFrameBytes",
+ // confluentFrameStream schemaId validation
+ "confluentFrameStream: schemaId must be an unsigned 32-bit integer",
+ // glueFrameStream schemaVersionId validation
+ "glueFrameStream: schemaVersionId required",
+ // glueFrameStream UUID validation
+ "UUID",
+ // glueFrameStream compression validation
+ "unsupported compression",
+ // asBytes chunk type validation
+ "schema-registry: chunk must be a Uint8Array, ArrayBuffer view, ArrayBuffer, or string",
+ // confluentUnframeStream.result() / glueUnframeStream.result() distinct-id guard
+ "distinct",
+ // zlib decompression failures (malformed payload)
+ "unexpected end of file",
+ "invalid stored block lengths",
+ "incorrect header check",
+ "invalid block type",
+ "invalid distance too far back",
+ "invalid literal/length code",
+ "invalid distance code",
+ "too many length or distance symbols",
+ "invalid code lengths set",
+ "invalid bit length repeat",
+ "over-subscribed dynamic bit lengths tree",
+ "incomplete dynamic bit lengths tree",
+ "empty distance tree with lengths",
+ "over-subscribed literal/length tree",
+ "incomplete literal/length tree",
+ ];
+ for (const msg of expectedErrors) {
+ if (e.message.includes(msg)) return;
+ }
+ console.error(input, e);
+ throw e;
+};
+
+// *** confluentFrameStream *** //
+test("fuzz confluentFrameStream w/ random payload + schemaId", async () => {
+ await fc.assert(
+ fc.asyncProperty(
+ fc.uint8Array({ minLength: 0, maxLength: 256 }),
+ fc.integer({ min: 0, max: 0xffffffff }),
+ async (payload, schemaId) => {
+ try {
+ const streams = [
+ createReadableStream([payload]),
+ confluentFrameStream({ schemaId }),
+ ];
+ await streamToArray(pipejoin(streams));
+ } catch (e) {
+ catchError({ payload, schemaId }, e);
+ }
+ },
+ ),
+ {
+ numRuns: 1_000,
+ verbose: 2,
+ examples: [],
+ },
+ );
+});
+
+// *** confluentUnframeStream *** //
+test("fuzz confluentUnframeStream w/ random bytes", async () => {
+ await fc.assert(
+ fc.asyncProperty(
+ fc.uint8Array({ minLength: 0, maxLength: 256 }),
+ async (input) => {
+ try {
+ await pipeline([
+ createReadableStream([input]),
+ confluentUnframeStream(),
+ ]);
+ } catch (e) {
+ catchError(input, e);
+ }
+ },
+ ),
+ {
+ numRuns: 1_000,
+ verbose: 2,
+ examples: [],
+ },
+ );
+});
+
+// *** confluent frame -> unframe roundtrip *** //
+test("fuzz confluent frame -> unframe roundtrip", async () => {
+ await fc.assert(
+ fc.asyncProperty(
+ fc.uint8Array({ minLength: 0, maxLength: 256 }),
+ fc.integer({ min: 0, max: 0xffffffff }),
+ async (payload, schemaId) => {
+ try {
+ const streams = [
+ createReadableStream([payload]),
+ confluentFrameStream({ schemaId }),
+ confluentUnframeStream(),
+ ];
+ await streamToArray(pipejoin(streams));
+ } catch (e) {
+ catchError({ payload, schemaId }, e);
+ }
+ },
+ ),
+ {
+ numRuns: 1_000,
+ verbose: 2,
+ examples: [],
+ },
+ );
+});
+
+// *** glueFrameStream *** //
+test("fuzz glueFrameStream w/ random payload + UUID", async () => {
+ await fc.assert(
+ fc.asyncProperty(
+ fc.uint8Array({ minLength: 0, maxLength: 256 }),
+ fc.uuid(),
+ async (payload, schemaVersionId) => {
+ try {
+ const streams = [
+ createReadableStream([payload]),
+ glueFrameStream({ schemaVersionId }),
+ ];
+ await streamToArray(pipejoin(streams));
+ } catch (e) {
+ catchError({ payload, schemaVersionId }, e);
+ }
+ },
+ ),
+ {
+ numRuns: 1_000,
+ verbose: 2,
+ examples: [],
+ },
+ );
+});
+
+// *** glueUnframeStream *** //
+test("fuzz glueUnframeStream w/ random bytes", async () => {
+ await fc.assert(
+ fc.asyncProperty(
+ fc.uint8Array({ minLength: 0, maxLength: 256 }),
+ async (input) => {
+ try {
+ await pipeline([createReadableStream([input]), glueUnframeStream()]);
+ } catch (e) {
+ catchError(input, e);
+ }
+ },
+ ),
+ {
+ numRuns: 1_000,
+ verbose: 2,
+ examples: [],
+ },
+ );
+});
+
+// *** glue frame -> unframe roundtrip (none compression) *** //
+test("fuzz glue frame -> unframe roundtrip (none)", async () => {
+ await fc.assert(
+ fc.asyncProperty(
+ fc.uint8Array({ minLength: 0, maxLength: 256 }),
+ fc.uuid(),
+ async (payload, schemaVersionId) => {
+ try {
+ const streams = [
+ createReadableStream([payload]),
+ glueFrameStream({ schemaVersionId }),
+ glueUnframeStream(),
+ ];
+ await streamToArray(pipejoin(streams));
+ } catch (e) {
+ catchError({ payload, schemaVersionId }, e);
+ }
+ },
+ ),
+ {
+ numRuns: 1_000,
+ verbose: 2,
+ examples: [],
+ },
+ );
+});
+
+// *** glue frame -> unframe roundtrip (zlib compression) *** //
+test("fuzz glue frame -> unframe roundtrip (zlib)", async () => {
+ await fc.assert(
+ fc.asyncProperty(
+ fc.uint8Array({ minLength: 0, maxLength: 256 }),
+ fc.uuid(),
+ async (payload, schemaVersionId) => {
+ try {
+ const streams = [
+ createReadableStream([payload]),
+ glueFrameStream({ schemaVersionId, compression: "zlib" }),
+ glueUnframeStream(),
+ ];
+ await streamToArray(pipejoin(streams));
+ } catch (e) {
+ catchError({ payload, schemaVersionId }, e);
+ }
+ },
+ ),
+ {
+ numRuns: 1_000,
+ verbose: 2,
+ examples: [],
+ },
+ );
+});
diff --git a/packages/schema-registry/index.js b/packages/schema-registry/index.js
new file mode 100644
index 0000000..05e7f14
--- /dev/null
+++ b/packages/schema-registry/index.js
@@ -0,0 +1,380 @@
+// Copyright 2026 will Farrell, and datastream contributors.
+// SPDX-License-Identifier: MIT
+/* global CompressionStream, DecompressionStream */
+import { createTransformStream } from "@datastream/core";
+
+// Each frame/unframe transform treats one input chunk as one Schema Registry
+// envelope. This matches the Kafka use case (one Kafka message = one chunk =
+// one Schema Registry-framed record). Callers piping concatenated framed
+// buffers must split them upstream (e.g. via a length-prefix transform).
+//
+// Unframe streams emit { schemaId | schemaVersionId, payload } envelopes
+// downstream so downstream decoders (e.g. protobufDecodeStream) can pick the
+// right schema per chunk without sharing mutable state via `.result()`. The
+// `.result()` accessor is still exposed for parity with the csvDetect pattern,
+// but reflects the *most recently seen* envelope and is racy under
+// backpressure — prefer the per-chunk envelope when wiring a decoder.
+
+const GLUE_COMPRESSION_NONE = 0x00;
+const GLUE_COMPRESSION_ZLIB = 0x05;
+const UUID_HEX_RE = /^[0-9a-fA-F]{32}$/;
+
+// Shared no-op for swallowing secondary promise rejections in error-handling
+// catch blocks (see inflate/deflate). Using a named reference avoids creating
+// uncalled anonymous functions that inflate function-coverage miss counts.
+const noop = () => {};
+
+const asBytes = (chunk) => {
+ if (typeof chunk === "string") return new TextEncoder().encode(chunk);
+ // ArrayBuffer.isView covers typed arrays / DataView with possible byteOffset
+ // (including Uint8Array — the resulting view is byte-identical to the input).
+ if (ArrayBuffer.isView(chunk)) {
+ return new Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength);
+ }
+ if (chunk instanceof ArrayBuffer) return new Uint8Array(chunk);
+ // Reject anything else (numbers, null, plain objects). The previous
+ // `new Uint8Array(chunk.buffer ?? chunk)` silently turned a number N into an
+ // N-byte zero-filled buffer instead of erroring.
+ throw new TypeError(
+ "schema-registry: chunk must be a Uint8Array, ArrayBuffer view, ArrayBuffer, or string",
+ );
+};
+
+const concat = (parts) => {
+ let total = 0;
+ for (const p of parts) total += p.byteLength;
+ const out = new Uint8Array(total);
+ let offset = 0;
+ for (const p of parts) {
+ out.set(p, offset);
+ offset += p.byteLength;
+ }
+ return out;
+};
+
+// Reassemble a single logical frame that createReadableStream may have
+// auto-chunked into multiple sub-chunks. Schema Registry envelopes carry no
+// embedded length, so we use the magic byte + minimum header length as the
+// frame-boundary signal: a chunk that begins with `magic` and is at least
+// `headerSize` bytes long starts a NEW frame; any other chunk is a
+// continuation of the frame currently being buffered. This keeps the
+// "one complete framed record per chunk" contract working (each such chunk
+// starts with the magic byte) while correctly reassembling a >chunkSize frame
+// that createReadableStream sliced into payload-only continuation chunks.
+const createFrameBuffer = (magic, headerSize) => {
+ let parts = null; // null => no frame in progress
+ return {
+ // Returns the completed previous frame (or undefined) and starts buffering
+ // the incoming chunk.
+ push(bytes) {
+ let completed;
+ const startsNewFrame =
+ bytes.byteLength >= headerSize && bytes[0] === magic;
+ if (startsNewFrame) {
+ // Emit the previously buffered frame (if any) before starting fresh.
+ // concat handles the common single-part case correctly too.
+ if (parts !== null) completed = concat(parts);
+ parts = [bytes];
+ } else {
+ // Continuation chunk. If nothing is in progress this is a malformed
+ // lead chunk; surface it to the caller as `undefined` start + push so
+ // the caller's header validation throws the right error.
+ if (parts === null) parts = [bytes];
+ else parts.push(bytes);
+ }
+ return completed;
+ },
+ flush() {
+ if (parts === null) return undefined;
+ const completed = concat(parts);
+ parts = null;
+ return completed;
+ },
+ };
+};
+
+const collectStream = async (readable, maxOutputSize, limitName) => {
+ const reader = readable.getReader();
+ const chunks = [];
+ let total = 0;
+ while (true) {
+ const { value, done } = await reader.read();
+ if (done) break;
+ total += value.byteLength;
+ if (maxOutputSize != null && total > maxOutputSize) {
+ await reader.cancel();
+ throw new Error(
+ `schema-registry: ${limitName} exceeded (${maxOutputSize})`,
+ );
+ }
+ chunks.push(value);
+ }
+ return concat(chunks);
+};
+
+const inflate = async (bytes, maxOutputSize) => {
+ const ds = new DecompressionStream("deflate");
+ const writer = ds.writable.getWriter();
+ // Errors on the write side surface via the read side; we await both so
+ // failures (e.g. malformed zlib, backpressure aborts) propagate cleanly.
+ const writeP = writer.write(bytes);
+ const closeP = writer.close();
+ try {
+ const result = await collectStream(
+ ds.readable,
+ maxOutputSize,
+ "maxDecompressedBytes",
+ );
+ await writeP;
+ await closeP;
+ return result;
+ } catch (err) {
+ // Swallow writeP/closeP rejections after collect throws — read-side error
+ // is the underlying cause.
+ writeP.catch(noop);
+ closeP.catch(noop);
+ throw err;
+ }
+};
+
+const deflate = async (bytes, maxOutputSize) => {
+ const cs = new CompressionStream("deflate");
+ const writer = cs.writable.getWriter();
+ const writeP = writer.write(bytes);
+ const closeP = writer.close();
+ try {
+ const result = await collectStream(
+ cs.readable,
+ maxOutputSize,
+ "maxFrameBytes",
+ );
+ await writeP;
+ await closeP;
+ return result;
+ } catch (err) {
+ writeP.catch(noop);
+ closeP.catch(noop);
+ throw err;
+ }
+};
+
+// *** Confluent (5-byte: 0x00 magic + uint32 BE schema id) *** //
+
+export const confluentFrameStream = (
+ { schemaId, resultKey } = {},
+ streamOptions = {},
+) => {
+ if (
+ // Number.isInteger is false for every non-number, so it already rejects
+ // strings/bigints/etc.; an explicit typeof check would be redundant.
+ !Number.isInteger(schemaId) ||
+ schemaId < 0 ||
+ schemaId > 0xffffffff
+ ) {
+ throw new TypeError(
+ "confluentFrameStream: schemaId must be an unsigned 32-bit integer",
+ );
+ }
+ const header = new Uint8Array(5);
+ header[0] = 0x00;
+ new DataView(header.buffer).setUint32(1, schemaId, false);
+ const value = { schemaId };
+ const transform = (chunk, enqueue) => {
+ enqueue(concat([header, asBytes(chunk)]));
+ };
+ const stream = createTransformStream(transform, streamOptions);
+ // For frame streams `.result()` echoes the schemaId the caller configured
+ // (not detected). Listed under "confluentSchemaId" for symmetry with
+ // unframe — see file header note.
+ stream.result = () => ({
+ key: resultKey ?? "confluentSchemaId",
+ value,
+ });
+ return stream;
+};
+
+export const confluentUnframeStream = (
+ { resultKey } = {},
+ streamOptions = {},
+) => {
+ const value = { schemaId: null };
+ let distinctIds = 0;
+ const frameBuffer = createFrameBuffer(0x00, 5);
+ const parseAndEmit = (bytes, enqueue) => {
+ if (bytes.byteLength < 5 || bytes[0] !== 0x00) {
+ throw new Error(
+ "confluentUnframeStream: missing 0x00 magic byte / frame is too short",
+ );
+ }
+ const schemaId = new DataView(
+ bytes.buffer,
+ bytes.byteOffset,
+ bytes.byteLength,
+ ).getUint32(1, false);
+ if (value.schemaId !== schemaId) distinctIds += 1;
+ value.schemaId = schemaId;
+ // subarray (zero-copy) — the source bytes outlive the chunk.
+ enqueue({ schemaId, payload: bytes.subarray(5) });
+ };
+ const transform = (chunk, enqueue) => {
+ const completed = frameBuffer.push(asBytes(chunk));
+ if (completed !== undefined) parseAndEmit(completed, enqueue);
+ };
+ const flush = (enqueue) => {
+ const completed = frameBuffer.flush();
+ if (completed !== undefined) parseAndEmit(completed, enqueue);
+ };
+ const stream = createTransformStream(transform, flush, streamOptions);
+ // `.result()` reflects the most-recently-seen envelope and is racy under
+ // backpressure (see file header). If more than one DISTINCT schema id was
+ // observed, the single shared value is meaningless, so throw rather than
+ // silently report a stale id — the per-chunk envelope is the correct API.
+ stream.result = () => {
+ if (distinctIds > 1) {
+ throw new Error(
+ "confluentUnframeStream.result(): stream carried multiple distinct schemaIds; use the per-chunk envelope { schemaId, payload } instead",
+ );
+ }
+ return { key: resultKey ?? "confluentSchemaId", value };
+ };
+ return stream;
+};
+
+// *** Glue (18-byte: 0x03 magic + 1 byte compression + 16 bytes UUID) *** //
+
+const uuidToBytes = (uuid) => {
+ const hex = uuid.replaceAll("-", "");
+ if (!UUID_HEX_RE.test(hex)) {
+ throw new TypeError(
+ `glueFrameStream: schemaVersionId must be a valid UUID (got ${uuid})`,
+ );
+ }
+ // hex is exactly 32 chars (UUID_HEX_RE), i.e. 16 byte-pairs. Collect into a
+ // plain array first so an over-long loop produces a >16-byte result (caught
+ // downstream by header.set) instead of a silently-ignored out-of-bounds write
+ // on a fixed-size typed array.
+ const out = [];
+ for (let i = 0; i < 16; i++) {
+ out.push(Number.parseInt(hex.slice(i * 2, i * 2 + 2), 16));
+ }
+ return new Uint8Array(out);
+};
+
+// Precomputed byte -> 2-char hex so bytesToUuid (called per unframed Glue
+// message) avoids a per-byte toString(16)+padStart and the 5 trailing slices:
+// index the table and concatenate the canonical 8-4-4-4-12 layout directly.
+const HEX_BYTE = Array.from({ length: 256 }, (_, i) =>
+ i.toString(16).padStart(2, "0"),
+);
+const bytesToUuid = (bytes, offset) => {
+ const h = HEX_BYTE;
+ return (
+ `${h[bytes[offset]]}${h[bytes[offset + 1]]}${h[bytes[offset + 2]]}${h[bytes[offset + 3]]}-` +
+ `${h[bytes[offset + 4]]}${h[bytes[offset + 5]]}-` +
+ `${h[bytes[offset + 6]]}${h[bytes[offset + 7]]}-` +
+ `${h[bytes[offset + 8]]}${h[bytes[offset + 9]]}-` +
+ `${h[bytes[offset + 10]]}${h[bytes[offset + 11]]}${h[bytes[offset + 12]]}${h[bytes[offset + 13]]}${h[bytes[offset + 14]]}${h[bytes[offset + 15]]}`
+ );
+};
+
+export const glueFrameStream = (
+ { schemaVersionId, compression = "none", maxFrameBytes, resultKey } = {},
+ streamOptions = {},
+) => {
+ if (typeof schemaVersionId !== "string") {
+ throw new TypeError("glueFrameStream: schemaVersionId required");
+ }
+ if (compression !== "none" && compression !== "zlib") {
+ throw new TypeError(
+ `glueFrameStream: unsupported compression "${compression}" (expected "none" or "zlib")`,
+ );
+ }
+ const uuid = uuidToBytes(schemaVersionId);
+ const compressionByte =
+ compression === "zlib" ? GLUE_COMPRESSION_ZLIB : GLUE_COMPRESSION_NONE;
+ const value = { schemaVersionId };
+ // Pre-built 18-byte header — reused across chunks (only payload differs).
+ const header = new Uint8Array(18);
+ header[0] = 0x03;
+ header[1] = compressionByte;
+ header.set(uuid, 2);
+
+ const transform = async (chunk, enqueue) => {
+ const bytes = asBytes(chunk);
+ // deflate() buffers the whole compressed result; bound it with the
+ // optional maxFrameBytes ceiling, mirroring glueUnframeStream's
+ // maxDecompressedBytes (no other buffering path here is unbounded).
+ const payload =
+ compression === "zlib" ? await deflate(bytes, maxFrameBytes) : bytes;
+ enqueue(concat([header, payload]));
+ };
+ const stream = createTransformStream(transform, streamOptions);
+ stream.result = () => ({
+ key: resultKey ?? "glueSchemaVersionId",
+ value,
+ });
+ return stream;
+};
+
+export const glueUnframeStream = (
+ { maxDecompressedBytes = 10 * 1024 * 1024, resultKey } = {},
+ streamOptions = {},
+) => {
+ const value = { schemaVersionId: null, compression: null };
+ let distinctIds = 0;
+ const frameBuffer = createFrameBuffer(0x03, 18);
+ const parseAndEmit = async (bytes, enqueue) => {
+ if (bytes.byteLength < 18 || bytes[0] !== 0x03) {
+ throw new Error(
+ "glueUnframeStream: missing 0x03 magic byte / frame is too short",
+ );
+ }
+ const compressionByte = bytes[1];
+ const schemaVersionId = bytesToUuid(bytes, 2);
+ if (value.schemaVersionId !== schemaVersionId) distinctIds += 1;
+ value.schemaVersionId = schemaVersionId;
+ const framedPayload = bytes.subarray(18);
+ let payload;
+ let kind;
+ if (compressionByte === GLUE_COMPRESSION_NONE) {
+ kind = "none";
+ payload = framedPayload;
+ } else if (compressionByte === GLUE_COMPRESSION_ZLIB) {
+ kind = "zlib";
+ payload = await inflate(framedPayload, maxDecompressedBytes);
+ } else {
+ throw new Error(
+ `glueUnframeStream: unsupported compression byte 0x${compressionByte.toString(16).padStart(2, "0")}`,
+ );
+ }
+ value.compression = kind;
+ enqueue({ schemaVersionId, compression: kind, payload });
+ };
+ const transform = async (chunk, enqueue) => {
+ const completed = frameBuffer.push(asBytes(chunk));
+ if (completed !== undefined) await parseAndEmit(completed, enqueue);
+ };
+ const flush = async (enqueue) => {
+ const completed = frameBuffer.flush();
+ if (completed !== undefined) await parseAndEmit(completed, enqueue);
+ };
+ const stream = createTransformStream(transform, flush, streamOptions);
+ // See confluentUnframeStream: throw rather than report a stale id when the
+ // stream carried multiple distinct schemaVersionIds.
+ stream.result = () => {
+ if (distinctIds > 1) {
+ throw new Error(
+ "glueUnframeStream.result(): stream carried multiple distinct schemaVersionIds; use the per-chunk envelope { schemaVersionId, compression, payload } instead",
+ );
+ }
+ return { key: resultKey ?? "glueSchemaVersionId", value };
+ };
+ return stream;
+};
+
+export default {
+ confluentFrameStream,
+ confluentUnframeStream,
+ glueFrameStream,
+ glueUnframeStream,
+};
diff --git a/packages/schema-registry/index.perf.js b/packages/schema-registry/index.perf.js
new file mode 100644
index 0000000..d366a88
--- /dev/null
+++ b/packages/schema-registry/index.perf.js
@@ -0,0 +1,142 @@
+// Copyright 2026 will Farrell, and datastream contributors.
+// SPDX-License-Identifier: MIT
+import test from "node:test";
+import {
+ createReadableStream,
+ pipejoin,
+ streamToArray,
+} from "@datastream/core";
+import {
+ confluentFrameStream,
+ confluentUnframeStream,
+ glueFrameStream,
+ glueUnframeStream,
+} from "@datastream/schema-registry";
+import { Bench } from "tinybench";
+
+// -- Data generators --
+
+const time = Number(process.env.BENCH_TIME ?? 5_000);
+
+const schemaId = 42;
+const schemaVersionId = "12345678-1234-1234-1234-1234567890ab";
+const count = 10_000;
+
+// Generate N Uint8Array payloads of 64 bytes each
+const messages = Array.from({ length: count }, (_, i) => {
+ const buf = new Uint8Array(64);
+ for (let j = 0; j < 64; j++) buf[j] = (i + j) % 256;
+ return buf;
+});
+
+// Pre-frame messages for unframe benchmarks
+const confluentFramed = await streamToArray(
+ pipejoin([
+ createReadableStream(messages),
+ confluentFrameStream({ schemaId }),
+ ]),
+);
+
+const glueFramed = await streamToArray(
+ pipejoin([
+ createReadableStream(messages),
+ glueFrameStream({ schemaVersionId }),
+ ]),
+);
+
+// -- Tests --
+
+test("perf: confluentFrameStream", async () => {
+ const bench = new Bench({ name: "confluentFrameStream", time });
+
+ bench.add(`${count} messages`, async () => {
+ const streams = [
+ createReadableStream(messages),
+ confluentFrameStream({ schemaId }),
+ ];
+ await streamToArray(pipejoin(streams));
+ });
+
+ await bench.run();
+ console.log(`\n${bench.name}`);
+ console.table(bench.table());
+});
+
+test("perf: confluentUnframeStream", async () => {
+ const bench = new Bench({ name: "confluentUnframeStream", time });
+
+ bench.add(`${count} messages`, async () => {
+ const streams = [
+ createReadableStream(confluentFramed),
+ confluentUnframeStream(),
+ ];
+ await streamToArray(pipejoin(streams));
+ });
+
+ await bench.run();
+ console.log(`\n${bench.name}`);
+ console.table(bench.table());
+});
+
+test("perf: confluent frame -> unframe roundtrip", async () => {
+ const bench = new Bench({ name: "confluent roundtrip", time });
+
+ bench.add(`${count} messages`, async () => {
+ const streams = [
+ createReadableStream(messages),
+ confluentFrameStream({ schemaId }),
+ confluentUnframeStream(),
+ ];
+ await streamToArray(pipejoin(streams));
+ });
+
+ await bench.run();
+ console.log(`\n${bench.name}`);
+ console.table(bench.table());
+});
+
+test("perf: glueFrameStream", async () => {
+ const bench = new Bench({ name: "glueFrameStream", time });
+
+ bench.add(`${count} messages`, async () => {
+ const streams = [
+ createReadableStream(messages),
+ glueFrameStream({ schemaVersionId }),
+ ];
+ await streamToArray(pipejoin(streams));
+ });
+
+ await bench.run();
+ console.log(`\n${bench.name}`);
+ console.table(bench.table());
+});
+
+test("perf: glueUnframeStream", async () => {
+ const bench = new Bench({ name: "glueUnframeStream", time });
+
+ bench.add(`${count} messages`, async () => {
+ const streams = [createReadableStream(glueFramed), glueUnframeStream()];
+ await streamToArray(pipejoin(streams));
+ });
+
+ await bench.run();
+ console.log(`\n${bench.name}`);
+ console.table(bench.table());
+});
+
+test("perf: glue frame -> unframe roundtrip", async () => {
+ const bench = new Bench({ name: "glue roundtrip", time });
+
+ bench.add(`${count} messages`, async () => {
+ const streams = [
+ createReadableStream(messages),
+ glueFrameStream({ schemaVersionId }),
+ glueUnframeStream(),
+ ];
+ await streamToArray(pipejoin(streams));
+ });
+
+ await bench.run();
+ console.log(`\n${bench.name}`);
+ console.table(bench.table());
+});
diff --git a/packages/schema-registry/index.test.js b/packages/schema-registry/index.test.js
new file mode 100644
index 0000000..5756260
--- /dev/null
+++ b/packages/schema-registry/index.test.js
@@ -0,0 +1,1377 @@
+import { deepStrictEqual, ok, strictEqual } from "node:assert";
+import test from "node:test";
+
+import {
+ createReadableStream,
+ pipejoin,
+ pipeline,
+ streamToArray,
+} from "@datastream/core";
+import {
+ confluentFrameStream,
+ confluentUnframeStream,
+ glueFrameStream,
+ glueUnframeStream,
+} from "@datastream/schema-registry";
+
+let variant = "unknown";
+for (const execArgv of process.execArgv) {
+ const flag = "--conditions=";
+ if (execArgv.includes(flag)) {
+ variant = execArgv.replace(flag, "");
+ }
+}
+
+const helloWorld = new TextEncoder().encode("hello world");
+const schemaUuid = "12345678-1234-1234-1234-1234567890ab";
+
+// *** Confluent *** //
+test(`${variant}: confluentFrameStream prepends 0x00 + uint32 BE schema id`, async () => {
+ const streams = [
+ createReadableStream([helloWorld]),
+ confluentFrameStream({ schemaId: 257 }),
+ ];
+ const out = await streamToArray(pipejoin(streams));
+ strictEqual(out.length, 1);
+ strictEqual(out[0][0], 0x00);
+ // 257 = 0x00000101
+ strictEqual(out[0][1], 0x00);
+ strictEqual(out[0][2], 0x00);
+ strictEqual(out[0][3], 0x01);
+ strictEqual(out[0][4], 0x01);
+ strictEqual(out[0].byteLength, 5 + helloWorld.byteLength);
+});
+
+test(`${variant}: confluentFrameStream encodes schemaId big-endian for >24-bit values`, async () => {
+ const streams = [
+ createReadableStream([new Uint8Array([0xaa])]),
+ confluentFrameStream({ schemaId: 0x12345678 }),
+ ];
+ const out = await streamToArray(pipejoin(streams));
+ deepStrictEqual(
+ Array.from(out[0].slice(0, 5)),
+ [0x00, 0x12, 0x34, 0x56, 0x78],
+ );
+});
+
+test(`${variant}: confluent frame -> unframe round-trip emits envelope with schemaId + payload`, async () => {
+ const unframe = confluentUnframeStream();
+ const streams = [
+ createReadableStream([helloWorld]),
+ confluentFrameStream({ schemaId: 42 }),
+ unframe,
+ ];
+ const out = await streamToArray(pipejoin(streams));
+ strictEqual(out.length, 1);
+ strictEqual(out[0].schemaId, 42);
+ deepStrictEqual(Array.from(out[0].payload), Array.from(helloWorld));
+ // .result() still works for compatibility with the csvDetect-style readers.
+ strictEqual(unframe.result().value.schemaId, 42);
+});
+
+test(`${variant}: confluentUnframeStream rejects frames missing the magic byte`, async () => {
+ const bogus = new Uint8Array([0x01, 0, 0, 0, 0, 0x68, 0x69]);
+ try {
+ await pipeline([createReadableStream([bogus]), confluentUnframeStream()]);
+ throw new Error("Should have thrown");
+ } catch (e) {
+ ok(e.message.includes("magic byte"));
+ }
+});
+
+// *** Glue uncompressed *** //
+test(`${variant}: glueFrameStream prepends 0x03 + compression byte + uuid`, async () => {
+ const streams = [
+ createReadableStream([helloWorld]),
+ glueFrameStream({ schemaVersionId: schemaUuid }),
+ ];
+ const out = await streamToArray(pipejoin(streams));
+ strictEqual(out[0][0], 0x03);
+ strictEqual(out[0][1], 0x00); // compression none
+ strictEqual(out[0].byteLength, 18 + helloWorld.byteLength);
+});
+
+test(`${variant}: glue frame -> unframe round-trip emits { schemaVersionId, compression, payload }`, async () => {
+ const unframe = glueUnframeStream();
+ const streams = [
+ createReadableStream([helloWorld]),
+ glueFrameStream({ schemaVersionId: schemaUuid }),
+ unframe,
+ ];
+ const out = await streamToArray(pipejoin(streams));
+ strictEqual(out[0].schemaVersionId, schemaUuid);
+ strictEqual(out[0].compression, "none");
+ deepStrictEqual(Array.from(out[0].payload), Array.from(helloWorld));
+ strictEqual(unframe.result().value.schemaVersionId, schemaUuid);
+ strictEqual(unframe.result().value.compression, "none");
+});
+
+// *** Glue zlib *** //
+test(`${variant}: glue frame -> unframe round-trip (zlib compressed)`, async () => {
+ const payload = new TextEncoder().encode("a".repeat(2048));
+ const unframe = glueUnframeStream();
+ const streams = [
+ createReadableStream([payload]),
+ glueFrameStream({ schemaVersionId: schemaUuid, compression: "zlib" }),
+ unframe,
+ ];
+ const out = await streamToArray(pipejoin(streams));
+ strictEqual(out[0].compression, "zlib");
+ deepStrictEqual(Array.from(out[0].payload), Array.from(payload));
+});
+
+test(`${variant}: glueUnframeStream enforces maxDecompressedBytes`, async () => {
+ const payload = new TextEncoder().encode("a".repeat(2048));
+ try {
+ await pipeline([
+ createReadableStream([payload]),
+ glueFrameStream({ schemaVersionId: schemaUuid, compression: "zlib" }),
+ glueUnframeStream({ maxDecompressedBytes: 100 }),
+ ]);
+ throw new Error("Should have thrown");
+ } catch (e) {
+ ok(e.message.includes("maxDecompressedBytes"));
+ }
+});
+
+test(`${variant}: glueUnframeStream rejects unknown compression byte`, async () => {
+ const bogus = new Uint8Array(18 + 4);
+ bogus[0] = 0x03;
+ bogus[1] = 0x09; // unsupported
+ try {
+ await pipeline([createReadableStream([bogus]), glueUnframeStream()]);
+ throw new Error("Should have thrown");
+ } catch (e) {
+ ok(e.message.includes("unsupported compression"));
+ }
+});
+
+// *** input validation *** //
+test(`${variant}: confluentFrameStream rejects non-integer / out-of-range schemaId`, () => {
+ for (const bad of [undefined, "1", -1, 1.5, null, 0x100000000]) {
+ try {
+ confluentFrameStream({ schemaId: bad });
+ throw new Error("Should have thrown");
+ } catch (e) {
+ ok(e.message.includes("schemaId"));
+ }
+ }
+});
+
+test(`${variant}: glueFrameStream rejects missing schemaVersionId`, () => {
+ try {
+ glueFrameStream({});
+ throw new Error("Should have thrown");
+ } catch (e) {
+ ok(e.message.includes("schemaVersionId"));
+ }
+});
+
+test(`${variant}: glueFrameStream rejects unsupported compression`, () => {
+ try {
+ glueFrameStream({ schemaVersionId: schemaUuid, compression: "gzip" });
+ throw new Error("Should have thrown");
+ } catch (e) {
+ ok(e.message.includes("compression"));
+ }
+});
+
+test(`${variant}: glueFrameStream rejects malformed schemaVersionId UUID`, () => {
+ for (const bad of [
+ "not-a-uuid",
+ "zzzzzzzz-1234-1234-1234-1234567890ab", // non-hex
+ "1234567812341234123412345678ab", // too short
+ ]) {
+ try {
+ glueFrameStream({ schemaVersionId: bad });
+ throw new Error("Should have thrown");
+ } catch (e) {
+ ok(e.message.includes("UUID"));
+ }
+ }
+});
+
+test(`${variant}: glueUnframeStream rejects frames missing the magic byte`, async () => {
+ const bogus = new Uint8Array(20);
+ bogus[0] = 0x07;
+ try {
+ await pipeline([createReadableStream([bogus]), glueUnframeStream()]);
+ throw new Error("Should have thrown");
+ } catch (e) {
+ ok(e.message.includes("magic byte"));
+ }
+});
+
+// *** asBytes input-type handling (finding: numeric chunk -> zero-filled buffer) *** //
+test(`${variant}: confluentUnframeStream accepts string chunks`, async () => {
+ // Build a framed Confluent envelope, then feed it back as a latin1 string.
+ const framed = await streamToArray(
+ pipejoin([
+ createReadableStream([helloWorld]),
+ confluentFrameStream({ schemaId: 7 }),
+ ]),
+ );
+ const asString = Array.from(framed[0])
+ .map((b) => String.fromCharCode(b))
+ .join("");
+ // Re-encode via TextEncoder would corrupt high bytes; helloWorld is ASCII so
+ // round-trips, and the header bytes are < 0x80, so a latin1 string is exact.
+ const out = await streamToArray(
+ pipejoin([createReadableStream([asString]), confluentUnframeStream()]),
+ );
+ strictEqual(out.length, 1);
+ strictEqual(out[0].schemaId, 7);
+ deepStrictEqual(Array.from(out[0].payload), Array.from(helloWorld));
+});
+
+test(`${variant}: confluentUnframeStream accepts ArrayBuffer view with non-zero byteOffset`, async () => {
+ const framed = await streamToArray(
+ pipejoin([
+ createReadableStream([helloWorld]),
+ confluentFrameStream({ schemaId: 9 }),
+ ]),
+ );
+ // Place the frame inside a larger buffer at a non-zero offset, then hand a
+ // subarray view (byteOffset > 0) to the unframe stream.
+ const backing = new Uint8Array(framed[0].byteLength + 3);
+ backing.set(framed[0], 3);
+ const view = backing.subarray(3);
+ const out = await streamToArray(
+ pipejoin([createReadableStream([view]), confluentUnframeStream()]),
+ );
+ strictEqual(out.length, 1);
+ strictEqual(out[0].schemaId, 9);
+ deepStrictEqual(Array.from(out[0].payload), Array.from(helloWorld));
+});
+
+test(`${variant}: confluentFrameStream throws on a numeric chunk instead of framing zero bytes`, async () => {
+ try {
+ await pipeline([
+ createReadableStream([5]),
+ confluentFrameStream({ schemaId: 1 }),
+ ]);
+ throw new Error("Should have thrown");
+ } catch (e) {
+ ok(e.message.includes("chunk must be"));
+ }
+});
+
+// *** Glue zlib failure / round-trip edge cases *** //
+test(`${variant}: glueUnframeStream rejects a malformed zlib payload`, async () => {
+ // magic 0x03 + compression 0x05 (zlib) + 16-byte UUID + garbage payload.
+ const frame = new Uint8Array(18 + 4);
+ frame[0] = 0x03;
+ frame[1] = 0x05;
+ frame.set([0xde, 0xad, 0xbe, 0xef], 18);
+ try {
+ await pipeline([createReadableStream([frame]), glueUnframeStream()]);
+ throw new Error("Should have thrown");
+ } catch (e) {
+ ok(e instanceof Error);
+ ok(!e.message.includes("Should have thrown"));
+ }
+});
+
+test(`${variant}: glue frame -> unframe round-trip (zlib, empty payload)`, async () => {
+ const empty = new Uint8Array(0);
+ const out = await streamToArray(
+ pipejoin([
+ createReadableStream([empty]),
+ glueFrameStream({ schemaVersionId: schemaUuid, compression: "zlib" }),
+ glueUnframeStream(),
+ ]),
+ );
+ strictEqual(out.length, 1);
+ strictEqual(out[0].compression, "zlib");
+ strictEqual(out[0].payload.byteLength, 0);
+});
+
+test(`${variant}: glueFrameStream deflate enforces maxFrameBytes ceiling`, async () => {
+ const payload = new TextEncoder().encode("a".repeat(4096));
+ try {
+ await pipeline([
+ createReadableStream([payload]),
+ glueFrameStream({
+ schemaVersionId: schemaUuid,
+ compression: "zlib",
+ maxFrameBytes: 10,
+ }),
+ ]);
+ throw new Error("Should have thrown");
+ } catch (e) {
+ ok(e.message.includes("maxFrameBytes"));
+ }
+});
+
+// *** .result() raciness guard *** //
+test(`${variant}: confluentUnframeStream.result() throws when multiple distinct schema ids are seen`, async () => {
+ const frameA = await streamToArray(
+ pipejoin([
+ createReadableStream([helloWorld]),
+ confluentFrameStream({ schemaId: 1 }),
+ ]),
+ );
+ const frameB = await streamToArray(
+ pipejoin([
+ createReadableStream([helloWorld]),
+ confluentFrameStream({ schemaId: 2 }),
+ ]),
+ );
+ const unframe = confluentUnframeStream();
+ await streamToArray(
+ pipejoin([createReadableStream([frameA[0], frameB[0]]), unframe]),
+ );
+ try {
+ await unframe.result();
+ throw new Error("Should have thrown");
+ } catch (e) {
+ ok(e.message.includes("distinct"));
+ }
+});
+
+// *** multi-chunk reassembly: a single frame split across chunks *** //
+test(`${variant}: confluent frame -> unframe round-trips a single frame auto-chunked over 16KB`, async () => {
+ // 40KB payload; createReadableStream auto-chunks the framed buffer into
+ // multiple 16KB sub-chunks of ONE frame.
+ const big = new Uint8Array(40 * 1024);
+ for (let i = 0; i < big.byteLength; i++) big[i] = i % 251;
+ const framed = await streamToArray(
+ pipejoin([
+ createReadableStream([big]),
+ confluentFrameStream({ schemaId: 123 }),
+ ]),
+ );
+ ok(framed[0].byteLength > 16384);
+ const out = await streamToArray(
+ pipejoin([
+ createReadableStream(framed[0]), // ArrayBuffer path -> sub-chunks
+ confluentUnframeStream(),
+ ]),
+ );
+ strictEqual(out.length, 1);
+ strictEqual(out[0].schemaId, 123);
+ strictEqual(out[0].payload.byteLength, big.byteLength);
+ deepStrictEqual(Array.from(out[0].payload), Array.from(big));
+});
+
+test(`${variant}: glue frame -> unframe round-trips a single frame auto-chunked over 16KB`, async () => {
+ const big = new Uint8Array(40 * 1024);
+ for (let i = 0; i < big.byteLength; i++) big[i] = (i * 7) % 251;
+ const framed = await streamToArray(
+ pipejoin([
+ createReadableStream([big]),
+ glueFrameStream({ schemaVersionId: schemaUuid }),
+ ]),
+ );
+ ok(framed[0].byteLength > 16384);
+ const out = await streamToArray(
+ pipejoin([createReadableStream(framed[0]), glueUnframeStream()]),
+ );
+ strictEqual(out.length, 1);
+ strictEqual(out[0].schemaVersionId, schemaUuid);
+ strictEqual(out[0].payload.byteLength, big.byteLength);
+ deepStrictEqual(Array.from(out[0].payload), Array.from(big));
+});
+
+// *** envelope shape protects against per-message schemaVersionId drift *** //
+test(`${variant}: glueUnframeStream envelope correctly pairs payload with its own schemaVersionId`, async () => {
+ const idA = "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa";
+ const idB = "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb";
+ const frameA = await streamToArray(
+ pipejoin([
+ createReadableStream([new TextEncoder().encode("payload-a")]),
+ glueFrameStream({ schemaVersionId: idA }),
+ ]),
+ );
+ const frameB = await streamToArray(
+ pipejoin([
+ createReadableStream([new TextEncoder().encode("payload-b")]),
+ glueFrameStream({ schemaVersionId: idB }),
+ ]),
+ );
+ const envelopes = await streamToArray(
+ pipejoin([
+ createReadableStream([frameA[0], frameB[0]]),
+ glueUnframeStream(),
+ ]),
+ );
+ strictEqual(envelopes.length, 2);
+ strictEqual(envelopes[0].schemaVersionId, idA);
+ strictEqual(envelopes[1].schemaVersionId, idB);
+ deepStrictEqual(new TextDecoder().decode(envelopes[0].payload), "payload-a");
+ deepStrictEqual(new TextDecoder().decode(envelopes[1].payload), "payload-b");
+});
+
+// *** UUID regex anchoring: ^ and $ must both match (not substring) *** //
+test(`${variant}: glueFrameStream rejects a 33-char hex string (fails $ anchor on UUID regex)`, () => {
+ // After replaceAll("-",""), 33 hex chars is not 32 - both anchors must hold.
+ const tooLong = "0123456789abcdef0123456789abcdef0"; // 33 hex chars, no hyphens
+ try {
+ glueFrameStream({ schemaVersionId: tooLong });
+ throw new Error("Should have thrown");
+ } catch (e) {
+ ok(e.message.includes("UUID"), `Expected UUID error, got: ${e.message}`);
+ }
+ const alsoTooLong = "012345678901234567890123456789abc"; // 33 hex chars
+ try {
+ glueFrameStream({ schemaVersionId: alsoTooLong });
+ throw new Error("Should have thrown");
+ } catch (e) {
+ ok(e.message.includes("UUID"), `Expected UUID error, got: ${e.message}`);
+ }
+});
+
+// *** asBytes: ArrayBuffer.isView path (non-Uint8Array typed array) *** //
+test(`${variant}: confluentFrameStream accepts an Int16Array (ArrayBuffer.isView branch)`, async () => {
+ // Int16Array is an ArrayBuffer view but NOT a Uint8Array - hits ArrayBuffer.isView branch.
+ const int16 = new Int16Array([1, 2, 3, 4]);
+ const out = await streamToArray(
+ pipejoin([
+ createReadableStream([int16]),
+ confluentFrameStream({ schemaId: 55 }),
+ ]),
+ );
+ strictEqual(out.length, 1);
+ strictEqual(out[0][0], 0x00); // magic byte
+ strictEqual(out[0].byteLength, 5 + int16.byteLength);
+});
+
+// *** asBytes: plain ArrayBuffer path *** //
+test(`${variant}: confluentFrameStream accepts a plain ArrayBuffer`, async () => {
+ // Plain ArrayBuffer (not a view) hits the instanceof ArrayBuffer branch.
+ const buf = new Uint8Array([0x61, 0x62, 0x63]).buffer; // "abc"
+ const out = await streamToArray(
+ pipejoin([
+ createReadableStream([buf]),
+ confluentFrameStream({ schemaId: 77 }),
+ ]),
+ );
+ strictEqual(out.length, 1);
+ strictEqual(out[0][0], 0x00);
+ strictEqual(out[0].byteLength, 5 + 3);
+ // Verify payload bytes are "abc"
+ strictEqual(out[0][5], 0x61);
+ strictEqual(out[0][6], 0x62);
+ strictEqual(out[0][7], 0x63);
+});
+
+// *** asBytes: Uint8Array fast-path returns the chunk identity *** //
+test(`${variant}: asBytes Uint8Array fast-path preserves the original bytes exactly`, async () => {
+ // Exercise the first branch in asBytes: Uint8Array -> return chunk directly.
+ const bytes = new Uint8Array([0x41, 0x42, 0x43]);
+ const out = await streamToArray(
+ pipejoin([
+ createReadableStream([bytes]),
+ confluentFrameStream({ schemaId: 0 }),
+ ]),
+ );
+ strictEqual(out[0][5], 0x41);
+ strictEqual(out[0][6], 0x42);
+ strictEqual(out[0][7], 0x43);
+});
+
+// *** confluentFrameStream schemaId boundary values *** //
+test(`${variant}: confluentFrameStream accepts schemaId === 0 (minimum valid, exact boundary)`, async () => {
+ const out = await streamToArray(
+ pipejoin([
+ createReadableStream([helloWorld]),
+ confluentFrameStream({ schemaId: 0 }),
+ ]),
+ );
+ strictEqual(out[0][1], 0x00);
+ strictEqual(out[0][2], 0x00);
+ strictEqual(out[0][3], 0x00);
+ strictEqual(out[0][4], 0x00);
+});
+
+test(`${variant}: confluentFrameStream accepts schemaId === 0xffffffff (maximum valid, exact boundary)`, async () => {
+ const out = await streamToArray(
+ pipejoin([
+ createReadableStream([helloWorld]),
+ confluentFrameStream({ schemaId: 0xffffffff }),
+ ]),
+ );
+ strictEqual(out[0][1], 0xff);
+ strictEqual(out[0][2], 0xff);
+ strictEqual(out[0][3], 0xff);
+ strictEqual(out[0][4], 0xff);
+});
+
+test(`${variant}: confluentFrameStream rejects schemaId === 0x100000000 (one above max)`, () => {
+ try {
+ confluentFrameStream({ schemaId: 0x100000000 });
+ throw new Error("Should have thrown");
+ } catch (e) {
+ ok(
+ e.message.includes("schemaId"),
+ `Expected schemaId error, got: ${e.message}`,
+ );
+ }
+});
+
+// *** confluentFrameStream typeof validation: number type check *** //
+test(`${variant}: confluentFrameStream rejects schemaId that is a number string (type check)`, () => {
+ try {
+ confluentFrameStream({ schemaId: "42" });
+ throw new Error("Should have thrown");
+ } catch (e) {
+ ok(
+ e.message.includes("schemaId"),
+ `Expected schemaId error, got: ${e.message}`,
+ );
+ }
+});
+
+// *** confluentFrameStream uses big-endian encoding (setUint32 false) *** //
+test(`${variant}: confluentFrameStream header bytes are big-endian (setUint32 little=false)`, async () => {
+ // 0x01020304 big-endian => bytes [0x01, 0x02, 0x03, 0x04]
+ const out = await streamToArray(
+ pipejoin([
+ createReadableStream([new Uint8Array([0xff])]),
+ confluentFrameStream({ schemaId: 0x01020304 }),
+ ]),
+ );
+ strictEqual(out[0][1], 0x01);
+ strictEqual(out[0][2], 0x02);
+ strictEqual(out[0][3], 0x03);
+ strictEqual(out[0][4], 0x04);
+});
+
+// *** confluentUnframeStream: frame exactly 4 bytes -> too short *** //
+test(`${variant}: confluentUnframeStream rejects a frame that is exactly 4 bytes (byteLength < 5)`, async () => {
+ const short = new Uint8Array([0x00, 0x00, 0x00, 0x01]); // valid magic, but only 4 bytes
+ try {
+ await pipeline([createReadableStream([short]), confluentUnframeStream()]);
+ throw new Error("Should have thrown");
+ } catch (e) {
+ ok(
+ e.message.includes("magic byte"),
+ `Expected magic byte error, got: ${e.message}`,
+ );
+ }
+});
+
+// *** confluentUnframeStream: schemaId read as big-endian (getUint32 false) *** //
+test(`${variant}: confluentUnframeStream reads schemaId as big-endian (not little-endian)`, async () => {
+ // magic 0x00 + [0x01, 0x02, 0x03, 0x04] big-endian = 0x01020304
+ const frame = new Uint8Array([0x00, 0x01, 0x02, 0x03, 0x04, 0xaa]);
+ const out = await streamToArray(
+ pipejoin([createReadableStream([frame]), confluentUnframeStream()]),
+ );
+ strictEqual(out[0].schemaId, 0x01020304);
+ strictEqual(out[0].payload[0], 0xaa);
+});
+
+// *** confluentUnframeStream distinctIds tracking *** //
+test(`${variant}: confluentUnframeStream.result() succeeds when exactly 1 distinct schemaId is seen`, async () => {
+ const unframe = confluentUnframeStream();
+ const frameA = await streamToArray(
+ pipejoin([
+ createReadableStream([helloWorld]),
+ confluentFrameStream({ schemaId: 5 }),
+ ]),
+ );
+ const frameB = await streamToArray(
+ pipejoin([
+ createReadableStream([new Uint8Array([0x01])]),
+ confluentFrameStream({ schemaId: 5 }), // same id
+ ]),
+ );
+ await streamToArray(
+ pipejoin([createReadableStream([frameA[0], frameB[0]]), unframe]),
+ );
+ const result = unframe.result();
+ strictEqual(result.value.schemaId, 5);
+});
+
+test(`${variant}: confluentUnframeStream.result() throws when exactly 2 distinct schemaIds are seen`, async () => {
+ const frameA = await streamToArray(
+ pipejoin([
+ createReadableStream([helloWorld]),
+ confluentFrameStream({ schemaId: 10 }),
+ ]),
+ );
+ const frameB = await streamToArray(
+ pipejoin([
+ createReadableStream([helloWorld]),
+ confluentFrameStream({ schemaId: 11 }),
+ ]),
+ );
+ const unframe = confluentUnframeStream();
+ await streamToArray(
+ pipejoin([createReadableStream([frameA[0], frameB[0]]), unframe]),
+ );
+ try {
+ unframe.result();
+ throw new Error("Should have thrown");
+ } catch (e) {
+ ok(
+ e.message.includes("distinct"),
+ `Expected distinct error, got: ${e.message}`,
+ );
+ ok(
+ e.message.includes("schemaId"),
+ `Expected schemaId in error, got: ${e.message}`,
+ );
+ }
+});
+
+// *** confluentUnframeStream.result() uses resultKey when provided *** //
+test(`${variant}: confluentUnframeStream.result() uses custom resultKey`, async () => {
+ const unframe = confluentUnframeStream({ resultKey: "myKey" });
+ await streamToArray(
+ pipejoin([
+ createReadableStream([helloWorld]),
+ confluentFrameStream({ schemaId: 3 }),
+ unframe,
+ ]),
+ );
+ strictEqual(unframe.result().key, "myKey");
+});
+
+test(`${variant}: confluentUnframeStream.result() defaults resultKey to "confluentSchemaId"`, async () => {
+ const unframe = confluentUnframeStream();
+ await streamToArray(
+ pipejoin([
+ createReadableStream([helloWorld]),
+ confluentFrameStream({ schemaId: 3 }),
+ unframe,
+ ]),
+ );
+ strictEqual(unframe.result().key, "confluentSchemaId");
+});
+
+// *** confluentFrameStream.result() resultKey *** //
+test(`${variant}: confluentFrameStream.result() uses custom resultKey`, async () => {
+ const stream = confluentFrameStream({
+ schemaId: 7,
+ resultKey: "myConfluentKey",
+ });
+ await streamToArray(pipejoin([createReadableStream([helloWorld]), stream]));
+ strictEqual(stream.result().key, "myConfluentKey");
+});
+
+test(`${variant}: confluentFrameStream.result() defaults to "confluentSchemaId"`, async () => {
+ const stream = confluentFrameStream({ schemaId: 7 });
+ await streamToArray(pipejoin([createReadableStream([helloWorld]), stream]));
+ strictEqual(stream.result().key, "confluentSchemaId");
+ strictEqual(stream.result().value.schemaId, 7);
+});
+
+// *** collectStream maxOutputSize boundary: total > maxOutputSize, not >= *** //
+test(`${variant}: glueUnframeStream allows decompressed output exactly equal to maxDecompressedBytes`, async () => {
+ const payload = new TextEncoder().encode("a".repeat(100));
+ const out = await streamToArray(
+ pipejoin([
+ createReadableStream([payload]),
+ glueFrameStream({ schemaVersionId: schemaUuid, compression: "zlib" }),
+ glueUnframeStream({ maxDecompressedBytes: 100 }),
+ ]),
+ );
+ strictEqual(out[0].payload.byteLength, 100);
+});
+
+// *** collectStream: maxOutputSize null means no limit *** //
+test(`${variant}: glueUnframeStream with default maxDecompressedBytes handles payloads without throwing`, async () => {
+ const payload = new TextEncoder().encode("test payload");
+ const out = await streamToArray(
+ pipejoin([
+ createReadableStream([payload]),
+ glueFrameStream({ schemaVersionId: schemaUuid, compression: "zlib" }),
+ glueUnframeStream(),
+ ]),
+ );
+ strictEqual(out.length, 1);
+ deepStrictEqual(Array.from(out[0].payload), Array.from(payload));
+});
+
+// *** createFrameBuffer: multi-chunk frame (parts.length > 1 -> concat needed in flush) *** //
+test(`${variant}: confluentUnframeStream reassembles a frame split into exactly 2 chunks`, async () => {
+ const framed = await streamToArray(
+ pipejoin([
+ createReadableStream([helloWorld]),
+ confluentFrameStream({ schemaId: 200 }),
+ ]),
+ );
+ const full = framed[0];
+ const headerChunk = full.slice(0, 5);
+ const payloadChunk = full.slice(5);
+ const out = await streamToArray(
+ pipejoin([
+ createReadableStream([headerChunk, payloadChunk]),
+ confluentUnframeStream(),
+ ]),
+ );
+ strictEqual(out.length, 1);
+ strictEqual(out[0].schemaId, 200);
+ deepStrictEqual(Array.from(out[0].payload), Array.from(helloWorld));
+});
+
+test(`${variant}: confluentUnframeStream reassembles a frame split into 3+ chunks (multi-part concat)`, async () => {
+ const payload = new Uint8Array(12);
+ for (let i = 0; i < 12; i++) payload[i] = i + 1; // none start with 0x00
+ const framed = await streamToArray(
+ pipejoin([
+ createReadableStream([payload]),
+ confluentFrameStream({ schemaId: 201 }),
+ ]),
+ );
+ const full = framed[0]; // 17 bytes total
+ const c1 = full.slice(0, 5); // header
+ const c2 = full.slice(5, 9); // continuation 1
+ const c3 = full.slice(9); // continuation 2
+ const out = await streamToArray(
+ pipejoin([createReadableStream([c1, c2, c3]), confluentUnframeStream()]),
+ );
+ strictEqual(out.length, 1);
+ strictEqual(out[0].schemaId, 201);
+ deepStrictEqual(Array.from(out[0].payload), Array.from(payload));
+});
+
+// *** createFrameBuffer: push completes previous multi-part frame when new frame starts *** //
+test(`${variant}: confluentUnframeStream emits first multi-part frame when second frame header arrives`, async () => {
+ const frameA = await streamToArray(
+ pipejoin([
+ createReadableStream([new Uint8Array([0x01, 0x02])]),
+ confluentFrameStream({ schemaId: 300 }),
+ ]),
+ );
+ const frameB = await streamToArray(
+ pipejoin([
+ createReadableStream([new Uint8Array([0x03, 0x04])]),
+ confluentFrameStream({ schemaId: 301 }),
+ ]),
+ );
+ const fullA = frameA[0];
+ const a1 = fullA.slice(0, 5); // header
+ const a2 = fullA.slice(5); // continuation
+ const out = await streamToArray(
+ pipejoin([
+ createReadableStream([a1, a2, frameB[0]]),
+ confluentUnframeStream(),
+ ]),
+ );
+ strictEqual(out.length, 2);
+ strictEqual(out[0].schemaId, 300);
+ strictEqual(out[1].schemaId, 301);
+});
+
+// *** createFrameBuffer flush: parts.length > 1 -> concat needed *** //
+test(`${variant}: glueUnframeStream flush emits multi-part frame via concat (parts.length > 1)`, async () => {
+ const bigPayload = new Uint8Array(20);
+ for (let i = 0; i < 20; i++) bigPayload[i] = i + 1; // none start with 0x03
+ const framed = await streamToArray(
+ pipejoin([
+ createReadableStream([bigPayload]),
+ glueFrameStream({ schemaVersionId: schemaUuid }),
+ ]),
+ );
+ const full = framed[0];
+ const c1 = full.slice(0, 18); // header exactly
+ const c2 = full.slice(18); // continuation
+ const out = await streamToArray(
+ pipejoin([createReadableStream([c1, c2]), glueUnframeStream()]),
+ );
+ strictEqual(out.length, 1);
+ strictEqual(out[0].schemaVersionId, schemaUuid);
+ deepStrictEqual(Array.from(out[0].payload), Array.from(bigPayload));
+});
+
+// *** glueUnframeStream: frame exactly 17 bytes -> too short *** //
+test(`${variant}: glueUnframeStream rejects a frame that is exactly 17 bytes (byteLength < 18)`, async () => {
+ const short = new Uint8Array(17);
+ short[0] = 0x03;
+ try {
+ await pipeline([createReadableStream([short]), glueUnframeStream()]);
+ throw new Error("Should have thrown");
+ } catch (e) {
+ ok(
+ e.message.includes("magic byte"),
+ `Expected magic byte error, got: ${e.message}`,
+ );
+ }
+});
+
+// *** glueUnframeStream distinctIds tracking *** //
+test(`${variant}: glueUnframeStream.result() succeeds when exactly 1 distinct schemaVersionId seen`, async () => {
+ const frameA = await streamToArray(
+ pipejoin([
+ createReadableStream([helloWorld]),
+ glueFrameStream({ schemaVersionId: schemaUuid }),
+ ]),
+ );
+ const frameB = await streamToArray(
+ pipejoin([
+ createReadableStream([new Uint8Array([0x42])]),
+ glueFrameStream({ schemaVersionId: schemaUuid }),
+ ]),
+ );
+ const unframe = glueUnframeStream();
+ await streamToArray(
+ pipejoin([createReadableStream([frameA[0], frameB[0]]), unframe]),
+ );
+ const result = unframe.result();
+ strictEqual(result.value.schemaVersionId, schemaUuid);
+});
+
+test(`${variant}: glueUnframeStream.result() throws when exactly 2 distinct schemaVersionIds seen`, async () => {
+ const idA = "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa00";
+ const idB = "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbb00";
+ const frameA = await streamToArray(
+ pipejoin([
+ createReadableStream([helloWorld]),
+ glueFrameStream({ schemaVersionId: idA }),
+ ]),
+ );
+ const frameB = await streamToArray(
+ pipejoin([
+ createReadableStream([helloWorld]),
+ glueFrameStream({ schemaVersionId: idB }),
+ ]),
+ );
+ const unframe = glueUnframeStream();
+ await streamToArray(
+ pipejoin([createReadableStream([frameA[0], frameB[0]]), unframe]),
+ );
+ try {
+ unframe.result();
+ throw new Error("Should have thrown");
+ } catch (e) {
+ ok(
+ e.message.includes("distinct"),
+ `Expected distinct error, got: ${e.message}`,
+ );
+ ok(
+ e.message.includes("schemaVersionId"),
+ `Expected schemaVersionId in error, got: ${e.message}`,
+ );
+ }
+});
+
+// *** glueUnframeStream.result() resultKey *** //
+test(`${variant}: glueUnframeStream.result() uses custom resultKey`, async () => {
+ const unframe = glueUnframeStream({ resultKey: "myGlueKey" });
+ await streamToArray(
+ pipejoin([
+ createReadableStream([helloWorld]),
+ glueFrameStream({ schemaVersionId: schemaUuid }),
+ unframe,
+ ]),
+ );
+ strictEqual(unframe.result().key, "myGlueKey");
+});
+
+test(`${variant}: glueUnframeStream.result() defaults to "glueSchemaVersionId"`, async () => {
+ const unframe = glueUnframeStream();
+ await streamToArray(
+ pipejoin([
+ createReadableStream([helloWorld]),
+ glueFrameStream({ schemaVersionId: schemaUuid }),
+ unframe,
+ ]),
+ );
+ strictEqual(unframe.result().key, "glueSchemaVersionId");
+});
+
+// *** glueFrameStream.result() resultKey *** //
+test(`${variant}: glueFrameStream.result() uses custom resultKey`, async () => {
+ const stream = glueFrameStream({
+ schemaVersionId: schemaUuid,
+ resultKey: "myGlueFrameKey",
+ });
+ await streamToArray(pipejoin([createReadableStream([helloWorld]), stream]));
+ strictEqual(stream.result().key, "myGlueFrameKey");
+});
+
+test(`${variant}: glueFrameStream.result() defaults to "glueSchemaVersionId"`, async () => {
+ const stream = glueFrameStream({ schemaVersionId: schemaUuid });
+ await streamToArray(pipejoin([createReadableStream([helloWorld]), stream]));
+ strictEqual(stream.result().key, "glueSchemaVersionId");
+ strictEqual(stream.result().value.schemaVersionId, schemaUuid);
+});
+
+// *** glueUnframeStream: unsupported compression byte error message includes zero-padded hex *** //
+test(`${variant}: glueUnframeStream unsupported compression error message includes zero-padded hex byte`, async () => {
+ // byte 0x09 -> padStart(2,"0") gives "09", not "9"
+ const frame = new Uint8Array(18 + 1);
+ frame[0] = 0x03;
+ frame[1] = 0x09;
+ try {
+ await pipeline([createReadableStream([frame]), glueUnframeStream()]);
+ throw new Error("Should have thrown");
+ } catch (e) {
+ ok(
+ e.message.includes("0x09"),
+ `Expected '0x09' in error message, got: ${e.message}`,
+ );
+ }
+});
+
+// *** createFrameBuffer startsNewFrame: byteLength >= headerSize not > headerSize *** //
+test(`${variant}: confluentUnframeStream accepts a frame chunk of exactly 5 bytes as new-frame start`, async () => {
+ const emptyPayload = new Uint8Array(0);
+ const framed = await streamToArray(
+ pipejoin([
+ createReadableStream([emptyPayload]),
+ confluentFrameStream({ schemaId: 500 }),
+ ]),
+ );
+ strictEqual(framed[0].byteLength, 5);
+ const out = await streamToArray(
+ pipejoin([createReadableStream([framed[0]]), confluentUnframeStream()]),
+ );
+ strictEqual(out.length, 1);
+ strictEqual(out[0].schemaId, 500);
+ strictEqual(out[0].payload.byteLength, 0);
+});
+
+test(`${variant}: glueUnframeStream accepts a frame chunk of exactly 18 bytes as new-frame start`, async () => {
+ const emptyPayload = new Uint8Array(0);
+ const framed = await streamToArray(
+ pipejoin([
+ createReadableStream([emptyPayload]),
+ glueFrameStream({ schemaVersionId: schemaUuid }),
+ ]),
+ );
+ strictEqual(framed[0].byteLength, 18);
+ const out = await streamToArray(
+ pipejoin([createReadableStream([framed[0]]), glueUnframeStream()]),
+ );
+ strictEqual(out.length, 1);
+ strictEqual(out[0].schemaVersionId, schemaUuid);
+ strictEqual(out[0].payload.byteLength, 0);
+});
+
+// *** flush does nothing on empty stream *** //
+test(`${variant}: confluentUnframeStream flush does nothing when stream had no input`, async () => {
+ const out = await streamToArray(
+ pipejoin([createReadableStream([]), confluentUnframeStream()]),
+ );
+ strictEqual(out.length, 0);
+});
+
+test(`${variant}: glueUnframeStream flush does nothing when stream had no input`, async () => {
+ const out = await streamToArray(
+ pipejoin([createReadableStream([]), glueUnframeStream()]),
+ );
+ strictEqual(out.length, 0);
+});
+
+// *** Error messages must be non-empty strings (StringLiteral mutants) *** //
+test(`${variant}: confluentFrameStream schemaId validation error message is non-empty`, () => {
+ try {
+ confluentFrameStream({ schemaId: undefined });
+ throw new Error("Should have thrown");
+ } catch (e) {
+ ok(
+ e.message !== "",
+ `Expected non-empty error message, got: "${e.message}"`,
+ );
+ ok(e.message.length > 10);
+ }
+});
+
+test(`${variant}: confluentUnframeStream missing magic byte error message is non-empty`, async () => {
+ const bogus = new Uint8Array([0x01, 0, 0, 0, 0, 0x68]);
+ try {
+ await pipeline([createReadableStream([bogus]), confluentUnframeStream()]);
+ throw new Error("Should have thrown");
+ } catch (e) {
+ ok(
+ e.message !== "",
+ `Expected non-empty error message, got: "${e.message}"`,
+ );
+ ok(e.message.length > 10);
+ }
+});
+
+test(`${variant}: confluentUnframeStream.result() multiple-ids error message is non-empty`, async () => {
+ const frameA = await streamToArray(
+ pipejoin([
+ createReadableStream([helloWorld]),
+ confluentFrameStream({ schemaId: 20 }),
+ ]),
+ );
+ const frameB = await streamToArray(
+ pipejoin([
+ createReadableStream([helloWorld]),
+ confluentFrameStream({ schemaId: 21 }),
+ ]),
+ );
+ const unframe = confluentUnframeStream();
+ await streamToArray(
+ pipejoin([createReadableStream([frameA[0], frameB[0]]), unframe]),
+ );
+ try {
+ unframe.result();
+ throw new Error("Should have thrown");
+ } catch (e) {
+ ok(
+ e.message !== "",
+ `Expected non-empty error message, got: "${e.message}"`,
+ );
+ ok(e.message.length > 10);
+ }
+});
+
+test(`${variant}: glueUnframeStream.result() multiple-ids error message is non-empty`, async () => {
+ const idA = "11111111-1111-1111-1111-111111111111";
+ const idB = "22222222-2222-2222-2222-222222222222";
+ const frameA = await streamToArray(
+ pipejoin([
+ createReadableStream([helloWorld]),
+ glueFrameStream({ schemaVersionId: idA }),
+ ]),
+ );
+ const frameB = await streamToArray(
+ pipejoin([
+ createReadableStream([helloWorld]),
+ glueFrameStream({ schemaVersionId: idB }),
+ ]),
+ );
+ const unframe = glueUnframeStream();
+ await streamToArray(
+ pipejoin([createReadableStream([frameA[0], frameB[0]]), unframe]),
+ );
+ try {
+ unframe.result();
+ throw new Error("Should have thrown");
+ } catch (e) {
+ ok(
+ e.message !== "",
+ `Expected non-empty error message, got: "${e.message}"`,
+ );
+ ok(e.message.length > 10);
+ }
+});
+
+// *** envelope contains both schemaId and payload fields (not empty object) *** //
+test(`${variant}: confluentUnframeStream envelope has schemaId and payload fields`, async () => {
+ const out = await streamToArray(
+ pipejoin([
+ createReadableStream([helloWorld]),
+ confluentFrameStream({ schemaId: 999 }),
+ confluentUnframeStream(),
+ ]),
+ );
+ ok("schemaId" in out[0], "envelope should have schemaId");
+ ok("payload" in out[0], "envelope should have payload");
+ strictEqual(out[0].schemaId, 999);
+});
+
+// *** confluentFrameStream value object has schemaId field *** //
+test(`${variant}: confluentFrameStream.result() value object contains schemaId`, async () => {
+ const stream = confluentFrameStream({ schemaId: 42 });
+ await streamToArray(pipejoin([createReadableStream([helloWorld]), stream]));
+ ok("schemaId" in stream.result().value, "value should have schemaId");
+ strictEqual(stream.result().value.schemaId, 42);
+});
+
+// *** glueUnframeStream value object has schemaVersionId and compression *** //
+test(`${variant}: glueUnframeStream.result() value object contains schemaVersionId and compression`, async () => {
+ const unframe = glueUnframeStream();
+ await streamToArray(
+ pipejoin([
+ createReadableStream([helloWorld]),
+ glueFrameStream({ schemaVersionId: schemaUuid }),
+ unframe,
+ ]),
+ );
+ ok("schemaVersionId" in unframe.result().value);
+ ok("compression" in unframe.result().value);
+ strictEqual(unframe.result().value.schemaVersionId, schemaUuid);
+});
+
+// *** confluentUnframeStream.result() value object has schemaId field *** //
+test(`${variant}: confluentUnframeStream.result() value has schemaId field (not empty object)`, async () => {
+ const unframe = confluentUnframeStream();
+ await streamToArray(
+ pipejoin([
+ createReadableStream([helloWorld]),
+ confluentFrameStream({ schemaId: 88 }),
+ unframe,
+ ]),
+ );
+ ok("schemaId" in unframe.result().value);
+ strictEqual(unframe.result().value.schemaId, 88);
+});
+
+// *** bytesToUuid: padStart with "0" is needed for single-digit hex bytes *** //
+test(`${variant}: glueUnframeStream decodes UUID bytes with single-digit hex values (padStart needed)`, async () => {
+ // "00010203-0405-0607-0809-0a0b0c0d0e0f" has bytes 0x00..0x0f requiring padStart(2,"0")
+ const uuidWithSmallBytes = "00010203-0405-0607-0809-0a0b0c0d0e0f";
+ const out = await streamToArray(
+ pipejoin([
+ createReadableStream([helloWorld]),
+ glueFrameStream({ schemaVersionId: uuidWithSmallBytes }),
+ glueUnframeStream(),
+ ]),
+ );
+ strictEqual(out[0].schemaVersionId, uuidWithSmallBytes);
+});
+
+// *** bytesToUuid loop: i < 16 not <= 16 (exactly 16 bytes needed) *** //
+test(`${variant}: glueUnframeStream decodes all 16 UUID bytes correctly (loop bound i < 16)`, async () => {
+ // All-FF UUID - if loop ran 17 iterations (i <= 16) it would read out-of-bounds bytes.
+ const allFF = "ffffffff-ffff-ffff-ffff-ffffffffffff";
+ const out = await streamToArray(
+ pipejoin([
+ createReadableStream([new Uint8Array([0x42])]),
+ glueFrameStream({ schemaVersionId: allFF }),
+ glueUnframeStream(),
+ ]),
+ );
+ strictEqual(out[0].schemaVersionId, allFF);
+});
+
+// *** default export contains all 4 functions *** //
+test(`${variant}: default export contains all 4 stream factory functions`, async () => {
+ const mod = await import("@datastream/schema-registry");
+ const def = mod.default;
+ ok(
+ typeof def.confluentFrameStream === "function",
+ "confluentFrameStream missing",
+ );
+ ok(
+ typeof def.confluentUnframeStream === "function",
+ "confluentUnframeStream missing",
+ );
+ ok(typeof def.glueFrameStream === "function", "glueFrameStream missing");
+ ok(typeof def.glueUnframeStream === "function", "glueUnframeStream missing");
+});
+
+// *** createFrameBuffer: chunk < headerSize starting with magic is a continuation *** //
+test(`${variant}: confluentUnframeStream treats a chunk shorter than 5 bytes starting with 0x00 as continuation`, async () => {
+ // A 3-byte chunk starting with 0x00 is < headerSize(5), so it is NOT a new frame.
+ // Instead it is a continuation. Combined with the next bytes, it forms a valid frame.
+ // Build a valid frame and split it: first 3 bytes (header prefix), then the remaining 8 bytes.
+ const framed = await streamToArray(
+ pipejoin([
+ createReadableStream([helloWorld]),
+ confluentFrameStream({ schemaId: 600 }),
+ ]),
+ );
+ const full = framed[0];
+ // first 3 bytes: [0x00, 0x00, 0x00] — starts with magic but only 3 bytes (< 5)
+ const c1 = full.slice(0, 3);
+ const c2 = full.slice(3);
+ const out = await streamToArray(
+ pipejoin([createReadableStream([c1, c2]), confluentUnframeStream()]),
+ );
+ strictEqual(out.length, 1);
+ strictEqual(out[0].schemaId, 600);
+ deepStrictEqual(Array.from(out[0].payload), Array.from(helloWorld));
+});
+
+test(`${variant}: glueUnframeStream treats a chunk shorter than 18 bytes starting with 0x03 as continuation`, async () => {
+ // A 10-byte chunk starting with 0x03 is < headerSize(18), so it is a continuation.
+ const framed = await streamToArray(
+ pipejoin([
+ createReadableStream([helloWorld]),
+ glueFrameStream({ schemaVersionId: schemaUuid }),
+ ]),
+ );
+ const full = framed[0];
+ const c1 = full.slice(0, 10); // starts with 0x03 but < 18 bytes
+ const c2 = full.slice(10);
+ const out = await streamToArray(
+ pipejoin([createReadableStream([c1, c2]), glueUnframeStream()]),
+ );
+ strictEqual(out.length, 1);
+ strictEqual(out[0].schemaVersionId, schemaUuid);
+ deepStrictEqual(Array.from(out[0].payload), Array.from(helloWorld));
+});
+
+// *** collectStream: maxOutputSize null/undefined -> no limit applied *** //
+test(`${variant}: confluentUnframeStream initial value has schemaId as null before any frames`, async () => {
+ // Test that result().value.schemaId is null (not undefined) before frames processed.
+ // With the { schemaId: null } mutation -> {}, value.schemaId would be undefined.
+ const unframe = confluentUnframeStream();
+ // Process one frame so result() does not throw due to distinctIds check
+ await streamToArray(
+ pipejoin([
+ createReadableStream([helloWorld]),
+ confluentFrameStream({ schemaId: 50 }),
+ unframe,
+ ]),
+ );
+ strictEqual(unframe.result().value.schemaId, 50);
+});
+
+test(`${variant}: glueUnframeStream initial value fields present after processing`, async () => {
+ // Test that result().value has schemaVersionId and compression (not an empty object).
+ // With the { schemaVersionId: null, compression: null } -> {}, fields would be undefined.
+ const unframe = glueUnframeStream();
+ await streamToArray(
+ pipejoin([
+ createReadableStream([helloWorld]),
+ glueFrameStream({ schemaVersionId: schemaUuid }),
+ unframe,
+ ]),
+ );
+ const v = unframe.result().value;
+ strictEqual(v.schemaVersionId, schemaUuid);
+ strictEqual(v.compression, "none");
+});
+
+// *** collectStream limitName fallback "maxDecompressedBytes" is non-empty string *** //
+test(`${variant}: glueUnframeStream limit error message contains non-empty limitName`, async () => {
+ // When glueUnframeStream calls inflate, limitName="maxDecompressedBytes" is passed.
+ // With the empty string mutant, the error would say "schema-registry: exceeded"
+ // instead of "schema-registry: maxDecompressedBytes exceeded".
+ const payload = new TextEncoder().encode("a".repeat(500));
+ try {
+ await pipeline([
+ createReadableStream([payload]),
+ glueFrameStream({ schemaVersionId: schemaUuid, compression: "zlib" }),
+ glueUnframeStream({ maxDecompressedBytes: 10 }),
+ ]);
+ throw new Error("Should have thrown");
+ } catch (e) {
+ // The error message must contain "maxDecompressedBytes" (not just "exceeded")
+ ok(
+ e.message.includes("maxDecompressedBytes"),
+ `Error should mention maxDecompressedBytes, got: ${e.message}`,
+ );
+ // Verify it's not an empty string for the limit name
+ const match = e.message.match(/schema-registry: (\S+) exceeded/);
+ ok(
+ match !== null,
+ `Error message format should match 'schema-registry: exceeded', got: ${e.message}`,
+ );
+ strictEqual(match[1], "maxDecompressedBytes");
+ }
+});
+
+// *** confluentUnframeStream initial value has schemaId as null (not undefined) *** //
+test(`${variant}: confluentUnframeStream.result() value.schemaId is null before any frames processed`, async () => {
+ // With { schemaId: null } -> {}, value.schemaId would be undefined, not null.
+ const unframe = confluentUnframeStream();
+ // distinctIds=0 so result() won't throw even before any frames.
+ const result = unframe.result();
+ strictEqual(result.value.schemaId, null);
+});
+
+// *** glueUnframeStream initial value fields are null (not undefined) *** //
+test(`${variant}: glueUnframeStream.result() value fields are null before any frames processed`, async () => {
+ // With { schemaVersionId: null, compression: null } -> {}, fields would be undefined.
+ const unframe = glueUnframeStream();
+ const result = unframe.result();
+ strictEqual(result.value.schemaVersionId, null);
+ strictEqual(result.value.compression, null);
+});
+
+// *** Multi-part push: payload bytes must be present in the completed first frame *** //
+test(`${variant}: confluentUnframeStream emits correct payload bytes from multi-part first frame`, async () => {
+ // Build a frame where the payload bytes differ from the header bytes.
+ // This ensures parts.length===1 ? parts[0] : concat(parts) actually works correctly
+ // when concat is needed (parts.length > 1 in the push path).
+ const distinctPayload = new Uint8Array([0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe]);
+ const frameA = await streamToArray(
+ pipejoin([
+ createReadableStream([distinctPayload]),
+ confluentFrameStream({ schemaId: 700 }),
+ ]),
+ );
+ const frameB = await streamToArray(
+ pipejoin([
+ createReadableStream([new Uint8Array([0x01])]),
+ confluentFrameStream({ schemaId: 701 }),
+ ]),
+ );
+ // Split frameA into header + payload to force parts.length===2 in push.
+ const a1 = frameA[0].slice(0, 5); // header
+ const a2 = frameA[0].slice(5); // payload = [0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe]
+ const out = await streamToArray(
+ pipejoin([
+ createReadableStream([a1, a2, frameB[0]]),
+ confluentUnframeStream(),
+ ]),
+ );
+ strictEqual(out.length, 2);
+ strictEqual(out[0].schemaId, 700);
+ // Must include ALL payload bytes (a2), not just the header (a1).
+ deepStrictEqual(Array.from(out[0].payload), Array.from(distinctPayload));
+ strictEqual(out[1].schemaId, 701);
+});
+
+// *** createFrameBuffer startsNewFrame requires the LENGTH check, not just magic ***
+// A short (< headerSize) continuation chunk that happens to start with the magic
+// byte must stay a continuation. Dropping the `byteLength >= headerSize` guard
+// (mutant: `true && bytes[0] === magic`) would mis-split it into its own frame.
+test(`${variant}: confluentUnframeStream keeps a <5-byte magic-leading continuation attached to the open frame`, async () => {
+ const framed = await streamToArray(
+ pipejoin([
+ createReadableStream([helloWorld]),
+ confluentFrameStream({ schemaId: 808 }),
+ ]),
+ );
+ // A 2-byte trailing continuation that begins with the magic byte 0x00.
+ const shortCont = new Uint8Array([0x00, 0x99]);
+ const out = await streamToArray(
+ pipejoin([
+ createReadableStream([framed[0], shortCont]),
+ confluentUnframeStream(),
+ ]),
+ );
+ // Correct: ONE frame whose payload is helloWorld + [0x00, 0x99].
+ strictEqual(out.length, 1);
+ strictEqual(out[0].schemaId, 808);
+ deepStrictEqual(Array.from(out[0].payload), [
+ ...Array.from(helloWorld),
+ 0x00,
+ 0x99,
+ ]);
+});
+
+// *** createFrameBuffer startsNewFrame uses >= headerSize, not > headerSize ***
+// A second frame that is EXACTLY headerSize bytes (empty payload) must be
+// recognised as a new frame. Mutant `> headerSize` would fold it into the
+// previous frame as a continuation.
+test(`${variant}: confluentUnframeStream treats an exactly-5-byte second frame as a new frame`, async () => {
+ const frameA = await streamToArray(
+ pipejoin([
+ createReadableStream([helloWorld]),
+ confluentFrameStream({ schemaId: 811 }),
+ ]),
+ );
+ // Second frame: empty payload => exactly 5 bytes, distinct schemaId.
+ const frameB = await streamToArray(
+ pipejoin([
+ createReadableStream([new Uint8Array(0)]),
+ confluentFrameStream({ schemaId: 812 }),
+ ]),
+ );
+ strictEqual(frameB[0].byteLength, 5);
+ const out = await streamToArray(
+ pipejoin([
+ createReadableStream([frameA[0], frameB[0]]),
+ confluentUnframeStream(),
+ ]),
+ );
+ // Correct: TWO distinct envelopes. Mutant (`>`) would merge into one.
+ strictEqual(out.length, 2);
+ strictEqual(out[0].schemaId, 811);
+ deepStrictEqual(Array.from(out[0].payload), Array.from(helloWorld));
+ strictEqual(out[1].schemaId, 812);
+ strictEqual(out[1].payload.byteLength, 0);
+});
+
+// *** collectStream maxOutputSize guard: `!= null` must gate the size check ***
+// Passing maxDecompressedBytes: null explicitly disables the ceiling. The guard
+// `maxOutputSize != null && total > maxOutputSize` must short-circuit to false.
+// Mutant `true && total > maxOutputSize` becomes `total > null` => `total > 0`,
+// which would throw for any non-empty decompressed output.
+test(`${variant}: glueUnframeStream with maxDecompressedBytes: null imposes no ceiling`, async () => {
+ const payload = new TextEncoder().encode("a".repeat(2048));
+ const out = await streamToArray(
+ pipejoin([
+ createReadableStream([payload]),
+ glueFrameStream({ schemaVersionId: schemaUuid, compression: "zlib" }),
+ glueUnframeStream({ maxDecompressedBytes: null }),
+ ]),
+ );
+ strictEqual(out.length, 1);
+ strictEqual(out[0].compression, "zlib");
+ deepStrictEqual(Array.from(out[0].payload), Array.from(payload));
+});
diff --git a/packages/schema-registry/index.tst.ts b/packages/schema-registry/index.tst.ts
new file mode 100644
index 0000000..b7b2e6f
--- /dev/null
+++ b/packages/schema-registry/index.tst.ts
@@ -0,0 +1,73 @@
+///
+///
+import type {
+ ConfluentEnvelope,
+ GlueEnvelope,
+} from "@datastream/schema-registry";
+import {
+ confluentFrameStream,
+ confluentUnframeStream,
+ glueFrameStream,
+ glueUnframeStream,
+} from "@datastream/schema-registry";
+import { describe, expect, test } from "tstyche";
+
+describe("ConfluentEnvelope", () => {
+ test("has schemaId and payload", () => {
+ expect().type.toBeAssignableTo<{
+ schemaId: number;
+ payload: Uint8Array;
+ }>();
+ });
+});
+
+describe("GlueEnvelope", () => {
+ test("has schemaVersionId, compression, and payload", () => {
+ expect().type.toBeAssignableTo<{
+ schemaVersionId: string;
+ compression: "none" | "zlib";
+ payload: Uint8Array;
+ }>();
+ });
+});
+
+describe("confluentFrameStream", () => {
+ test("requires schemaId", () => {
+ expect(
+ confluentFrameStream({ schemaId: 1 }),
+ ).type.not.toBeAssignableTo();
+ });
+
+ test("exposes result", () => {
+ const stream = confluentFrameStream({ schemaId: 1 });
+ expect(stream.result).type.not.toBeAssignableTo();
+ });
+});
+
+describe("confluentUnframeStream", () => {
+ test("accepts no options", () => {
+ expect(confluentUnframeStream()).type.not.toBeAssignableTo();
+ });
+});
+
+describe("glueFrameStream", () => {
+ test("requires schemaVersionId", () => {
+ expect(
+ glueFrameStream({ schemaVersionId: "abc" }),
+ ).type.not.toBeAssignableTo();
+ });
+
+ test("accepts compression", () => {
+ expect(
+ glueFrameStream({ schemaVersionId: "abc", compression: "zlib" }),
+ ).type.not.toBeAssignableTo();
+ });
+});
+
+describe("glueUnframeStream", () => {
+ test("accepts maxDecompressedBytes", () => {
+ expect(
+ glueUnframeStream({ maxDecompressedBytes: 1024 }),
+ ).type.not.toBeAssignableTo();
+ });
+});
diff --git a/packages/schema-registry/package.json b/packages/schema-registry/package.json
new file mode 100644
index 0000000..25e43d4
--- /dev/null
+++ b/packages/schema-registry/package.json
@@ -0,0 +1,71 @@
+{
+ "name": "@datastream/schema-registry",
+ "version": "0.5.0",
+ "description": "Schema-Registry wire-format framing transform streams (Confluent and AWS Glue)",
+ "type": "module",
+ "engines": {
+ "node": ">=24"
+ },
+ "engineStrict": true,
+ "publishConfig": {
+ "access": "public"
+ },
+ "main": "./index.node.mjs",
+ "module": "./index.web.mjs",
+ "exports": {
+ ".": {
+ "node": {
+ "import": {
+ "types": "./index.d.ts",
+ "default": "./index.node.mjs"
+ }
+ },
+ "import": {
+ "types": "./index.d.ts",
+ "default": "./index.web.mjs"
+ }
+ },
+ "./webstream": {
+ "types": "./index.d.ts",
+ "default": "./index.web.mjs"
+ }
+ },
+ "types": "index.d.ts",
+ "files": [
+ "*.mjs",
+ "*.map",
+ "*.d.ts"
+ ],
+ "scripts": {
+ "test": "npm run test:unit",
+ "test:unit": "node --test",
+ "test:perf": "node --test index.perf.js",
+ "test:mutation": "cd ../.. && MUTATE_PACKAGE=\"$(basename \"$OLDPWD\")\" stryker run"
+ },
+ "license": "MIT",
+ "keywords": [
+ "schema-registry",
+ "confluent",
+ "glue",
+ "avro",
+ "protobuf",
+ "Web Stream API",
+ "Node Stream API"
+ ],
+ "author": {
+ "name": "datastream contributors",
+ "url": "https://github.com/willfarrell/datastream/graphs/contributors"
+ },
+ "repository": {
+ "type": "git",
+ "url": "github:willfarrell/datastream",
+ "directory": "packages/schema-registry"
+ },
+ "bugs": {
+ "url": "https://github.com/willfarrell/datastream/issues"
+ },
+ "homepage": "https://datastream.js.org",
+ "dependencies": {
+ "@datastream/core": "0.5.0"
+ }
+}
diff --git a/websites/datastream.js.org/src/routes/docs/packages/arrow/+page.md b/websites/datastream.js.org/src/routes/docs/packages/arrow/+page.md
new file mode 100644
index 0000000..a9dc332
--- /dev/null
+++ b/websites/datastream.js.org/src/routes/docs/packages/arrow/+page.md
@@ -0,0 +1,123 @@
+---
+title: arrow
+description: Apache Arrow record batch transform streams.
+---
+
+Apache Arrow record batch transform streams. Convert rows to and from Arrow `RecordBatch` objects and detect a schema from sampled data.
+
+## Install
+
+```bash
+npm install @datastream/arrow apache-arrow
+```
+
+`apache-arrow` is a peer dependency.
+
+## `arrowDetectSchemaStream` PassThrough
+
+Samples the first rows of the stream and infers an Arrow `Schema`. Rows pass through unchanged. Accepts either arrays (columns become `column0`, `column1`, …) or objects (columns become object keys).
+
+### Options
+
+| Option | Type | Default | Description |
+|--------|------|---------|-------------|
+| `sampleSize` | `number` | `100` | Number of rows to buffer before sealing the schema |
+| `resultKey` | `string` | `"arrowDetectSchema"` | Key in pipeline result |
+
+### Result
+
+```javascript
+{ schema: Schema | null, fields: string[] | null }
+```
+
+### Type inference
+
+| Value | Arrow type |
+|-------|------------|
+| `boolean` | `Bool` |
+| Integer in signed 32-bit range | `Int32` |
+| Integer outside 32-bit range / non-integer `number` | `Float64` |
+| `Date` | `TimestampMillisecond` |
+| Anything else | `Utf8` |
+
+Integers outside the signed 32-bit range widen to `Float64` (exact up to 2^53) instead of silently wrapping inside an `Int32` builder.
+
+### Example
+
+```javascript
+import { pipeline, createReadableStream } from '@datastream/core'
+import { arrowDetectSchemaStream } from '@datastream/arrow'
+
+const detect = arrowDetectSchemaStream()
+
+const result = await pipeline([
+ createReadableStream([
+ { id: 1, name: 'Alice' },
+ { id: 2, name: 'Bob' },
+ ]),
+ detect,
+])
+
+console.log(result.arrowDetectSchema.fields) // ['id', 'name']
+```
+
+## `arrowBatchFromArrayStream` Transform
+
+Builds Arrow `RecordBatch` objects from incoming array rows. Each row is an array of column values in schema field order.
+
+### Options
+
+| Option | Type | Default | Description |
+|--------|------|---------|-------------|
+| `schema` | `Schema \| () => Schema` | — | Arrow schema, or a lazy function returning one (required) |
+| `batchSize` | `number` | `10000` | Rows per emitted `RecordBatch` |
+
+## `arrowBatchFromObjectStream` Transform
+
+Builds Arrow `RecordBatch` objects from incoming object rows, mapping each schema field name to the matching object key.
+
+### Options
+
+| Option | Type | Default | Description |
+|--------|------|---------|-------------|
+| `schema` | `Schema \| () => Schema` | — | Arrow schema, or a lazy function returning one (required) |
+| `batchSize` | `number` | `10000` | Rows per emitted `RecordBatch` |
+
+### Example
+
+```javascript
+import { pipeline, createReadableStream } from '@datastream/core'
+import { arrowDetectSchemaStream, arrowBatchFromObjectStream } from '@datastream/arrow'
+
+const detect = arrowDetectSchemaStream()
+
+await pipeline([
+ createReadableStream(rows),
+ detect,
+ arrowBatchFromObjectStream({
+ schema: () => detect.result().value.schema,
+ }),
+ // ... e.g. duckdbArrowInsertStream
+])
+```
+
+## `arrowToArrayStream` Transform
+
+Expands each incoming `RecordBatch` into array rows (one array of column values per row).
+
+## `arrowToObjectStream` Transform
+
+Expands each incoming `RecordBatch` into object rows, keyed by the batch schema's field names.
+
+### Example
+
+```javascript
+import { pipeline } from '@datastream/core'
+import { arrowToObjectStream } from '@datastream/arrow'
+
+await pipeline([
+ recordBatchReadableStream,
+ arrowToObjectStream(),
+ // ... each chunk is { id, name, ... }
+])
+```
diff --git a/websites/datastream.js.org/src/routes/docs/packages/duckdb/+page.md b/websites/datastream.js.org/src/routes/docs/packages/duckdb/+page.md
new file mode 100644
index 0000000..938403e
--- /dev/null
+++ b/websites/datastream.js.org/src/routes/docs/packages/duckdb/+page.md
@@ -0,0 +1,124 @@
+---
+title: duckdb
+description: DuckDB writable streams for inserting rows and Arrow record batches.
+---
+
+DuckDB writable streams. Insert rows or Apache Arrow `RecordBatch` objects directly into a DuckDB table.
+
+## Install
+
+```bash
+npm install @datastream/duckdb
+```
+
+DuckDB is provided through optional peer dependencies. Install the runtime for your platform:
+
+| Platform | Package |
+|----------|---------|
+| Node.js | `@duckdb/node-api` |
+| Browser | `@duckdb/duckdb-wasm` |
+
+The Arrow insert stream also requires `apache-arrow`.
+
+## `duckdbConnect`
+
+Opens a DuckDB connection. Defaults to an in-memory database.
+
+| Argument | Type | Default | Description |
+|----------|------|---------|-------------|
+| `path` | `string` | `":memory:"` | Database file path, or `:memory:` |
+| `options` | `object` | — | DuckDB instance options |
+
+```javascript
+import { duckdbConnect } from '@datastream/duckdb'
+
+const db = await duckdbConnect() // in-memory
+```
+
+## `duckdbAppenderStream` Writable
+
+Appends array or object rows into an existing table using the DuckDB appender. Returns a Promise resolving to the writable stream.
+
+### Options
+
+| Option | Type | Default | Description |
+|--------|------|---------|-------------|
+| `db` | `Connection` | — | DuckDB connection from `duckdbConnect` (required) |
+| `table` | `string` | — | Target table name (required) |
+| `schema` | `Schema \| () => Schema` | — | Arrow schema; when provided and the table does not exist, the table is created from it |
+
+When no `schema` is given, the target table must already exist; its column names are read from the table. Array rows are inserted in column order, object rows by column name.
+
+### Example
+
+```javascript
+import { pipeline, createReadableStream } from '@datastream/core'
+import { duckdbConnect, duckdbAppenderStream } from '@datastream/duckdb'
+
+const db = await duckdbConnect()
+await db.run('CREATE TABLE people (id INTEGER, name VARCHAR)')
+
+await pipeline([
+ createReadableStream([
+ { id: 1, name: 'Alice' },
+ { id: 2, name: 'Bob' },
+ ]),
+ await duckdbAppenderStream({ db, table: 'people' }),
+])
+```
+
+## `duckdbArrowInsertStream` Writable
+
+Inserts Apache Arrow `RecordBatch` objects into a table. Returns a Promise resolving to the writable stream. Pairs with `arrowBatchFromObjectStream` / `arrowBatchFromArrayStream` from `@datastream/arrow`.
+
+### Options
+
+| Option | Type | Default | Description |
+|--------|------|---------|-------------|
+| `db` | `Connection` | — | DuckDB connection from `duckdbConnect` (required) |
+| `table` | `string` | — | Target table name (required) |
+| `schema` | `Schema \| () => Schema` | — | Arrow schema; when provided and the table does not exist, the table is created from it |
+
+### Example
+
+```javascript
+import { pipeline, createReadableStream } from '@datastream/core'
+import { arrowDetectSchemaStream, arrowBatchFromObjectStream } from '@datastream/arrow'
+import { duckdbConnect, duckdbArrowInsertStream } from '@datastream/duckdb'
+
+const db = await duckdbConnect()
+const detect = arrowDetectSchemaStream()
+
+await pipeline([
+ createReadableStream(rows),
+ detect,
+ arrowBatchFromObjectStream({ schema: () => detect.result().value.schema }),
+ await duckdbArrowInsertStream({
+ db,
+ table: 'events',
+ schema: () => detect.result().value.schema,
+ }),
+])
+```
+
+## Arrow type mapping
+
+When creating a table from an Arrow schema, types map to DuckDB columns as follows:
+
+| Arrow type | DuckDB type |
+|------------|-------------|
+| `Bool` | `BOOLEAN` |
+| `Int8` / `Int16` / `Int32` / `Int64` | `TINYINT` / `SMALLINT` / `INTEGER` / `BIGINT` |
+| `Uint8` / `Uint16` / `Uint32` / `Uint64` | `UTINYINT` / `USMALLINT` / `UINTEGER` / `UBIGINT` |
+| `Float32` / `Float64` | `REAL` / `DOUBLE` |
+| `DateDay` / `DateMillisecond` | `DATE` |
+| `TimestampSecond` / `TimestampMillisecond` / `TimestampMicrosecond` / `TimestampNanosecond` | `TIMESTAMP_S` / `TIMESTAMP_MS` / `TIMESTAMP` / `TIMESTAMP_NS` |
+| anything else | `VARCHAR` |
+
+## Platform support
+
+| Feature | Node.js | Browser |
+|---------|---------|---------|
+| `duckdbConnect` | `@duckdb/node-api` | `@duckdb/duckdb-wasm` |
+| `duckdbAppenderStream` | yes | yes |
+| `duckdbArrowInsertStream` | yes | yes (requires `apache-arrow`) |
diff --git a/websites/datastream.js.org/src/routes/docs/packages/kafka/+page.md b/websites/datastream.js.org/src/routes/docs/packages/kafka/+page.md
new file mode 100644
index 0000000..5a34c38
--- /dev/null
+++ b/websites/datastream.js.org/src/routes/docs/packages/kafka/+page.md
@@ -0,0 +1,128 @@
+---
+title: kafka
+description: Kafka producer and consumer streams built on kafkajs.
+---
+
+Kafka producer and consumer streams built on [kafkajs](https://kafka.js.org). Produce messages from a writable stream and consume them from a readable stream with end-to-end backpressure.
+
+## Install
+
+```bash
+npm install @datastream/kafka kafkajs
+```
+
+`kafkajs` is an optional peer dependency.
+
+## `kafkaConnect`
+
+Creates a Kafka client and connects a producer and/or consumer. Returns a connection object. A consumer is created only when a `groupId` is provided; the producer is created unless `producer` is set to `false`.
+
+### Options
+
+| Option | Type | Default | Description |
+|--------|------|---------|-------------|
+| `brokers` | `string[]` | — | Broker addresses |
+| `clientId` | `string` | — | Client identifier |
+| `ssl` | `object` | — | TLS configuration |
+| `sasl` | `object` | — | SASL authentication (see `@datastream/aws` MSK IAM) |
+| `groupId` | `string` | — | Consumer group id; required to create a consumer |
+| `producer` | `object \| false` | `{}` | Producer options, or `false` to skip the producer |
+| `consumer` | `object` | `{}` | Additional consumer options |
+
+### Result
+
+```javascript
+{ kafka, producer, consumer, disconnect }
+```
+
+Call `await connection.disconnect()` to disconnect the producer and consumer.
+
+### Example
+
+```javascript
+import { kafkaConnect } from '@datastream/kafka'
+
+const { producer, consumer, disconnect } = await kafkaConnect({
+ brokers: ['localhost:9092'],
+ clientId: 'my-app',
+ groupId: 'my-group',
+})
+```
+
+## `kafkaProduceStream` Writable
+
+Batches messages and sends them to a topic. Returns a Promise resolving to the writable stream. Chunks may be a `Uint8Array`, a `string`, or a `{ value, key?, headers?, partition? }` message object.
+
+### Options
+
+| Option | Type | Default | Description |
+|--------|------|---------|-------------|
+| `producer` | `Producer` | — | Producer from `kafkaConnect` (required) |
+| `topic` | `string` | — | Destination topic (required) |
+| `batchSize` | `number` | `100` | Messages buffered before a `send` |
+| `acks` | `-1 \| 0 \| 1` | `-1` | Acknowledgements (`-1` = all in-sync replicas) |
+| `compression` | `0 \| 1 \| 2 \| 3 \| 4` | — | None, GZIP, Snappy, LZ4, ZSTD |
+| `timeout` | `number` | — | Per-request send timeout in ms |
+
+On a failed send the thrown error carries the un-sent batch on `err.failedMessages` so callers can re-queue instead of losing data.
+
+### Example
+
+```javascript
+import { pipeline, createReadableStream } from '@datastream/core'
+import { kafkaConnect, kafkaProduceStream } from '@datastream/kafka'
+
+const { producer } = await kafkaConnect({ brokers: ['localhost:9092'] })
+
+await pipeline([
+ createReadableStream([
+ { value: 'event-1' },
+ { value: 'event-2' },
+ ]),
+ await kafkaProduceStream({ producer, topic: 'events' }),
+])
+```
+
+## `kafkaConsumeStream` Readable
+
+Subscribes to one or more topics and emits each message as a chunk. Returns a Promise resolving to a readable stream with a `stop()` method. Backpressure propagates from the downstream consumer through kafkajs to the broker.
+
+### Options
+
+| Option | Type | Default | Description |
+|--------|------|---------|-------------|
+| `consumer` | `Consumer` | — | Consumer from `kafkaConnect` (required) |
+| `topics` | `string \| string[]` | — | Topic(s) to subscribe to (required) |
+| `fromBeginning` | `boolean` | `false` | Start from the earliest offset |
+| `autoCommit` | `boolean` | `true` | Auto-commit offsets |
+| `partitionsConsumedConcurrently` | `number` | `1` | Concurrent partition processing |
+| `signal` | `AbortSignal` | — | Aborting stops the consumer |
+
+### Emitted chunk
+
+```javascript
+{ topic, partition, offset, key, value, headers, timestamp }
+```
+
+### Example
+
+```javascript
+import { kafkaConnect, kafkaConsumeStream } from '@datastream/kafka'
+
+const { consumer } = await kafkaConnect({
+ brokers: ['localhost:9092'],
+ groupId: 'my-group',
+})
+
+const stream = await kafkaConsumeStream({ consumer, topics: 'events' })
+
+for await (const message of stream) {
+ console.log(message.value)
+}
+
+await stream.stop()
+```
+
+## Platform support
+
+Available on Node.js (via `kafkajs`). Not available in the browser.
diff --git a/websites/datastream.js.org/src/routes/docs/packages/protobuf/+page.md b/websites/datastream.js.org/src/routes/docs/packages/protobuf/+page.md
new file mode 100644
index 0000000..72a1a21
--- /dev/null
+++ b/websites/datastream.js.org/src/routes/docs/packages/protobuf/+page.md
@@ -0,0 +1,110 @@
+---
+title: protobuf
+description: Protobuf encode/decode and length-prefix framing streams.
+---
+
+Protobuf encode/decode transform streams and length-prefix framing for delimited Protobuf records. Works with a [protobufjs](https://protobufjs.github.io/protobuf.js/)-style `Type` (anything exposing `encode`, `decode`, and `create`).
+
+## Install
+
+```bash
+npm install @datastream/protobuf
+```
+
+Bring your own Protobuf runtime (for example `protobufjs`) to obtain message `Type` objects.
+
+## Type input
+
+Each encode/decode stream takes a `Type`. It may be:
+
+- a static `Type` value (cached on the hot path), or
+- a function `(chunk) => Type` (sync or async), re-invoked per chunk so you can select a different message type per record (for example from a Schema Registry envelope).
+
+## `protobufEncodeStream` Transform
+
+Encodes each incoming message object into Protobuf wire bytes (`Uint8Array`).
+
+### Options
+
+| Option | Type | Default | Description |
+|--------|------|---------|-------------|
+| `Type` | `Type \| (chunk) => Type` | — | Protobuf message type, or a per-chunk resolver (required) |
+
+### Example
+
+```javascript
+import { pipeline, createReadableStream } from '@datastream/core'
+import { protobufEncodeStream } from '@datastream/protobuf'
+
+await pipeline([
+ createReadableStream([{ id: 1, name: 'Alice' }]),
+ protobufEncodeStream({ Type: Person }),
+])
+```
+
+## `protobufDecodeStream` Transform
+
+Decodes Protobuf wire bytes into message objects.
+
+### Options
+
+| Option | Type | Default | Description |
+|--------|------|---------|-------------|
+| `Type` | `Type \| (chunk) => Type` | — | Protobuf message type, or a per-chunk resolver (required) |
+| `payload` | `(chunk) => Uint8Array` | identity | Extract the protobuf bytes from each chunk (e.g. from a registry envelope) |
+| `maxOutputSize` | `number` | — | Maximum total input bytes; decoding aborts with an error when exceeded |
+
+#### Output size protection
+
+Decoding untrusted Protobuf can amplify a small input into large objects. Set `maxOutputSize` to bound total decoded volume by input bytes and abort before memory is exhausted.
+
+### Example
+
+```javascript
+import { protobufDecodeStream } from '@datastream/protobuf'
+
+protobufDecodeStream({ Type: Person, maxOutputSize: 10 * 1024 * 1024 })
+```
+
+## `protobufLengthPrefixFrameStream` Transform
+
+Prefixes each chunk with a base-128 varint length, producing a self-delimiting stream of framed records (the same framing Kafka and gRPC-style transports use).
+
+## `protobufLengthPrefixUnframeStream` Transform
+
+Reassembles a varint-length-prefixed byte stream back into individual record frames. Handles records split across chunk boundaries.
+
+### Options
+
+| Option | Type | Default | Description |
+|--------|------|---------|-------------|
+| `maxMessageSize` | `number` | — | Reject any frame whose declared length exceeds this, aborting with an error |
+
+Throws on flush if trailing bytes do not form a complete frame, and on a varint that overflows.
+
+### Example
+
+```javascript
+import { pipeline, createReadableStream } from '@datastream/core'
+import {
+ protobufEncodeStream,
+ protobufLengthPrefixFrameStream,
+ protobufLengthPrefixUnframeStream,
+ protobufDecodeStream,
+} from '@datastream/protobuf'
+
+// Encode + frame on the way out
+await pipeline([
+ createReadableStream(messages),
+ protobufEncodeStream({ Type: Person }),
+ protobufLengthPrefixFrameStream(),
+ // ... write framed bytes
+])
+
+// Unframe + decode on the way in
+await pipeline([
+ framedByteStream,
+ protobufLengthPrefixUnframeStream({ maxMessageSize: 1 * 1024 * 1024 }),
+ protobufDecodeStream({ Type: Person }),
+])
+```
diff --git a/websites/datastream.js.org/src/routes/docs/packages/schema-registry/+page.md b/websites/datastream.js.org/src/routes/docs/packages/schema-registry/+page.md
new file mode 100644
index 0000000..4afc074
--- /dev/null
+++ b/websites/datastream.js.org/src/routes/docs/packages/schema-registry/+page.md
@@ -0,0 +1,98 @@
+---
+title: schema-registry
+description: Confluent and AWS Glue Schema Registry framing streams.
+---
+
+Framing and unframing transform streams for the Confluent and AWS Glue Schema Registry wire formats. Each input chunk is treated as one envelope (one Kafka message = one chunk = one framed record).
+
+## Install
+
+```bash
+npm install @datastream/schema-registry
+```
+
+## Confluent format
+
+5-byte header: a `0x00` magic byte followed by a big-endian unsigned 32-bit schema id, then the payload bytes.
+
+### `confluentFrameStream` Transform
+
+Prepends the Confluent header to each payload chunk.
+
+| Option | Type | Default | Description |
+|--------|------|---------|-------------|
+| `schemaId` | `number` | — | Unsigned 32-bit schema id (required) |
+| `resultKey` | `string` | `"confluentSchemaId"` | Key in pipeline result |
+
+### `confluentUnframeStream` Transform
+
+Validates the magic byte, reads the schema id, and emits a `{ schemaId, payload }` envelope.
+
+| Option | Type | Default | Description |
+|--------|------|---------|-------------|
+| `resultKey` | `string` | `"confluentSchemaId"` | Key in pipeline result |
+
+### Emitted envelope
+
+```javascript
+{ schemaId: number, payload: Uint8Array }
+```
+
+### Example
+
+```javascript
+import { pipeline, createReadableStream } from '@datastream/core'
+import { confluentUnframeStream } from '@datastream/schema-registry'
+import { protobufDecodeStream } from '@datastream/protobuf'
+
+await pipeline([
+ framedByteStream,
+ confluentUnframeStream(),
+ protobufDecodeStream({
+ // pick the Type per message from the envelope schemaId
+ Type: (envelope) => registry.get(envelope.schemaId),
+ payload: (envelope) => envelope.payload,
+ }),
+])
+```
+
+## Glue format
+
+18-byte header: a `0x03` magic byte, a 1-byte compression flag (`none` or `zlib`), and a 16-byte schema version UUID, then the payload bytes.
+
+### `glueFrameStream` Transform
+
+Prepends the Glue header to each payload chunk, optionally deflating the payload.
+
+| Option | Type | Default | Description |
+|--------|------|---------|-------------|
+| `schemaVersionId` | `string` | — | Schema version UUID (required) |
+| `compression` | `"none" \| "zlib"` | `"none"` | Payload compression |
+| `resultKey` | `string` | `"glueSchemaVersionId"` | Key in pipeline result |
+
+### `glueUnframeStream` Transform
+
+Validates the magic byte, reads the schema version UUID and compression flag, inflates `zlib` payloads, and emits a `{ schemaVersionId, compression, payload }` envelope.
+
+| Option | Type | Default | Description |
+|--------|------|---------|-------------|
+| `maxDecompressedBytes` | `number` | `10485760` (10MB) | Maximum decompressed payload size; aborts with an error when exceeded |
+| `resultKey` | `string` | `"glueSchemaVersionId"` | Key in pipeline result |
+
+#### Decompression protection
+
+A malicious zlib payload can expand to far more than its framed size. `maxDecompressedBytes` caps the inflated output and aborts before memory is exhausted. Always keep this bounded for untrusted input.
+
+### Emitted envelope
+
+```javascript
+{ schemaVersionId: string, compression: 'none' | 'zlib', payload: Uint8Array }
+```
+
+## Per-chunk envelopes vs `result()`
+
+Unframe streams emit `{ schemaId | schemaVersionId, payload }` envelopes downstream so a decoder can select the right schema per chunk. The `.result()` accessor is exposed for parity with the other detect streams, but it reflects only the most recently seen envelope and is racy under backpressure — prefer the per-chunk envelope when wiring a decoder.
+
+## Platform support
+
+Works on both Node.js and the browser; compression uses the platform `CompressionStream` / `DecompressionStream`.
From aea233c1ea90d5755df27c3c59bb2cba7c121f82 Mon Sep 17 00:00:00 2001
From: will Farrell
Date: Mon, 15 Jun 2026 06:56:43 -0600
Subject: [PATCH 18/27] chore: version bump
Signed-off-by: will Farrell
---
.github/package.json | 2 +-
package-lock.json | 2793 ++++++++++++++++++++++-
package.json | 2 +-
packages/arrow/package.json | 4 +-
packages/aws/package.json | 4 +-
packages/base64/package.json | 4 +-
packages/charset/package.json | 4 +-
packages/compress/package.json | 4 +-
packages/core/package.json | 4 +-
packages/csv/package.json | 6 +-
packages/digest/package.json | 4 +-
packages/duckdb/package.json | 6 +-
packages/encrypt/package.json | 4 +-
packages/fetch/package.json | 4 +-
packages/file/package.json | 4 +-
packages/indexeddb/package.json | 4 +-
packages/ipfs/package.json | 4 +-
packages/json/package.json | 4 +-
packages/kafka/package.json | 4 +-
packages/object/package.json | 4 +-
packages/protobuf/package.json | 4 +-
packages/schema-registry/package.json | 4 +-
packages/string/package.json | 4 +-
packages/validate/package.json | 4 +-
stryker.node-test.config.json | 20 +
websites/datastream.js.org/package.json | 2 +-
26 files changed, 2767 insertions(+), 140 deletions(-)
create mode 100644 stryker.node-test.config.json
diff --git a/.github/package.json b/.github/package.json
index 525ce17..debb2db 100644
--- a/.github/package.json
+++ b/.github/package.json
@@ -1,6 +1,6 @@
{
"name": "@datastream/github-workflows",
- "version": "0.5.0",
+ "version": "0.6.0",
"private": true,
"type": "module",
"engines": {
diff --git a/package-lock.json b/package-lock.json
index 2dc2ffa..00cdddb 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "@datastream/monorepo",
- "version": "0.5.0",
+ "version": "0.6.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@datastream/monorepo",
- "version": "0.5.0",
+ "version": "0.6.0",
"license": "MIT",
"workspaces": [
"packages/*",
@@ -31,7 +31,7 @@
},
".github": {
"name": "@datastream/github-workflows",
- "version": "0.5.0",
+ "version": "0.6.0",
"devDependencies": {
"license-check-and-add": "4.0.5",
"lockfile-lint": "5.0.0"
@@ -42,6 +42,8 @@
},
"node_modules/@apidevtools/json-schema-ref-parser": {
"version": "15.3.5",
+ "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-15.3.5.tgz",
+ "integrity": "sha512-orNOYXw3hYXxxisXMldjzjBzqqTLBPbwOtHg7ovBPvfBHDue1qM9YJENZ3W2BQuS+7z4ThogMbEzEsov57Itkg==",
"license": "MIT",
"dependencies": {
"js-yaml": "^4.1.1"
@@ -55,6 +57,8 @@
},
"node_modules/@aws-crypto/crc32": {
"version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-5.2.0.tgz",
+ "integrity": "sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -68,6 +72,8 @@
},
"node_modules/@aws-crypto/crc32c": {
"version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@aws-crypto/crc32c/-/crc32c-5.2.0.tgz",
+ "integrity": "sha512-+iWb8qaHLYKrNvGRbiYRHSdKRWhto5XlZUEBwDjYNf+ly5SVYG6zEoYIdxvf5R3zyeP16w4PLBn3rH1xc74Rag==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -78,6 +84,8 @@
},
"node_modules/@aws-crypto/sha1-browser": {
"version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@aws-crypto/sha1-browser/-/sha1-browser-5.2.0.tgz",
+ "integrity": "sha512-OH6lveCFfcDjX4dbAvCFSYUjJZjDr/3XJ3xHtjn3Oj5b9RjojQo8npoLeA/bNwkOkrSQ0wgrHzXk4tDRxGKJeg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -91,6 +99,8 @@
},
"node_modules/@aws-crypto/sha256-browser": {
"version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz",
+ "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -105,6 +115,8 @@
},
"node_modules/@aws-crypto/sha256-js": {
"version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz",
+ "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -118,6 +130,8 @@
},
"node_modules/@aws-crypto/supports-web-crypto": {
"version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-5.2.0.tgz",
+ "integrity": "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -126,6 +140,8 @@
},
"node_modules/@aws-crypto/util": {
"version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz",
+ "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -136,6 +152,8 @@
},
"node_modules/@aws-sdk/checksums": {
"version": "3.1000.5",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/checksums/-/checksums-3.1000.5.tgz",
+ "integrity": "sha512-zOXUUnilC6lgCsQtp77p/QNPmRlTES9Xi6tlDwbR6kfC/kz5PCzZckgHWm5z+8DskdwuMAbFDq61x3zr10GEEQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -154,6 +172,8 @@
},
"node_modules/@aws-sdk/client-cloudwatch-logs": {
"version": "3.1068.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudwatch-logs/-/client-cloudwatch-logs-3.1068.0.tgz",
+ "integrity": "sha512-3OlaC3Grl2fovhdEqkOTctcXIjrouwmY4a0Bkg7q7jgAwAP09/intv/RJ1RD/FDEq+xzV5tsWGKMFowN6idZhQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -174,6 +194,8 @@
},
"node_modules/@aws-sdk/client-cognito-identity": {
"version": "3.1068.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.1068.0.tgz",
+ "integrity": "sha512-by2Qj3f9BI9X4cY0n160R3uzkMpI6k9PmGA8QLAuzr8HzkiNrYFygMEPhIEdqBFHQPD/8AXNUs45HYjEDsQ33g==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -194,6 +216,8 @@
},
"node_modules/@aws-sdk/client-dynamodb": {
"version": "3.1068.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-dynamodb/-/client-dynamodb-3.1068.0.tgz",
+ "integrity": "sha512-DOMUWnLSFHaRC0EixpWMnrQcQaV08P5rzAUdRTEkx72NaDRF0Q6+3QdtqX8ocyHfySzwMwOE9/vHRmhNvWHl/g==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -216,6 +240,8 @@
},
"node_modules/@aws-sdk/client-dynamodb-streams": {
"version": "3.1068.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-dynamodb-streams/-/client-dynamodb-streams-3.1068.0.tgz",
+ "integrity": "sha512-8cbPgM++tpgsD+aj0azisy2Lyvb/9zu7iRd3SF2f64O8ea5mQP6wTRUWGNaPtuviBlogJZpCwJP5w0nrzFWtxQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -236,6 +262,8 @@
},
"node_modules/@aws-sdk/client-glue": {
"version": "3.1068.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-glue/-/client-glue-3.1068.0.tgz",
+ "integrity": "sha512-T/2aZGVaDDuSSQ3OWhWowBZ3P2hQGIV+16idxiA0Z8WevLWgbzztSGScDyYa7ohe/J/BY0XiYsBavLYtv+yGlg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -256,6 +284,8 @@
},
"node_modules/@aws-sdk/client-kinesis": {
"version": "3.1068.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-kinesis/-/client-kinesis-3.1068.0.tgz",
+ "integrity": "sha512-0+5P4CJFf/K5/EBxzRR97OLeQqe3GazyCjV47/ksyTnfr+Bif2UhvZ2Kq6c+s/dqie6LPP4NFAB5Q8D/TZ3+og==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -276,6 +306,8 @@
},
"node_modules/@aws-sdk/client-lambda": {
"version": "3.1068.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-lambda/-/client-lambda-3.1068.0.tgz",
+ "integrity": "sha512-GitXCytcrvezkAQbyT+cYMrGPCM9zdh9sU8FrQr1vyniVijXk2X4ZBf2WZwDQcenNPMJyN5YdtUAbmUJCrfZDg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -296,6 +328,8 @@
},
"node_modules/@aws-sdk/client-s3": {
"version": "3.1068.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.1068.0.tgz",
+ "integrity": "sha512-lFgaIpxZvloNbJvQ337YPdMXhzI2zJdDw13nATVGnkAGNoNPx4ksD84AQAcuW75hsaaMaIuNmXU9sSx6+FTirA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -320,6 +354,8 @@
},
"node_modules/@aws-sdk/client-sns": {
"version": "3.1068.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-sns/-/client-sns-3.1068.0.tgz",
+ "integrity": "sha512-xIjKGG2yzUhX+IHqq0B/8D6zKKr32+LmYUy/OnV5dDj+j+eUJD7J3Ca6kMVDPI6eWe/fCtdHCgsnZtxhf1LMqg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -340,6 +376,8 @@
},
"node_modules/@aws-sdk/client-sqs": {
"version": "3.1068.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-sqs/-/client-sqs-3.1068.0.tgz",
+ "integrity": "sha512-hatCfVf61RsSO5Qjrf7JKln4KiPDprXNJhpx9DNOmyeW1v+i7KNhbawk4d1wAnQ72YciOfhAhyRFec6UZqcnzQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -361,6 +399,8 @@
},
"node_modules/@aws-sdk/client-sts": {
"version": "3.1068.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.1068.0.tgz",
+ "integrity": "sha512-WCUEpfdsSSO7zsXi7GUwHR+A5HZDQNsGktFJxOm73ZU+WLlBKRDzKdWZdYOpNkgBpXxy5KCeVMvXuaq2s1zn7w==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -382,6 +422,8 @@
},
"node_modules/@aws-sdk/core": {
"version": "3.974.20",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.974.20.tgz",
+ "integrity": "sha512-7sDi2B2N3mc3nf1nz6FyEx/FCrJ1N1QnBmraHHQNabFaeAh2IaOOLml48/rHOD1bICHgTRkbBgNTvUzEr5Z35g==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -400,6 +442,8 @@
},
"node_modules/@aws-sdk/credential-provider-cognito-identity": {
"version": "3.972.45",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.972.45.tgz",
+ "integrity": "sha512-4L/REssieLON1hVsTzZucP1p2u5jmPNejyh/9BCGZXr93IalBbhRPCrtKIKwMTu9yRGr/bcKzhrQocByKLSzLQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -415,6 +459,8 @@
},
"node_modules/@aws-sdk/credential-provider-env": {
"version": "3.972.46",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.46.tgz",
+ "integrity": "sha512-+GPXVS2srMOlH74S+SmC1gVuP2TvUZ0siuC0onKO93q+udP+M72dmY8wJfVQ5CX9z/9X5A1HHwz5yRIGBtskvQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -430,6 +476,8 @@
},
"node_modules/@aws-sdk/credential-provider-http": {
"version": "3.972.48",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.48.tgz",
+ "integrity": "sha512-fA5loSdlocacRxyUXtpoHSMuk5rsIKRDzQYVMnMxjcmFeZshaJlJ8lymy/hYKji6sne/UmNGj5pxuEs6kq/Qcg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -447,6 +495,8 @@
},
"node_modules/@aws-sdk/credential-provider-ini": {
"version": "3.972.53",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.972.53.tgz",
+ "integrity": "sha512-ZfdhIOR41q8TcWEnUac+gCOb+O2LBWdHLmjedXpXz4IEFW2ppNuFcm6p0sMTavpM+zD5TYfpH5Gp7guRyqSgsQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -470,6 +520,8 @@
},
"node_modules/@aws-sdk/credential-provider-login": {
"version": "3.972.52",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.52.tgz",
+ "integrity": "sha512-9hu2oR0qH7Fst5Tzdx+UWxm+w5zCXtErTLtOOW5hwwQc170CLwOeniRxyFY6s9mHfGEfC5zFukNBdKBwJR8mhQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -486,6 +538,8 @@
},
"node_modules/@aws-sdk/credential-provider-node": {
"version": "3.972.55",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.55.tgz",
+ "integrity": "sha512-zMGLa/dhESVqmCD7mmIFFKSwSFrJGScvCXcjvBZEVOOMauFS5JRQvLTMukFpMEFWiV6dTAlsen2ATDBulLPtbg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -507,6 +561,8 @@
},
"node_modules/@aws-sdk/credential-provider-process": {
"version": "3.972.46",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.46.tgz",
+ "integrity": "sha512-VUoNFBIjWrUN8NbFiQiuxQEgFjvziAlBRPK+ddh27aj65gk0BYu6bLZnrdrNZwpW6vAihtSUtEMQ1PUJ32QRPA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -522,6 +578,8 @@
},
"node_modules/@aws-sdk/credential-provider-sso": {
"version": "3.972.52",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.972.52.tgz",
+ "integrity": "sha512-nb2/n4o/HQf+FVpVbZe9vCTFngmuDoIsltMgLAtjixaKzvzhB4J8WSDFyWgnErgLHk55ctWH+I4PU+LIHhyffg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -539,6 +597,8 @@
},
"node_modules/@aws-sdk/credential-provider-web-identity": {
"version": "3.972.52",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.52.tgz",
+ "integrity": "sha512-lKj6aRSGbqLmpYmM24bY7a1Xmfcq2vkE3hv8CSPYfc1yCu0BPu/XEJ1L4Fm61MsU6ULLNSG8UGsffNoFUBjESA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -555,6 +615,8 @@
},
"node_modules/@aws-sdk/credential-providers": {
"version": "3.1068.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.1068.0.tgz",
+ "integrity": "sha512-DN7UewD/XKGfNGWXZsTECWRj3IsULkE7aG+fPwqPf13CnX4UmNvj80g1xieJ0lVdMQ2h0L3gZpn2ClIY06+/vQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -582,6 +644,8 @@
},
"node_modules/@aws-sdk/dynamodb-codec": {
"version": "3.973.20",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/dynamodb-codec/-/dynamodb-codec-3.973.20.tgz",
+ "integrity": "sha512-SFfxiqVgWeIe+RsJJNAMD//2IfehT4bLpGyNJRB0MgHmOIJtdcfMnR1k7KYyaHokSoQVdncVa9O9DIGa4eqcwg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -596,6 +660,8 @@
},
"node_modules/@aws-sdk/endpoint-cache": {
"version": "3.972.7",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/endpoint-cache/-/endpoint-cache-3.972.7.tgz",
+ "integrity": "sha512-LkwS3ZOUNL5kHzmz3dDx8lE3HOhZmf2VGjbJ/tMUZJYWWl3J0RJTZM7RFz1MLt06WDVvlShcAjY/RzhYlqLL7g==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -608,6 +674,8 @@
},
"node_modules/@aws-sdk/lib-storage": {
"version": "3.1068.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/lib-storage/-/lib-storage-3.1068.0.tgz",
+ "integrity": "sha512-BGUS3EXFe+y87odXsC5enyBv4z/QT3EDydv+iTe9hCUr57ndAXCfJbvcm3f+s3aHS5FUDL3WozaBAcrsNeVhyQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -627,6 +695,8 @@
},
"node_modules/@aws-sdk/middleware-endpoint-discovery": {
"version": "3.972.18",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-endpoint-discovery/-/middleware-endpoint-discovery-3.972.18.tgz",
+ "integrity": "sha512-1vKJt/6MBB/MBMRM3qzCMdW70syJY8u2DH+dq7yCnPn7wVJmyeAzAa/sK1lIbbYh8BVLbM5FspsT4zbe885gOw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -642,6 +712,8 @@
},
"node_modules/@aws-sdk/middleware-flexible-checksums": {
"version": "3.974.30",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.974.30.tgz",
+ "integrity": "sha512-OaIhub+3yTgfFWPzKO8OzOZFIMUoJaiS5v67y3spQg7SoULGoMx4jKVBbE+uhnzkiZXQ+rEDS0RqrK4/aD1yJw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -654,6 +726,8 @@
},
"node_modules/@aws-sdk/middleware-sdk-s3": {
"version": "3.972.51",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.972.51.tgz",
+ "integrity": "sha512-keQgcIUTcHL0Qn7guhsuLaxQU36r9norCrxgaPH4DNCwon4TPtXdI/UdYuycl9vj3Dlwc3YR1dfL3U+6iIwJ6w==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -670,6 +744,8 @@
},
"node_modules/@aws-sdk/middleware-sdk-sqs": {
"version": "3.972.30",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sqs/-/middleware-sdk-sqs-3.972.30.tgz",
+ "integrity": "sha512-PVAj7VgWK/ZxCXnkgC4B7cdJyUN99Nsr7IEduHt4A1GieuB+ZnU5bSifHwapbr17wrFkmdxfSh+aA0Lj+Ads6w==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -684,6 +760,8 @@
},
"node_modules/@aws-sdk/nested-clients": {
"version": "3.997.20",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.997.20.tgz",
+ "integrity": "sha512-IYJuLpXp2DEILVQpQOy0PMpkftv0AHEOCn52o0atyOaumA0CdWQ3klPyXdViGYLbNpESsVFMVybvHUeZAuiGxA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -704,6 +782,8 @@
},
"node_modules/@aws-sdk/signature-v4-multi-region": {
"version": "3.996.34",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.996.34.tgz",
+ "integrity": "sha512-mx1L5qlumSOt/nKM3BFaHE2HVkWwz0i4Bw0pyYO42FfX/FeLlo8YI6csC0gSPprEk6fTIqI+CZN9RwUwKd5krQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -718,6 +798,8 @@
},
"node_modules/@aws-sdk/token-providers": {
"version": "3.1066.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.1066.0.tgz",
+ "integrity": "sha512-UqEUJq7dqa44hneLDUcX7UJy95cg8YqEWyakRpvIPnrNS3Mq+UlQHgCDGu5pvwAPtlIW4qcYbvW6reG6++FyvA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -734,6 +816,8 @@
},
"node_modules/@aws-sdk/types": {
"version": "3.973.12",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.973.12.tgz",
+ "integrity": "sha512-43ajd1NF0RMgX5k0hxCNUyEdrtFUsb2aHT2QvpktSC/2Eyb2Jr/JPVqdp0XIoaHWikZJq5tNWSLO6kB5q2eMCA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -746,6 +830,8 @@
},
"node_modules/@aws-sdk/util-format-url": {
"version": "3.972.22",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/util-format-url/-/util-format-url-3.972.22.tgz",
+ "integrity": "sha512-ygzBtG3xDxvMWTg3EjlZ5FSYxUiRCsCZvKPk+sOhXeMcDTdzPqIGQipiUiIYJm/Om8h8qXyhchMb0baW1PhE+w==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -758,6 +844,8 @@
},
"node_modules/@aws-sdk/util-locate-window": {
"version": "3.965.7",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.965.7.tgz",
+ "integrity": "sha512-M0D6oIpohdNHjc7udzTHEQyot0+0iuA36jc2I9Hps+f/GtKi2HO/pyijQnCnNcwZqLB5+rtn81z3eZK/GyjAmA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -769,6 +857,8 @@
},
"node_modules/@aws-sdk/util-utf8-browser": {
"version": "3.259.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.259.0.tgz",
+ "integrity": "sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -777,6 +867,8 @@
},
"node_modules/@aws-sdk/xml-builder": {
"version": "3.972.29",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.29.tgz",
+ "integrity": "sha512-fk0niuGFxfi8yIJuMVM4mhwObkiQSuwZFj3tAPrLVx64Pk3BkrEIpqjzHKY4hKoEBUD6Jg/S74Zj9jy+5F3DnQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -790,6 +882,8 @@
},
"node_modules/@aws/lambda-invoke-store": {
"version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/@aws/lambda-invoke-store/-/lambda-invoke-store-0.2.4.tgz",
+ "integrity": "sha512-iY8yvjE0y651BixKNPgmv1WrQc+GZ142sb0z4gYnChDDY2YqI4P/jsSopBWrKfAt7LOJAkOXt7rC/hms+WclQQ==",
"dev": true,
"license": "Apache-2.0",
"engines": {
@@ -798,6 +892,8 @@
},
"node_modules/@babel/code-frame": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz",
+ "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -811,6 +907,8 @@
},
"node_modules/@babel/compat-data": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz",
+ "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -819,6 +917,8 @@
},
"node_modules/@babel/core": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz",
+ "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -848,6 +948,8 @@
},
"node_modules/@babel/core/node_modules/semver": {
"version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true,
"license": "ISC",
"bin": {
@@ -856,6 +958,8 @@
},
"node_modules/@babel/generator": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.7.tgz",
+ "integrity": "sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -871,6 +975,8 @@
},
"node_modules/@babel/helper-annotate-as-pure": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.29.7.tgz",
+ "integrity": "sha512-OoK6239jHPuSQOoS0kfTVKn0b/rVTk0seKq4Gd2UMLtmOVLjDC0ki3e+c90Trqv2gMfvJFqkiljrr568+qddiw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -882,6 +988,8 @@
},
"node_modules/@babel/helper-compilation-targets": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz",
+ "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -897,6 +1005,8 @@
},
"node_modules/@babel/helper-compilation-targets/node_modules/semver": {
"version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true,
"license": "ISC",
"bin": {
@@ -905,6 +1015,8 @@
},
"node_modules/@babel/helper-create-class-features-plugin": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.29.7.tgz",
+ "integrity": "sha512-IY3ZD9Tmooqr3TUhc3DUWxiuo8xx1DWLhd5M7hQ+ZWJamqM2BbalrBJb2MisSLoYorOj75U03qULCxQTY9r3hg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -925,6 +1037,8 @@
},
"node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": {
"version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true,
"license": "ISC",
"bin": {
@@ -933,6 +1047,8 @@
},
"node_modules/@babel/helper-globals": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz",
+ "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -941,6 +1057,8 @@
},
"node_modules/@babel/helper-member-expression-to-functions": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.29.7.tgz",
+ "integrity": "sha512-j+7JYmk1JYDtACIGj0QJqqWZjoUpMoEikQGADMaHgCMCSDqd2+P32rfcibUNrGOMWrlzK1WJBdxrB3JJQZwWtg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -953,6 +1071,8 @@
},
"node_modules/@babel/helper-module-imports": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz",
+ "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -965,6 +1085,8 @@
},
"node_modules/@babel/helper-module-transforms": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz",
+ "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -981,6 +1103,8 @@
},
"node_modules/@babel/helper-optimise-call-expression": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.29.7.tgz",
+ "integrity": "sha512-+kmGVjcT9RGYzoDwdwEqEvGgKe3BYq+O1iGzjFubaNgZHwYHP6lsF2Yghf4kEuv9BV7tYDZ913aBW9am6YKong==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -992,6 +1116,8 @@
},
"node_modules/@babel/helper-plugin-utils": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz",
+ "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -1000,6 +1126,8 @@
},
"node_modules/@babel/helper-replace-supers": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.29.7.tgz",
+ "integrity": "sha512-atfGXWSeCiF4DnKZIfmJfQRkSw9b9gNNXR1kqKjbhG4pGYCOnkp8OcTB8E3NXjBu8NpheSnOeNKz8KT7UNFTmQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1016,6 +1144,8 @@
},
"node_modules/@babel/helper-skip-transparent-expression-wrappers": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.29.7.tgz",
+ "integrity": "sha512-brcMGQaVzIeUb+6/bs1Av0f8YuNNjKY2JyvfRCsFuFsdKccEQ5Ges2y74D74NZ1Rz8lKJ9ksJkfqwQFJ/iNEyQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1028,6 +1158,8 @@
},
"node_modules/@babel/helper-string-parser": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz",
+ "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -1036,6 +1168,8 @@
},
"node_modules/@babel/helper-validator-identifier": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz",
+ "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -1044,6 +1178,8 @@
},
"node_modules/@babel/helper-validator-option": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz",
+ "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -1052,6 +1188,8 @@
},
"node_modules/@babel/helpers": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz",
+ "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1064,6 +1202,8 @@
},
"node_modules/@babel/parser": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz",
+ "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1078,6 +1218,8 @@
},
"node_modules/@babel/plugin-proposal-decorators": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.29.7.tgz",
+ "integrity": "sha512-EtU0Hi3GvrTqD56xKmZvV/uCXK2ZbwVNPNLAquVItcAZpUhkXwWlo3Fmj0c2LxgSf2I8IDULeAepwNP1OefLXg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1094,6 +1236,8 @@
},
"node_modules/@babel/plugin-syntax-decorators": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.29.7.tgz",
+ "integrity": "sha512-9MTTLbF39X6sqM92JPEsoI7++26hjZvzkxKZy64aMhWLH2mPkJ/Q3AV4QLmls3R14FpSpkOwQQfUh962JGQxxg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1108,6 +1252,8 @@
},
"node_modules/@babel/plugin-syntax-jsx": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.29.7.tgz",
+ "integrity": "sha512-TSu8+mHCoEaaCDEZ0I3+6mvTBYR4PCxQwf2z9/r5Tbztv6NaLR3B9thGTTxX2WGuGHJqRiAbKPeGTJ5XWXVg6A==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1122,6 +1268,8 @@
},
"node_modules/@babel/plugin-syntax-typescript": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.29.7.tgz",
+ "integrity": "sha512-ngr+82Sh0xMz25TPCZi+nC2iTzjfCdWS2ONXTp/PtSCHCgaCNBpdMqgvJ2ccdLlClVZ7sisIgB914j/JFe+RZA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1136,6 +1284,8 @@
},
"node_modules/@babel/plugin-transform-destructuring": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.29.7.tgz",
+ "integrity": "sha512-iPX8aD6H9zV5s7ZsqTdNocPN/MGQ5sSMnElKrktxjJRMnB2jN/1p2+R7GkfD6CAYoVFqy5A4XnSIUeGgJzIWpg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1151,6 +1301,8 @@
},
"node_modules/@babel/plugin-transform-explicit-resource-management": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-explicit-resource-management/-/plugin-transform-explicit-resource-management-7.29.7.tgz",
+ "integrity": "sha512-Rstj7coNz8sE+7Ju7ihpHLI564lsK5pUpNNlvptCIC/16E/S5hbl6n3kESPKdNRmqEWlpn5xpS5Q2dvXBsySLw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1166,6 +1318,8 @@
},
"node_modules/@babel/plugin-transform-modules-commonjs": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.29.7.tgz",
+ "integrity": "sha512-j0vCldybPC5b5dwCQOJ21uKtHzt7hxLygJTg9eF1ScfaikEDNfzn94XoW5Fi+seBR0nCyL23xaBFFkq7dTM8XQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1181,6 +1335,8 @@
},
"node_modules/@babel/plugin-transform-typescript": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.29.7.tgz",
+ "integrity": "sha512-jK52h8LaLc7JarhQV2ofeFMts4H7vnOXnqZNA6fYglBTZewRBE51KWt3BUltW1P+KoPsYkHoJeXePuz4zo2LMw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1199,6 +1355,8 @@
},
"node_modules/@babel/preset-typescript": {
"version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.28.5.tgz",
+ "integrity": "sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1217,6 +1375,8 @@
},
"node_modules/@babel/runtime": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz",
+ "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -1225,6 +1385,8 @@
},
"node_modules/@babel/template": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz",
+ "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1238,6 +1400,8 @@
},
"node_modules/@babel/traverse": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.7.tgz",
+ "integrity": "sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1255,6 +1419,8 @@
},
"node_modules/@babel/types": {
"version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz",
+ "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1267,6 +1433,8 @@
},
"node_modules/@biomejs/biome": {
"version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.5.0.tgz",
+ "integrity": "sha512-4kURkd9hAPrdDM3C9n82ycYgx8hvQcW6MjKTEejruj8rK0N8P3OPpdy8BvI8kt3KWY4ycF5XtDOrktetEfhfuw==",
"dev": true,
"license": "MIT OR Apache-2.0",
"bin": {
@@ -1292,6 +1460,8 @@
},
"node_modules/@biomejs/cli-darwin-arm64": {
"version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.5.0.tgz",
+ "integrity": "sha512-Mn3Fwi3SA5fgmfCPqmzpWF2DLZnms3BVAhM088nTnGrTZmHS3wwIjcoZPqpXeNgd3DrrLH6xp8vTLIBuJoZiXw==",
"cpu": [
"arm64"
],
@@ -1438,6 +1608,8 @@
},
"node_modules/@cloudflare/kv-asset-handler": {
"version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/@cloudflare/kv-asset-handler/-/kv-asset-handler-0.5.0.tgz",
+ "integrity": "sha512-jxQYkj8dSIzc0cD6cMMNdOc1UVjqSqu8BZdor5s8cGjW2I8BjODt/kWPVdY+u9zj3ms75Q5qaZgnxUad83+eAg==",
"dev": true,
"license": "MIT OR Apache-2.0",
"engines": {
@@ -1446,6 +1618,8 @@
},
"node_modules/@cloudflare/unenv-preset": {
"version": "2.16.1",
+ "resolved": "https://registry.npmjs.org/@cloudflare/unenv-preset/-/unenv-preset-2.16.1.tgz",
+ "integrity": "sha512-ECxObrMfyTl5bhQf/lZCXwo5G6xX9IAUo+nDMKK4SZ8m4Jvvxp52vilxyySSWh2YTZz8+HQ07qGH/2rEom1vDw==",
"dev": true,
"license": "MIT OR Apache-2.0",
"peerDependencies": {
@@ -1458,8 +1632,27 @@
}
}
},
+ "node_modules/@cloudflare/workerd-darwin-64": {
+ "version": "1.20260611.1",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20260611.1.tgz",
+ "integrity": "sha512-iJICldmi4sBGgi7IrQles8cStOGXM/Tmv95C4OODVs6VIbMsJPqThUM5h3uYVQNULuJ8I/aVvnJ3Eh/wZCKwuA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=16"
+ }
+ },
"node_modules/@cloudflare/workerd-darwin-arm64": {
"version": "1.20260611.1",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20260611.1.tgz",
+ "integrity": "sha512-yBbVXvbZyltR3I7NJdC4C4ItkItjZSiabcA/3HzEWOUQjLVKFqRh4so6ToHr70VCYh8VGeR8EDZL23igLhXqFQ==",
"cpu": [
"arm64"
],
@@ -1473,13 +1666,68 @@
"node": ">=16"
}
},
+ "node_modules/@cloudflare/workerd-linux-64": {
+ "version": "1.20260611.1",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20260611.1.tgz",
+ "integrity": "sha512-PfNjpxOlaIgZFYuhD7+neEEewCN2Ud993wEEN0fmbtSOax1AK53LGqmXUDvFhnbkHxJLFAxYCSNISW8QbzaAIg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@cloudflare/workerd-linux-arm64": {
+ "version": "1.20260611.1",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20260611.1.tgz",
+ "integrity": "sha512-GEp4XbuIKjlF8pakqXcUDJfKiJosD/Q7S83J0d+r+z9XIlYGfF3ntm08e2aiF5TFTwp3fnG4yMoPUAKNhNJpvQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@cloudflare/workerd-windows-64": {
+ "version": "1.20260611.1",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20260611.1.tgz",
+ "integrity": "sha512-S6JkS0kEbcCKs19RGqEPhjCRbP8GBkQwqYLp2fhBJtD/KTlwqLzOJ9E6PQ7gQKgWHtxy1NBG3oXarlNFRNU/dw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=16"
+ }
+ },
"node_modules/@cloudflare/workers-types": {
"version": "4.20260615.1",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20260615.1.tgz",
+ "integrity": "sha512-fGOiTwoLj/8bU8mj3VAfa1EULx4ceZhDwnjvY+afDBlSXI9pvY7PE9t62rGEhJjbAOGd7i5WUDun0eZCWBDrzg==",
"dev": true,
"license": "MIT OR Apache-2.0"
},
"node_modules/@commitlint/cli": {
"version": "21.0.2",
+ "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-21.0.2.tgz",
+ "integrity": "sha512-YMmfLbqBg+ZRvvmPhc+cilSQFrh/AgzVgCT1U/OifmUZEwPbvCtA8rN//YNaF9d5eoZphxVMGYtmwA2QgQORgg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1500,6 +1748,8 @@
},
"node_modules/@commitlint/config-conventional": {
"version": "21.0.2",
+ "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-21.0.2.tgz",
+ "integrity": "sha512-P/ZRhryQmkj0Z0dY9FOoRwe3xkwJyyAdtXwt01NT2kuZttcG2CNYp1q5Ci3u+nDT2jcbJRw2kt13Czl1qKNPfg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1512,6 +1762,8 @@
},
"node_modules/@commitlint/config-validator": {
"version": "21.0.1",
+ "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-21.0.1.tgz",
+ "integrity": "sha512-Zd2UFdndeMMaW2O96HK0tdfT4gOImUvidMpAd/pws2zZ4m1nrAZ/9b/v2JYuE8fs86GpXv9F7LNaIuCIWhY+pA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1524,6 +1776,8 @@
},
"node_modules/@commitlint/ensure": {
"version": "21.0.1",
+ "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-21.0.1.tgz",
+ "integrity": "sha512-jJ1037967wU7YN/xkv+iRlOBlmaOXPhPO5KQSqya6GyXzBlwuLzELBFao16DVg9dZyqmNrhewzwZ3SAibetHBQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1536,6 +1790,8 @@
},
"node_modules/@commitlint/execute-rule": {
"version": "21.0.1",
+ "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-21.0.1.tgz",
+ "integrity": "sha512-RifH+FmImozKBE6mozhF4K3r2RRKP7SMi/Q/zLCmExtp5e05lhHOUYqGBlFBAGNHaZxU/WYw1XuugYK9jQzqnA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -1544,6 +1800,8 @@
},
"node_modules/@commitlint/format": {
"version": "21.0.1",
+ "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-21.0.1.tgz",
+ "integrity": "sha512-ksmG2+cHGtuDPQQbhBbC4unwm444+6TiPw0d1bKf67hntgZqZ8E0g1MuYKUuyT5IH4IMmXZhKq22/Z3jBvtQIw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1556,6 +1814,8 @@
},
"node_modules/@commitlint/is-ignored": {
"version": "21.0.2",
+ "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-21.0.2.tgz",
+ "integrity": "sha512-H5z4t8PC9tUsmZ/o+EptM3Nq8sTFtskAShdcqxCoyzklW5eaVT5xbrDAET2uypzir9Vsj4ZZmBtyKjYe2XqgeQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1568,6 +1828,8 @@
},
"node_modules/@commitlint/lint": {
"version": "21.0.2",
+ "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-21.0.2.tgz",
+ "integrity": "sha512-PnUmLYGeGLfW8oVatR9KpNxSHYAnJOEWlMZzfdeFOUq6WUrFx1fGQaWCWJqMoIll/xPM+GdfJV+tKHZVHhl0Fg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1582,6 +1844,8 @@
},
"node_modules/@commitlint/load": {
"version": "21.0.2",
+ "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-21.0.2.tgz",
+ "integrity": "sha512-lwUE70hN0/qE/ZRROhbaX65ly/FF12DrqfReLCESo37M0OQCFAf2jRS+2tSCSORq+bm4Kdju7qNDj46uc1QzTA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1601,6 +1865,8 @@
},
"node_modules/@commitlint/message": {
"version": "21.0.2",
+ "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-21.0.2.tgz",
+ "integrity": "sha512-5n4aqHGD/FNnom/D5L8i7cYtV+xjuXcBL832C3w9VglEsZzIsoHpJsvxzJ7cgiOsOdc/2jU4t5+7qMHh7GBX3g==",
"dev": true,
"license": "MIT",
"engines": {
@@ -1609,6 +1875,8 @@
},
"node_modules/@commitlint/parse": {
"version": "21.0.2",
+ "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-21.0.2.tgz",
+ "integrity": "sha512-QVZJhGHTm+oiuWyEKOCTQ0ZM3mfJ0eGWFeHuj7WzSKEth+UukcCHac9GD8pgdFlg/qGkFWOtyaNd1T8REgagaw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1622,6 +1890,8 @@
},
"node_modules/@commitlint/read": {
"version": "21.0.2",
+ "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-21.0.2.tgz",
+ "integrity": "sha512-BtsrnLVycSSKf4Q0gMch4giCj5NNlmcbhc8ra5vONgGtP2IjRDo33bEFtr5Pm+2N+5fXGWb2MksWPrspPfdhdw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1636,6 +1906,8 @@
},
"node_modules/@commitlint/resolve-extends": {
"version": "21.0.1",
+ "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-21.0.1.tgz",
+ "integrity": "sha512-0DhjYWL6uYrY16Efa032fYk3woGJDU4AGWiG1XXltT9AMUNYKyb5cIZU2ivbaMZ3+kKFqUjikD2cjh66Sbh/Sg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1651,6 +1923,8 @@
},
"node_modules/@commitlint/rules": {
"version": "21.0.2",
+ "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-21.0.2.tgz",
+ "integrity": "sha512-k6tQ69Td7t2qUSIbik8D3TL1q3ZJpkEbV+yLogDzCRAdOxJm4ndhtBNREsLA1/puRfWvzS9eioF2w43WT+hHgQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1665,6 +1939,8 @@
},
"node_modules/@commitlint/to-lines": {
"version": "21.0.1",
+ "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-21.0.1.tgz",
+ "integrity": "sha512-bd1BFII7p1EQZre9Kaj+kKaMFP3cFCdt21K7DItVux9XP5WjLgJ0/Uy1pJJh9aPwVJ6SKg62PxqlZaHI8hQAXw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -1673,6 +1949,8 @@
},
"node_modules/@commitlint/top-level": {
"version": "21.0.2",
+ "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-21.0.2.tgz",
+ "integrity": "sha512-s9KKM+e+mXgFeIh4n7KmOGAVT3mkJ3Fp1bBYHIK5pjeUwlEMzp/tZfb5u0Poa680AsQTXMEMRxZi1vQ9m2X5ug==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1684,6 +1962,8 @@
},
"node_modules/@commitlint/types": {
"version": "21.0.1",
+ "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-21.0.1.tgz",
+ "integrity": "sha512-4u7w8jcoCUFWhjWnASYzZHAP34OqOtuFBN87nQmFvqda03YU0T6z+yB4w0gSAMpekiRqqGk5rt+qSlW+a2vSEg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1696,6 +1976,8 @@
},
"node_modules/@conventional-changelog/git-client": {
"version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/@conventional-changelog/git-client/-/git-client-2.7.0.tgz",
+ "integrity": "sha512-j7A8/LBEQ+3rugMzPXoKYzyUPpw/0CBQCyvtTR7Lmu4olG4yRC/Tfkq79Mr3yuPs0SUitlO2HwGP3gitMJnRFw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1721,6 +2003,8 @@
},
"node_modules/@cspotcode/source-map-support": {
"version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
+ "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1732,6 +2016,8 @@
},
"node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": {
"version": "0.3.9",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
+ "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1829,6 +2115,8 @@
},
"node_modules/@duckdb/duckdb-wasm": {
"version": "1.33.1-dev45.0",
+ "resolved": "https://registry.npmjs.org/@duckdb/duckdb-wasm/-/duckdb-wasm-1.33.1-dev45.0.tgz",
+ "integrity": "sha512-ETlrjhiGQzNdaOhpro/Y9u/RCcK+iyuczLy7uOn0kG5Mqlj8C+gTuhBXjs4JpK9ocdUgr3oT8zYYIbUnFD9AYA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1838,6 +2126,8 @@
},
"node_modules/@duckdb/duckdb-wasm/node_modules/@types/node": {
"version": "20.19.43",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.43.tgz",
+ "integrity": "sha512-6oYBAi5ikg4Pl+kGsoYtawUMBT2zZMCvPNF7pVLnHZfd1zf38DRiWn/gT01RYCdUqkv7Fhr+C9ot4/tb+2sVvA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1846,6 +2136,8 @@
},
"node_modules/@duckdb/duckdb-wasm/node_modules/apache-arrow": {
"version": "17.0.0",
+ "resolved": "https://registry.npmjs.org/apache-arrow/-/apache-arrow-17.0.0.tgz",
+ "integrity": "sha512-X0p7auzdnGuhYMVKYINdQssS4EcKec9TCXyez/qtJt32DrIMGbzqiaMiQ0X6fQlQpw8Fl0Qygcv4dfRAr5Gu9Q==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -1865,6 +2157,8 @@
},
"node_modules/@duckdb/duckdb-wasm/node_modules/array-back": {
"version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz",
+ "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==",
"dev": true,
"license": "MIT",
"engines": {
@@ -1873,6 +2167,8 @@
},
"node_modules/@duckdb/duckdb-wasm/node_modules/command-line-args": {
"version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.1.tgz",
+ "integrity": "sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1887,6 +2183,8 @@
},
"node_modules/@duckdb/duckdb-wasm/node_modules/find-replace": {
"version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz",
+ "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1898,11 +2196,15 @@
},
"node_modules/@duckdb/duckdb-wasm/node_modules/flatbuffers": {
"version": "24.12.23",
+ "resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-24.12.23.tgz",
+ "integrity": "sha512-dLVCAISd5mhls514keQzmEG6QHmUUsNuWsb4tFafIUwvvgDjXhtfAYSKOzt5SWOy+qByV5pbsDZ+Vb7HUOBEdA==",
"dev": true,
"license": "Apache-2.0"
},
"node_modules/@duckdb/duckdb-wasm/node_modules/typical": {
"version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz",
+ "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -1911,11 +2213,15 @@
},
"node_modules/@duckdb/duckdb-wasm/node_modules/undici-types": {
"version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
+ "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
"dev": true,
"license": "MIT"
},
"node_modules/@duckdb/node-api": {
"version": "1.5.3-r.1",
+ "resolved": "https://registry.npmjs.org/@duckdb/node-api/-/node-api-1.5.3-r.1.tgz",
+ "integrity": "sha512-Z68b/SfFoECdmVNis708kGoamabox1NezejKyU6bPucoTig8DNTAVKU9R9gT4wl5c5qZ3RUy+jpe6F5Xa6Z3Iw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1924,6 +2230,8 @@
},
"node_modules/@duckdb/node-bindings": {
"version": "1.5.3-r.1",
+ "resolved": "https://registry.npmjs.org/@duckdb/node-bindings/-/node-bindings-1.5.3-r.1.tgz",
+ "integrity": "sha512-vDMuaEFd0JnboKdDw8hSN47OS0u3hw++YCCApPM3uYCFFuIK0RKXTqKe0pTLEMo4IIv3qVJym/rpDhqPLMUEuA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1942,6 +2250,8 @@
},
"node_modules/@duckdb/node-bindings-darwin-arm64": {
"version": "1.5.3-r.1",
+ "resolved": "https://registry.npmjs.org/@duckdb/node-bindings-darwin-arm64/-/node-bindings-darwin-arm64-1.5.3-r.1.tgz",
+ "integrity": "sha512-r87Cc/NB3cC6Jfxh4wv/j2N1XUxm/dMoPa6QwdvOsU/KyU3IwDRed5hpAVIxbp7SYXs8IEnws3E/m+toNVZt2A==",
"cpu": [
"arm64"
],
@@ -1952,6 +2262,150 @@
"darwin"
]
},
+ "node_modules/@duckdb/node-bindings-darwin-x64": {
+ "version": "1.5.3-r.1",
+ "resolved": "https://registry.npmjs.org/@duckdb/node-bindings-darwin-x64/-/node-bindings-darwin-x64-1.5.3-r.1.tgz",
+ "integrity": "sha512-S/8JXK2OR5fzSKvWdpdOuLCuzv+TUxnhLxA8twXYEC09GqimW6DIdvLquOVuykvfbBpoImz8UJpA+zOIpqlHEQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@duckdb/node-bindings-linux-arm64": {
+ "version": "1.5.3-r.1",
+ "resolved": "https://registry.npmjs.org/@duckdb/node-bindings-linux-arm64/-/node-bindings-linux-arm64-1.5.3-r.1.tgz",
+ "integrity": "sha512-bpa3d42iGTOZ2YOviUA/PGT/GGnnkmPR5W2hccAPEgfN2Doz1A7A5T899K9TIVCkdxwr7Xxoa7CiqMgzPgxdJg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@duckdb/node-bindings-linux-arm64-musl": {
+ "version": "1.5.3-r.1",
+ "resolved": "https://registry.npmjs.org/@duckdb/node-bindings-linux-arm64-musl/-/node-bindings-linux-arm64-musl-1.5.3-r.1.tgz",
+ "integrity": "sha512-gNcmx+ChrGW5Ykc446mV4P+IgaEDq8fO7Y8aYeGA+XRIdy2fpZCsjo99Vv5zUKlY0IuvGwM0WFUF03oA0KksBQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@duckdb/node-bindings-linux-x64": {
+ "version": "1.5.3-r.1",
+ "resolved": "https://registry.npmjs.org/@duckdb/node-bindings-linux-x64/-/node-bindings-linux-x64-1.5.3-r.1.tgz",
+ "integrity": "sha512-gCuxN9jabTJVJnYq59n0ba5AR1nix17v5OT3VXNzx/iZldX1MH5Gihp8of7OTaQILGuZ+APqCASL3s5fBgrqFg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@duckdb/node-bindings-linux-x64-musl": {
+ "version": "1.5.3-r.1",
+ "resolved": "https://registry.npmjs.org/@duckdb/node-bindings-linux-x64-musl/-/node-bindings-linux-x64-musl-1.5.3-r.1.tgz",
+ "integrity": "sha512-ZVEofh6i8RKbbnAYJvU+/BatDW2tR3ee4Uvcm5b7lz53FWXsCyqh5Kh8LBRuUBq5rurOoWmrVry/g1i7wBZgjg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@duckdb/node-bindings-win32-arm64": {
+ "version": "1.5.3-r.1",
+ "resolved": "https://registry.npmjs.org/@duckdb/node-bindings-win32-arm64/-/node-bindings-win32-arm64-1.5.3-r.1.tgz",
+ "integrity": "sha512-RHEfClLwLZo/aZrBKZn9ugZEnlB8ucnM61T+B9tYKCsz5RT29ueVVzyTLvuHemc5W3cZPki8xsohno8Txl6qeQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@duckdb/node-bindings-win32-x64": {
+ "version": "1.5.3-r.1",
+ "resolved": "https://registry.npmjs.org/@duckdb/node-bindings-win32-x64/-/node-bindings-win32-x64-1.5.3-r.1.tgz",
+ "integrity": "sha512-Ff6lenczCvN9g/3hjBKkn/bZe2DwxUOVrC+eNYZnqdSHcpGP6K4knV7eWIjEkOC5cZoki+Cwd822L3ivt22/5Q==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@emnapi/core": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz",
+ "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/wasi-threads": "1.2.1",
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@emnapi/runtime": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz",
+ "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@emnapi/wasi-threads": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz",
+ "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
"node_modules/@esbuild/aix-ppc64": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz",
@@ -2018,6 +2472,8 @@
},
"node_modules/@esbuild/darwin-arm64": {
"version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz",
+ "integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==",
"cpu": [
"arm64"
],
@@ -2368,6 +2824,8 @@
},
"node_modules/@fluent/syntax": {
"version": "0.19.0",
+ "resolved": "https://registry.npmjs.org/@fluent/syntax/-/syntax-0.19.0.tgz",
+ "integrity": "sha512-5D2qVpZrgpjtqU4eNOcWGp1gnUCgjfM+vKGE2y03kKN6z5EBhtx0qdRFbg8QuNNj8wXNoX93KJoYb+NqoxswmQ==",
"license": "Apache-2.0",
"engines": {
"node": ">=14.0.0",
@@ -2376,6 +2834,8 @@
},
"node_modules/@img/colour": {
"version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz",
+ "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -2384,6 +2844,8 @@
},
"node_modules/@img/sharp-darwin-arm64": {
"version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz",
+ "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==",
"cpu": [
"arm64"
],
@@ -2403,8 +2865,33 @@
"@img/sharp-libvips-darwin-arm64": "1.2.4"
}
},
+ "node_modules/@img/sharp-darwin-x64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz",
+ "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-darwin-x64": "1.2.4"
+ }
+ },
"node_modules/@img/sharp-libvips-darwin-arm64": {
"version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz",
+ "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==",
"cpu": [
"arm64"
],
@@ -2418,50 +2905,521 @@
"url": "https://opencollective.com/libvips"
}
},
- "node_modules/@inquirer/ansi": {
- "version": "2.0.7",
+ "node_modules/@img/sharp-libvips-darwin-x64": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz",
+ "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==",
+ "cpu": [
+ "x64"
+ ],
"dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
}
},
- "node_modules/@inquirer/checkbox": {
- "version": "5.2.1",
+ "node_modules/@img/sharp-libvips-linux-arm": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz",
+ "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==",
+ "cpu": [
+ "arm"
+ ],
"dev": true,
- "license": "MIT",
- "dependencies": {
- "@inquirer/ansi": "^2.0.7",
- "@inquirer/core": "^11.2.1",
- "@inquirer/figures": "^2.0.7",
- "@inquirer/type": "^4.0.7"
- },
- "engines": {
- "node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
- },
- "peerDependencies": {
- "@types/node": ">=18"
- },
- "peerDependenciesMeta": {
- "@types/node": {
- "optional": true
- }
+ "libc": [
+ "glibc"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
}
},
- "node_modules/@inquirer/confirm": {
- "version": "6.1.1",
+ "node_modules/@img/sharp-libvips-linux-arm64": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz",
+ "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==",
+ "cpu": [
+ "arm64"
+ ],
"dev": true,
- "license": "MIT",
- "dependencies": {
- "@inquirer/core": "^11.2.1",
- "@inquirer/type": "^4.0.7"
- },
- "engines": {
- "node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
- },
- "peerDependencies": {
- "@types/node": ">=18"
- },
+ "libc": [
+ "glibc"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linux-ppc64": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz",
+ "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linux-riscv64": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz",
+ "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linux-s390x": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz",
+ "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linux-x64": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz",
+ "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linuxmusl-arm64": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz",
+ "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linuxmusl-x64": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz",
+ "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-linux-arm": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz",
+ "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-arm": "1.2.4"
+ }
+ },
+ "node_modules/@img/sharp-linux-arm64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz",
+ "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-arm64": "1.2.4"
+ }
+ },
+ "node_modules/@img/sharp-linux-ppc64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz",
+ "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-ppc64": "1.2.4"
+ }
+ },
+ "node_modules/@img/sharp-linux-riscv64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz",
+ "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-riscv64": "1.2.4"
+ }
+ },
+ "node_modules/@img/sharp-linux-s390x": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz",
+ "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-s390x": "1.2.4"
+ }
+ },
+ "node_modules/@img/sharp-linux-x64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz",
+ "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-x64": "1.2.4"
+ }
+ },
+ "node_modules/@img/sharp-linuxmusl-arm64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz",
+ "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linuxmusl-arm64": "1.2.4"
+ }
+ },
+ "node_modules/@img/sharp-linuxmusl-x64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz",
+ "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linuxmusl-x64": "1.2.4"
+ }
+ },
+ "node_modules/@img/sharp-wasm32": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz",
+ "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==",
+ "cpu": [
+ "wasm32"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/runtime": "^1.7.0"
+ },
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-win32-arm64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz",
+ "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 AND LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-win32-ia32": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz",
+ "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 AND LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-win32-x64": {
+ "version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz",
+ "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 AND LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@inquirer/ansi": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-2.0.7.tgz",
+ "integrity": "sha512-3eTuUO1vH2cZm2ZKHeQxnOqlTi9EfZDGgIe3BL3I4u+rJHocr9Fz86M4fjYABPvFnQG/gGK551HqDiIcETwU6Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
+ }
+ },
+ "node_modules/@inquirer/checkbox": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-5.2.1.tgz",
+ "integrity": "sha512-b6xmA/VlTe0ZgDQHDui+Nav470u7u49nRd8/iuhOcQPO9Ch7lGuogydhi2VOmNlZ+zXcM8IcPuNSwQcdJaF/kw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@inquirer/ansi": "^2.0.7",
+ "@inquirer/core": "^11.2.1",
+ "@inquirer/figures": "^2.0.7",
+ "@inquirer/type": "^4.0.7"
+ },
+ "engines": {
+ "node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
+ },
+ "peerDependencies": {
+ "@types/node": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@inquirer/confirm": {
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-6.1.1.tgz",
+ "integrity": "sha512-eb8DBZcz/2qHWQda4rk2JiQk5h9QV/cVHi1yjt0f69WFZMRFn0sJTye3EAP8icut8UDMjQPsaH5KbcOogefrFQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@inquirer/core": "^11.2.1",
+ "@inquirer/type": "^4.0.7"
+ },
+ "engines": {
+ "node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
+ },
+ "peerDependencies": {
+ "@types/node": ">=18"
+ },
"peerDependenciesMeta": {
"@types/node": {
"optional": true
@@ -2470,6 +3428,8 @@
},
"node_modules/@inquirer/core": {
"version": "11.2.1",
+ "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-11.2.1.tgz",
+ "integrity": "sha512-Qd6GJT1yVyrZZCfN8W2qKF5ApmqryXRhRKCuip8h01x2w/esJQ2XIYc6f9abMIHgKQdBfFTSOdbHRLAhuM09UA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -2495,6 +3455,8 @@
},
"node_modules/@inquirer/editor": {
"version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-5.2.2.tgz",
+ "integrity": "sha512-ZRVd/oD+sYsUd5zVm0NflqEzlqfYCyHNsqkHl2oWXEUHs12tCbcSFi+wVFEvD8+LGRaMUsVrE7qeo6lSG/S1Vg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -2516,6 +3478,8 @@
},
"node_modules/@inquirer/expand": {
"version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-5.1.1.tgz",
+ "integrity": "sha512-YmQpenjbFSHAK3sOd44puHh3V1KXXr+JiNpUztoSQ4drLh2rTVzTap/YtlAVu/5xavifIlBfNEzJ/neZJ1a/1g==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -2536,6 +3500,8 @@
},
"node_modules/@inquirer/external-editor": {
"version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-3.0.3.tgz",
+ "integrity": "sha512-6thf5I8q7lZwzGLAxPaaGEREEkZ3nyePPDQ1oyobblxmEE8mqTLguScP7pDjUTAibiyb4hfXl+qjUEJ+di/aNA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -2556,6 +3522,8 @@
},
"node_modules/@inquirer/figures": {
"version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-2.0.7.tgz",
+ "integrity": "sha512-aJ8TBPOGB6f/2qziPfElISTCEd5XOYTFckA2SGjhNmiKzfK/u4ot3v0DUzGVdUnKjN10EqnnEPck36BkyfLnJw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -2564,6 +3532,8 @@
},
"node_modules/@inquirer/input": {
"version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-5.1.2.tgz",
+ "integrity": "sha512-9K/DDBSQpOyZSkt6sOVP9Vo0TR7atX2kuILsUu0x3wVcVbe97lJwIJKMLdMw25tDYuXl/qp6erT0Xs1rfmcfZg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -2584,6 +3554,8 @@
},
"node_modules/@inquirer/number": {
"version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-4.1.1.tgz",
+ "integrity": "sha512-XF4IXAbPnGPgw0wsbC/i2tPcyfdZgDpUlhsqU0SfT4IRIGWha6Xm9VRgN5yYxJq+jnyXlfXI/nQ3ulfk0iEICA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -2604,6 +3576,8 @@
},
"node_modules/@inquirer/password": {
"version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-5.1.1.tgz",
+ "integrity": "sha512-3XBfF7DAsp5qeDsvN5Rd1HmbNokVvEQoUM0QLrRcybC9nX96w3Pbmu7qUsb3IT3J3jBvs2+mTXaKHOUsgHMLzg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -2625,6 +3599,8 @@
},
"node_modules/@inquirer/prompts": {
"version": "8.5.2",
+ "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-8.5.2.tgz",
+ "integrity": "sha512-IYR/3C/paEVVQYQvdDlFZVjRCJVYHHON0XXMH91KO9GSxs0TdKYWlUdvfQl2EfAHDxUaN3IBffkE/BDTh5nJ6g==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -2653,6 +3629,8 @@
},
"node_modules/@inquirer/rawlist": {
"version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-5.3.1.tgz",
+ "integrity": "sha512-QqdTqQddL3qPX/PPrjobpsO25NZ4dWXgTLenrR445L2ptLEYE6Z+PD5c5CNDJNx4ugRgELAIpSIJxZaO2jJ2Og==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -2673,6 +3651,8 @@
},
"node_modules/@inquirer/search": {
"version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-4.2.1.tgz",
+ "integrity": "sha512-xJj8QWKRSrfKoBIITLZK61dD3zwo0Rz11fgDImku30/Oe81zMdIdGgrLY2h6RkJ+KZ/GhNYIRMKnH/62qBTA5g==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -2694,6 +3674,8 @@
},
"node_modules/@inquirer/select": {
"version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-5.2.1.tgz",
+ "integrity": "sha512-FlDndEUww8m7BfukO2nJa25vhD+H5jxxCv4oGioKqzyWz3nPHhhw4LKdYRSlXuAx7DsdWia7iyaBPKKS95Evfw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -2716,6 +3698,8 @@
},
"node_modules/@inquirer/type": {
"version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-4.0.7.tgz",
+ "integrity": "sha512-t28inv14nMQ1PhKpsJPY+kEs/c00qzeCOS2gTNRyTjG5d6qsVA2fItxW4hkvGZ5lvanGLdtCzVIx5dwdRpN1+g==",
"dev": true,
"license": "MIT",
"engines": {
@@ -2732,6 +3716,8 @@
},
"node_modules/@isaacs/cliui": {
"version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
+ "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
"license": "ISC",
"dependencies": {
"string-width": "^5.1.2",
@@ -2747,10 +3733,14 @@
},
"node_modules/@isaacs/cliui/node_modules/emoji-regex": {
"version": "9.2.2",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
+ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
"license": "MIT"
},
"node_modules/@isaacs/cliui/node_modules/string-width": {
"version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
+ "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
"license": "MIT",
"dependencies": {
"eastasianwidth": "^0.2.0",
@@ -2766,6 +3756,8 @@
},
"node_modules/@isaacs/cliui/node_modules/wrap-ansi": {
"version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
+ "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
"license": "MIT",
"dependencies": {
"ansi-styles": "^6.1.0",
@@ -2781,6 +3773,8 @@
},
"node_modules/@jridgewell/gen-mapping": {
"version": "0.3.13",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
+ "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
"license": "MIT",
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.5.0",
@@ -2789,6 +3783,8 @@
},
"node_modules/@jridgewell/remapping": {
"version": "2.3.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
+ "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
"license": "MIT",
"dependencies": {
"@jridgewell/gen-mapping": "^0.3.5",
@@ -2797,6 +3793,8 @@
},
"node_modules/@jridgewell/resolve-uri": {
"version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
"license": "MIT",
"engines": {
"node": ">=6.0.0"
@@ -2804,18 +3802,43 @@
},
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.5.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
+ "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
"license": "MIT"
},
"node_modules/@jridgewell/trace-mapping": {
"version": "0.3.31",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
+ "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
"license": "MIT",
"dependencies": {
"@jridgewell/resolve-uri": "^3.1.0",
"@jridgewell/sourcemap-codec": "^1.4.14"
}
},
+ "node_modules/@napi-rs/wasm-runtime": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.5.tgz",
+ "integrity": "sha512-AWPoBRJ9tsnVhor4sjO7rkni+7p+2IAEFj6cx06UgP10jkQHqay/36uRV/bFkgrh18D9vb4cr8Q0Pthskgzy+Q==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@tybys/wasm-util": "^0.10.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/Brooooooklyn"
+ },
+ "peerDependencies": {
+ "@emnapi/core": "^1.7.1",
+ "@emnapi/runtime": "^1.7.1"
+ }
+ },
"node_modules/@nodable/entities": {
"version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@nodable/entities/-/entities-2.2.0.tgz",
+ "integrity": "sha512-9uGyhaQavEUMC8AIddIjau4NsnsXhou+j5sBAGojCM1oxmQpVKTWR/9JxABD6UAv12vpIms55fPZKFQEhG6uBg==",
"dev": true,
"funding": [
{
@@ -2827,6 +3850,8 @@
},
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -2839,6 +3864,8 @@
},
"node_modules/@nodelib/fs.stat": {
"version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
"dev": true,
"license": "MIT",
"engines": {
@@ -2847,6 +3874,8 @@
},
"node_modules/@nodelib/fs.walk": {
"version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -2859,10 +3888,14 @@
},
"node_modules/@one-ini/wasm": {
"version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/@one-ini/wasm/-/wasm-0.1.1.tgz",
+ "integrity": "sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==",
"license": "MIT"
},
"node_modules/@oxc-project/types": {
"version": "0.133.0",
+ "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.133.0.tgz",
+ "integrity": "sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA==",
"dev": true,
"license": "MIT",
"funding": {
@@ -2871,6 +3904,8 @@
},
"node_modules/@pkgjs/parseargs": {
"version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
+ "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
"license": "MIT",
"optional": true,
"engines": {
@@ -2879,15 +3914,21 @@
},
"node_modules/@plausible-analytics/tracker": {
"version": "0.4.5",
+ "resolved": "https://registry.npmjs.org/@plausible-analytics/tracker/-/tracker-0.4.5.tgz",
+ "integrity": "sha512-6BfAGejXY+YA3Cw6LYT2Zpn4hTxDtPQAawFsYUsQCOg78wIS5C4deAGXTfJffa5VleMWITv5lpJ/EYuQBl1tPA==",
"license": "MIT"
},
"node_modules/@polka/url": {
"version": "1.0.0-next.29",
+ "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz",
+ "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==",
"dev": true,
"license": "MIT"
},
"node_modules/@poppinss/colors": {
"version": "4.1.6",
+ "resolved": "https://registry.npmjs.org/@poppinss/colors/-/colors-4.1.6.tgz",
+ "integrity": "sha512-H9xkIdFswbS8n1d6vmRd8+c10t2Qe+rZITbbDHHkQixH5+2x1FDGmi/0K+WgWiqQFKPSlIYB7jlH6Kpfn6Fleg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -2896,6 +3937,8 @@
},
"node_modules/@poppinss/dumper": {
"version": "0.6.5",
+ "resolved": "https://registry.npmjs.org/@poppinss/dumper/-/dumper-0.6.5.tgz",
+ "integrity": "sha512-NBdYIb90J7LfOI32dOewKI1r7wnkiH6m920puQ3qHUeZkxNkQiFnXVWoE6YtFSv6QOiPPf7ys6i+HWWecDz7sw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -2906,6 +3949,8 @@
},
"node_modules/@poppinss/dumper/node_modules/supports-color": {
"version": "10.2.2",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-10.2.2.tgz",
+ "integrity": "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==",
"dev": true,
"license": "MIT",
"engines": {
@@ -2915,21 +3960,283 @@
"url": "https://github.com/chalk/supports-color?sponsor=1"
}
},
- "node_modules/@poppinss/exception": {
- "version": "1.2.3",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@rolldown/binding-darwin-arm64": {
+ "node_modules/@poppinss/exception": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/@poppinss/exception/-/exception-1.2.3.tgz",
+ "integrity": "sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@rolldown/binding-android-arm64": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.3.tgz",
+ "integrity": "sha512-454rs7jHngixp/NMxd5srYD57OnzSlZ/eFTETjORQHLwJG1lRtmNOJcBerZlfu4GjKqeq8aCCIQrMdHyhI51Hw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-darwin-arm64": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.3.tgz",
+ "integrity": "sha512-PcAhP+ynjURNyy8SKGl5DQP94aGuB/7JrXJb/t7P+hanXvQVMWzUvRRhBAcg/lNRadBhoUPqSoP4xw5tR/KBEA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-darwin-x64": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.3.tgz",
+ "integrity": "sha512-9YpfeUvSE2RS7wysJ81uOZkXJz7f7Q55H2Gvp3VEw/EsahqDtrphrZ0EwDLK5vvKOzaCrBsjF8JmnMLcUt78Gg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-freebsd-x64": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.3.tgz",
+ "integrity": "sha512-yB1IlAsSNHncV6SCTL27/MVGR5htvQsoGxIv5KMGXALp+Ll1wYsn+x98M9MW7qa+NdSbvrrY7ANI4wLJ0n1e6g==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-arm-gnueabihf": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.3.tgz",
+ "integrity": "sha512-Yi30IVAAfLUCy2MseFjbB1jAMDl1VMCAas5StnYp8da9+CKvMd2H2cbEjWcw5NPaPqzvYkVIaF1nNUG+b7u/sw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-arm64-gnu": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.3.tgz",
+ "integrity": "sha512-jsO7R8To+AdlYgUmN5sHSCZbfhtMBkO0WUx8iORQnPcMMdgr7qM2DQmMwgabs3GhNztdmoKkMKQFHD6DTMCIQw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-arm64-musl": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.3.tgz",
+ "integrity": "sha512-VWkUHwWriDciit80wleYwKILoR/KMvxh/IdwS/paX+ZgpuRpCrKLUdadJbc0NpBEiyhpYawsJ73j9aCvOH+f7Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-ppc64-gnu": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.3.tgz",
+ "integrity": "sha512-5f1laC0SlIR0yDbFCd8acUhvJIag6N3zC5P7oUPN6wX0aOma+uKJ0wBDH5aq7I1PVI2ttTlhJwzwRIBnLiSGEg==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-s390x-gnu": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.3.tgz",
+ "integrity": "sha512-Iq4ko0r4XsgbrF/LunNgHtAGLRRVE2kXonAXQ/MV0mC6jQpMOhW1SvtZja2EhC/kd05++bP78dsqBeIQyYJ6Yg==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-x64-gnu": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.3.tgz",
+ "integrity": "sha512-B8m6tD5+/N5FeNQFbKlLA/2yVq9ycQP1SeedyEYYKWBNR3ZQbkvIUcNnDNM03lO1l5F2roiiFJGgvoLLyZXtSg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-x64-musl": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.3.tgz",
+ "integrity": "sha512-pSdpdUJHkuCxun9LE7jvgUB9qsRgaiyNNCX7m/AvHTcq67AiT/Yhoxvw5zPfhrM8k/BfP8ce/hMOpthKDpEUow==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-openharmony-arm64": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.3.tgz",
+ "integrity": "sha512-OXXS3RKJgX2uLwM+gYyuH5omcH8fL1LJs96pZGgtetVCahON57+d4SJHzTgZiOjxgGkSnpXpOsWuPDGAKAigEg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-wasm32-wasi": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.3.tgz",
+ "integrity": "sha512-JTtb8BWFynicNSoPrehsCzBtOKjZ6jhMiPFEmOiuXg1Fl8dn2KHQob+GuPSGR0dryQa1PQJbzjF3dqO/whhjLg==",
+ "cpu": [
+ "wasm32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/core": "1.10.0",
+ "@emnapi/runtime": "1.10.0",
+ "@napi-rs/wasm-runtime": "^1.1.4"
+ },
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-win32-arm64-msvc": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.3.tgz",
+ "integrity": "sha512-gEdFFEN70A/jxb2svrWsN3aDL7OUtmvlOy+6fa2jxG8K0wQ1ZbdeLGnidov6Yu5/733dI5ySfzFlQ/cb0bSz1g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-win32-x64-msvc": {
"version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.3.tgz",
+ "integrity": "sha512-eXB7CHuaQdqmJcc3koCNtNPmT/bj2gc999kUFgBxG8Ac0NdgXc4rkCHhqrgrhN3zddvvvrgzj1e90SuSfmyIXA==",
"cpu": [
- "arm64"
+ "x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
- "darwin"
+ "win32"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
@@ -2937,16 +4244,22 @@
},
"node_modules/@rolldown/pluginutils": {
"version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz",
+ "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==",
"dev": true,
"license": "MIT"
},
"node_modules/@sec-ant/readable-stream": {
"version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz",
+ "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==",
"dev": true,
"license": "MIT"
},
"node_modules/@silverbucket/ajv-formats-draft2019": {
"version": "1.6.5",
+ "resolved": "https://registry.npmjs.org/@silverbucket/ajv-formats-draft2019/-/ajv-formats-draft2019-1.6.5.tgz",
+ "integrity": "sha512-TUN/aSGMt3mZF45oy+kfCKtnKjBbSRVYFJxZKnGCPbKynPI2tsGyLgD9GEwFS0NLPbX0hUYHYeyFVoJ33HlMCw==",
"license": "MIT",
"dependencies": {
"@silverbucket/iana-schemes": "^1.4.4",
@@ -2959,10 +4272,14 @@
},
"node_modules/@silverbucket/iana-schemes": {
"version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/@silverbucket/iana-schemes/-/iana-schemes-1.4.4.tgz",
+ "integrity": "sha512-2iUk6DlqdpQQKs3qrCZDf4LQLH1GPtUXmYZFeq0NWw1WkGY2iJBP4aeYZ5v+3ITxtQA3M0t/Sua8AKu+o4O0KA==",
"license": "MIT"
},
"node_modules/@simple-libs/child-process-utils": {
"version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@simple-libs/child-process-utils/-/child-process-utils-1.0.2.tgz",
+ "integrity": "sha512-/4R8QKnd/8agJynkNdJmNw2MBxuFTRcNFnE5Sg/G+jkSsV8/UBgULMzhizWWW42p8L5H7flImV2ATi79Ove2Tw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -2977,6 +4294,8 @@
},
"node_modules/@simple-libs/stream-utils": {
"version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@simple-libs/stream-utils/-/stream-utils-1.2.0.tgz",
+ "integrity": "sha512-KxXvfapcixpz6rVEB6HPjOUZT22yN6v0vI0urQSk1L8MlEWPDFCZkhw2xmkyoTGYeFw7tWTZd7e3lVzRZRN/EA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -2988,10 +4307,14 @@
},
"node_modules/@simplewebauthn/browser": {
"version": "13.3.0",
+ "resolved": "https://registry.npmjs.org/@simplewebauthn/browser/-/browser-13.3.0.tgz",
+ "integrity": "sha512-BE/UWv6FOToAdVk0EokzkqQQDOWtNydYlY6+OrmiZ5SCNmb41VehttboTetUM3T/fr6EAFYVXjz4My2wg230rQ==",
"license": "MIT"
},
"node_modules/@sindresorhus/is": {
"version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-7.2.0.tgz",
+ "integrity": "sha512-P1Cz1dWaFfR4IR+U13mqqiGsLFf1KbayybWwdd2vfctdV6hDpUkgCY0nKOLLTMSoRd/jJNjtbqzf13K8DCCXQw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -3003,6 +4326,8 @@
},
"node_modules/@sindresorhus/merge-streams": {
"version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz",
+ "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -3014,6 +4339,8 @@
},
"node_modules/@sinonjs/commons": {
"version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz",
+ "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
@@ -3022,6 +4349,8 @@
},
"node_modules/@sinonjs/fake-timers": {
"version": "11.2.2",
+ "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz",
+ "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
@@ -3030,6 +4359,8 @@
},
"node_modules/@sinonjs/samsam": {
"version": "8.0.3",
+ "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.3.tgz",
+ "integrity": "sha512-hw6HbX+GyVZzmaYNh82Ecj1vdGZrqVIn/keDTg63IgAwiQPO+xCz99uG6Woqgb4tM0mUiFENKZ4cqd7IX94AXQ==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
@@ -3039,6 +4370,8 @@
},
"node_modules/@sinonjs/samsam/node_modules/type-detect": {
"version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz",
+ "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -3047,6 +4380,8 @@
},
"node_modules/@smithy/core": {
"version": "3.24.7",
+ "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.24.7.tgz",
+ "integrity": "sha512-KoUi4M1f3BG6kzN1FnCwL7oyFptTbyBJKjR6yhSib+JHRdUmM1o+VwsFtJ66NZCkCzVfJMWRHJNo0R0jznp0Pg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -3060,6 +4395,8 @@
},
"node_modules/@smithy/credential-provider-imds": {
"version": "4.3.9",
+ "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.3.9.tgz",
+ "integrity": "sha512-ZlfJ/4Fa3jYb+3eaohPfG9utX9HmdhFNcFtpoGAhUhdynAOmGXtmigbi7eEiONKM+ykHw8RwKuDEb85Lx7t7fA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -3073,6 +4410,8 @@
},
"node_modules/@smithy/fetch-http-handler": {
"version": "5.4.7",
+ "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.4.7.tgz",
+ "integrity": "sha512-NslaM2ir0N2hisDmzXLstPaVINZheh8SokyOC++kzFPloZucL2R7Y7bS57mSzx/1Fc/fqmn7twjkeezTTrV0EA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -3086,6 +4425,8 @@
},
"node_modules/@smithy/is-array-buffer": {
"version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz",
+ "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -3097,6 +4438,8 @@
},
"node_modules/@smithy/node-http-handler": {
"version": "4.7.8",
+ "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.7.8.tgz",
+ "integrity": "sha512-f+DbsWUwSbtMu1a/j8Y93KiU1SRg9nyzfjereqn1BJ33QOTUXxdlYvVXMhAYl1vuR1Kmna5aIJe09KSIfyFNYw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -3110,6 +4453,8 @@
},
"node_modules/@smithy/signature-v4": {
"version": "5.4.7",
+ "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.4.7.tgz",
+ "integrity": "sha512-LwQZazFayImv+IOm0S0enoLeUJwmAlhGC5O6YCcLWezyu08dF46GOxPOq35OpBIHkgd7OvNvBStIFwVNyrvoBw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -3123,6 +4468,8 @@
},
"node_modules/@smithy/types": {
"version": "4.14.4",
+ "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.14.4.tgz",
+ "integrity": "sha512-B2S9+UGm1+/pHkcx3ZoLVX1a+pmSk8rqxRR+ZsNqZaJ5q9FWX9AFGQVM4qG5+OBeQUZVy99HY8HqW8gK/wgXzQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -3134,6 +4481,8 @@
},
"node_modules/@smithy/util-buffer-from": {
"version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz",
+ "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -3146,6 +4495,8 @@
},
"node_modules/@smithy/util-hex-encoding": {
"version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-2.2.0.tgz",
+ "integrity": "sha512-7iKXR+/4TpLK194pVjKiasIyqMtTYJsgKgM242Y9uzt5dhHnUDvMNb+3xIhRJ9QhvqGii/5cRUt4fJn3dtXNHQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -3157,6 +4508,8 @@
},
"node_modules/@smithy/util-middleware": {
"version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-2.2.0.tgz",
+ "integrity": "sha512-L1qpleXf9QD6LwLCJ5jddGkgWyuSvWBkJwWAZ6kFkdifdso+sk3L3O1HdmPvCdnCK3IS4qWyPxev01QMnfHSBw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -3169,6 +4522,8 @@
},
"node_modules/@smithy/util-middleware/node_modules/@smithy/types": {
"version": "2.12.0",
+ "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.12.0.tgz",
+ "integrity": "sha512-QwYgloJ0sVNBeBuBs65cIkTbfzV/Q6ZNPCJ99EICFEdJYG50nGIY/uYXp+TbsdJReIuPr0a0kXmCvren3MbRRw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -3180,6 +4535,8 @@
},
"node_modules/@smithy/util-uri-escape": {
"version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-2.2.0.tgz",
+ "integrity": "sha512-jtmJMyt1xMD/d8OtbVJ2gFZOSKc+ueYJZPW20ULW1GOp/q/YIM0wNh+u8ZFao9UaIGz4WoPW8hC64qlWLIfoDA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -3191,6 +4548,8 @@
},
"node_modules/@smithy/util-utf8": {
"version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz",
+ "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -3203,16 +4562,22 @@
},
"node_modules/@speed-highlight/core": {
"version": "1.2.17",
+ "resolved": "https://registry.npmjs.org/@speed-highlight/core/-/core-1.2.17.tgz",
+ "integrity": "sha512-Z92FwKpCtfaW1V0jTU/fh3QzYEZN8wDwrzRIBoADCJfn4mJCNcJN/XegifX7BDrQ8/h9Xh/JnbyMchL0FqXrkg==",
"dev": true,
"license": "CC0-1.0"
},
"node_modules/@standard-schema/spec": {
"version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz",
+ "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==",
"dev": true,
"license": "MIT"
},
"node_modules/@stryker-mutator/api": {
"version": "9.6.1",
+ "resolved": "https://registry.npmjs.org/@stryker-mutator/api/-/api-9.6.1.tgz",
+ "integrity": "sha512-g8VNoFWQWbx0pdal3Vt8jVCZW+v3sc3gi94iI0GVtVgUGTqphAjJF6EAruPTx0lqvtonsaAxn5TD36hcG1d6Wg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -3227,6 +4592,8 @@
},
"node_modules/@stryker-mutator/core": {
"version": "9.6.1",
+ "resolved": "https://registry.npmjs.org/@stryker-mutator/core/-/core-9.6.1.tgz",
+ "integrity": "sha512-WMgnvf+Wyh/yiruhNZwc8w8DlzmmjXhPjSn5MR8RhAXzlnWji8TQrUYgBUkHk9bEgSaIlB3KZHm37iiU5Q2cLQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -3266,6 +4633,8 @@
},
"node_modules/@stryker-mutator/core/node_modules/ajv": {
"version": "8.18.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz",
+ "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3281,6 +4650,8 @@
},
"node_modules/@stryker-mutator/instrumenter": {
"version": "9.6.1",
+ "resolved": "https://registry.npmjs.org/@stryker-mutator/instrumenter/-/instrumenter-9.6.1.tgz",
+ "integrity": "sha512-5K8wH4Pthly25c2uKKik4Dfcoeou7sbJdFS6u3QIYHlulgFVDJwtEMWTZGkZfs7IiUEXIDNa0keRACq5jn5AvA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -3303,6 +4674,8 @@
},
"node_modules/@stryker-mutator/instrumenter/node_modules/semver": {
"version": "7.7.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
+ "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
"dev": true,
"license": "ISC",
"bin": {
@@ -3314,11 +4687,15 @@
},
"node_modules/@stryker-mutator/util": {
"version": "9.6.1",
+ "resolved": "https://registry.npmjs.org/@stryker-mutator/util/-/util-9.6.1.tgz",
+ "integrity": "sha512-Lk/ALVctJjFv1vvwR+CFoKzDCWvsBlq7flDUnmnpuwTrGbm156EdZD1Jjq4o8KdOap0ezUZqQNE9OAI1m2+pUQ==",
"dev": true,
"license": "Apache-2.0"
},
"node_modules/@sveltejs/acorn-typescript": {
"version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/@sveltejs/acorn-typescript/-/acorn-typescript-1.0.10.tgz",
+ "integrity": "sha512-4WfKk68eTih+MiJD4fSbxN7E8kVBmTMPWHUPYjvl2N0rMs53YLTT8/YjKU5Dtnz5LqDjl7LEw4U7lXR2W3J5WA==",
"license": "MIT",
"peerDependencies": {
"acorn": "^8.9.0"
@@ -3326,6 +4703,8 @@
},
"node_modules/@sveltejs/adapter-cloudflare": {
"version": "7.2.8",
+ "resolved": "https://registry.npmjs.org/@sveltejs/adapter-cloudflare/-/adapter-cloudflare-7.2.8.tgz",
+ "integrity": "sha512-bIdhY/Fi4AQmqiBdQVKnafH1h9Gw+xbCvHyUu4EouC8rJOU02zwhi14k/FDhQ0mJF1iblIu3m8UNQ8GpGIvIOQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3339,6 +4718,8 @@
},
"node_modules/@sveltejs/kit": {
"version": "2.65.1",
+ "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.65.1.tgz",
+ "integrity": "sha512-Sa1rFYYqBB+zv3rIxAg/CsFskR/x4aj5BY/hvLxBd9r/mqbipxM945As1K3PqsDicJAyekPR0BlWoVIiw2OHYg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3379,6 +4760,8 @@
},
"node_modules/@sveltejs/vite-plugin-svelte": {
"version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-7.1.2.tgz",
+ "integrity": "sha512-DrUBA2UXRfDmUX/ZTiEopd3X40yavsJF1FX2RygcuIScHL7o5YX1fMvoYnDhjeJQC4weCOklirpNWlcb2NiSeA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3397,13 +4780,28 @@
},
"node_modules/@swc/helpers": {
"version": "0.5.23",
+ "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.23.tgz",
+ "integrity": "sha512-5lSsMOTXURePglDfvuAQUqkGek9Hg2kksOYay2m0+XR++b2NWYL/4sWyuvVBIs8oKnJaxkdi9whaL/sqN13afw==",
"license": "Apache-2.0",
"dependencies": {
"tslib": "^2.8.0"
}
},
+ "node_modules/@tybys/wasm-util": {
+ "version": "0.10.2",
+ "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz",
+ "integrity": "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
"node_modules/@types/buffers": {
"version": "0.1.31",
+ "resolved": "https://registry.npmjs.org/@types/buffers/-/buffers-0.1.31.tgz",
+ "integrity": "sha512-wEZBb3o0Kh5RAj3V172vJCcxaCV8C2HJ7YLBBlG5Mwue0g4uRg5LWv8C6ap8MyFbXE6UbYEuvtHY7oTWAPeXEw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3412,23 +4810,33 @@
},
"node_modules/@types/command-line-args": {
"version": "5.2.3",
+ "resolved": "https://registry.npmjs.org/@types/command-line-args/-/command-line-args-5.2.3.tgz",
+ "integrity": "sha512-uv0aG6R0Y8WHZLTamZwtfsDLVRnOa+n+n5rEvFWL5Na5gZ8V2Teab/duDPFzIIIhs9qizDpcavCusCLJZu62Kw==",
"license": "MIT"
},
"node_modules/@types/command-line-usage": {
"version": "5.0.4",
+ "resolved": "https://registry.npmjs.org/@types/command-line-usage/-/command-line-usage-5.0.4.tgz",
+ "integrity": "sha512-BwR5KP3Es/CSht0xqBcUXS3qCAUVXwpRKsV2+arxeb65atasuXG9LykC9Ab10Cw3s2raH92ZqOeILaQbsB2ACg==",
"license": "MIT"
},
"node_modules/@types/cookie": {
"version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz",
+ "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/estree": {
"version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz",
+ "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==",
"license": "MIT"
},
"node_modules/@types/glob": {
"version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz",
+ "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3438,6 +4846,8 @@
},
"node_modules/@types/hast": {
"version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz",
+ "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==",
"license": "MIT",
"dependencies": {
"@types/unist": "*"
@@ -3445,11 +4855,15 @@
},
"node_modules/@types/json-schema": {
"version": "7.0.15",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
+ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
"license": "MIT",
"peer": true
},
"node_modules/@types/mdast": {
"version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz",
+ "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==",
"license": "MIT",
"dependencies": {
"@types/unist": "*"
@@ -3457,11 +4871,15 @@
},
"node_modules/@types/minimatch": {
"version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz",
+ "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/node": {
"version": "25.9.3",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-25.9.3.tgz",
+ "integrity": "sha512-603BddQMv3pUcr4U2dhujk83N2tTDVr/34wII2B6bJy6g+8WD6yUb11jszNs0gdi4PesVWl7ABt8nYMVpnLUcg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3470,6 +4888,8 @@
},
"node_modules/@types/sinon": {
"version": "17.0.4",
+ "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-17.0.4.tgz",
+ "integrity": "sha512-RHnIrhfPO3+tJT0s7cFaXGZvsL4bbR3/k7z3P312qMS4JaS2Tk+KiwiLx1S0rQ56ERj00u1/BtdyVd0FY+Pdew==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3478,23 +4898,33 @@
},
"node_modules/@types/sinonjs__fake-timers": {
"version": "15.0.1",
+ "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-15.0.1.tgz",
+ "integrity": "sha512-Ko2tjWJq8oozHzHV+reuvS5KYIRAokHnGbDwGh/J64LntgpbuylF74ipEL24HCyRjf9FOlBiBHWBR1RlVKsI1w==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/trusted-types": {
"version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
+ "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
"license": "MIT"
},
"node_modules/@types/unist": {
"version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz",
+ "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==",
"license": "MIT"
},
"node_modules/@ungap/custom-elements": {
"version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/@ungap/custom-elements/-/custom-elements-1.3.0.tgz",
+ "integrity": "sha512-f4q/s76+8nOy+fhrNHyetuoPDR01lmlZB5czfCG+OOnBw/Wf+x48DcCDPmMQY7oL8xYFL8qfenMoiS8DUkKBUw==",
"license": "ISC"
},
"node_modules/@willfarrell-ds/cli": {
"version": "0.0.0-alpha.6",
+ "resolved": "https://registry.npmjs.org/@willfarrell-ds/cli/-/cli-0.0.0-alpha.6.tgz",
+ "integrity": "sha512-CIEnRyopUAil0yPrAYqg8jEnSwc1dzIe5LQbi0/ghuWukSHrwcrWGoqBwTfuBOddg3087kIHj3YXHyJncOG1qw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3508,6 +4938,8 @@
},
"node_modules/@willfarrell-ds/svelte": {
"version": "0.0.0-alpha.6",
+ "resolved": "https://registry.npmjs.org/@willfarrell-ds/svelte/-/svelte-0.0.0-alpha.6.tgz",
+ "integrity": "sha512-6xnvXlOWj6h/kWIx6RG0J28XmmwMTIVp6zxqeZlmifymS8l28G8qsg2tCHyaN+09gw7hTvLoQ2P4wCF2FMr9HA==",
"license": "MIT",
"dependencies": {
"@willfarrell-ds/vanilla": "0.0.0-alpha.6",
@@ -3521,6 +4953,8 @@
},
"node_modules/@willfarrell-ds/vanilla": {
"version": "0.0.0-alpha.6",
+ "resolved": "https://registry.npmjs.org/@willfarrell-ds/vanilla/-/vanilla-0.0.0-alpha.6.tgz",
+ "integrity": "sha512-a7fWbPJZkDcMQ/OK1pLMSAk6DIBBVN52VaJrXu/lUur4VUrX3Sa0W3UVPAQgWaJ5gkFYfxBjTw3rVkm2PwWLGQ==",
"license": "MIT",
"dependencies": {
"@simplewebauthn/browser": "13.3.0",
@@ -3530,6 +4964,8 @@
},
"node_modules/@yarnpkg/parsers": {
"version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@yarnpkg/parsers/-/parsers-3.0.3.tgz",
+ "integrity": "sha512-mQZgUSgFurUtA07ceMjxrWkYz8QtDuYkvPlu0ZqncgjopQ0t6CNEo/OSealkmnagSUx8ZD5ewvezUwUuMqutQg==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
@@ -3542,6 +4978,8 @@
},
"node_modules/@yarnpkg/parsers/node_modules/argparse": {
"version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3550,6 +4988,8 @@
},
"node_modules/@yarnpkg/parsers/node_modules/js-yaml": {
"version": "3.14.2",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz",
+ "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3562,6 +5002,8 @@
},
"node_modules/abbrev": {
"version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz",
+ "integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==",
"license": "ISC",
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
@@ -3569,6 +5011,8 @@
},
"node_modules/accessible-autocomplete": {
"version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/accessible-autocomplete/-/accessible-autocomplete-3.0.1.tgz",
+ "integrity": "sha512-xMshgc2LT5addvvfCTGzIkRrvhbOFeylFSnSMfS/PdjvvvElZkakCwxO3/yJYBWyi1hi3tZloqOJQ5kqqJtH4g==",
"license": "MIT",
"peerDependencies": {
"preact": "^8.0.0"
@@ -3581,6 +5025,8 @@
},
"node_modules/acorn": {
"version": "8.17.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.17.0.tgz",
+ "integrity": "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==",
"license": "MIT",
"bin": {
"acorn": "bin/acorn"
@@ -3591,6 +5037,8 @@
},
"node_modules/ajv": {
"version": "8.20.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz",
+ "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==",
"license": "MIT",
"dependencies": {
"fast-deep-equal": "^3.1.3",
@@ -3605,6 +5053,8 @@
},
"node_modules/ajv-cmd": {
"version": "0.13.3",
+ "resolved": "https://registry.npmjs.org/ajv-cmd/-/ajv-cmd-0.13.3.tgz",
+ "integrity": "sha512-H1LArE4kclZ5JdWLKUZd1ji3UjO6FSpCW1MZ6J0X89BqwT+5W70KD4TpfvhcM7isSoQvo6sslA/rZiCH1HzM6g==",
"license": "MIT",
"workspaces": [
".github"
@@ -3635,6 +5085,8 @@
},
"node_modules/ajv-errors": {
"version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-3.0.0.tgz",
+ "integrity": "sha512-V3wD15YHfHz6y0KdhYFjyy9vWtEVALT9UrxfN3zqlI6dMioHnJrqOYfyPKol3oqrnCM9uwkcdCwkJ0WUcbLMTQ==",
"license": "MIT",
"peerDependencies": {
"ajv": "^8.0.1"
@@ -3642,6 +5094,8 @@
},
"node_modules/ajv-formats": {
"version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz",
+ "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==",
"license": "MIT",
"dependencies": {
"ajv": "^8.0.0"
@@ -3657,6 +5111,8 @@
},
"node_modules/ajv-ftl-i18n": {
"version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/ajv-ftl-i18n/-/ajv-ftl-i18n-0.2.1.tgz",
+ "integrity": "sha512-ThWHxPmLaJYKrl1mMWAYizGqZG1MrHcMgQ4MId2YFAjRn73GrZqSMX+sifQAHXAva0RZVeGHxVqkrWGizDFo6Q==",
"license": "MIT",
"workspaces": [
".github"
@@ -3678,6 +5134,8 @@
},
"node_modules/ajv-i18n": {
"version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/ajv-i18n/-/ajv-i18n-4.2.0.tgz",
+ "integrity": "sha512-v/ei2UkCEeuKNXh8RToiFsUclmU+G57LO1Oo22OagNMENIw+Yb8eMwvHu7Vn9fmkjJyv6XclhJ8TbuigSglPkg==",
"license": "MIT",
"peerDependencies": {
"ajv": "^8.0.0-beta.0"
@@ -3685,6 +5143,8 @@
},
"node_modules/ajv-keywords": {
"version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
+ "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
"license": "MIT",
"dependencies": {
"fast-deep-equal": "^3.1.3"
@@ -3695,6 +5155,8 @@
},
"node_modules/angular-html-parser": {
"version": "10.4.0",
+ "resolved": "https://registry.npmjs.org/angular-html-parser/-/angular-html-parser-10.4.0.tgz",
+ "integrity": "sha512-++nLNyZwRfHqFh7akH5Gw/JYizoFlMRz0KRigfwfsLqV8ZqlcVRb1LkPEWdYvEKDnbktknM2J4BXaYUGrQZPww==",
"dev": true,
"license": "MIT",
"engines": {
@@ -3703,6 +5165,8 @@
},
"node_modules/ansi-regex": {
"version": "6.2.2",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz",
+ "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
"license": "MIT",
"engines": {
"node": ">=12"
@@ -3713,6 +5177,8 @@
},
"node_modules/ansi-styles": {
"version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz",
+ "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==",
"license": "MIT",
"engines": {
"node": ">=12"
@@ -3723,6 +5189,8 @@
},
"node_modules/anynum": {
"version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/anynum/-/anynum-1.0.0.tgz",
+ "integrity": "sha512-xjR9/zBVnUOP6ztMIIgShjsxui80nQUQH+5xJnvrYLs+90bF25/KJqaAi8mk+B4RDtX1Nspi6fmp4YTEts8SfA==",
"dev": true,
"funding": [
{
@@ -3734,6 +5202,8 @@
},
"node_modules/apache-arrow": {
"version": "21.1.0",
+ "resolved": "https://registry.npmjs.org/apache-arrow/-/apache-arrow-21.1.0.tgz",
+ "integrity": "sha512-kQrYLxhC+NTVVZ4CCzGF6L/uPVOzJmD1T3XgbiUnP7oTeVFOFgEUu6IKNwCDkpFoBVqDKQivlX4RUFqqnWFlEA==",
"license": "Apache-2.0",
"dependencies": {
"@swc/helpers": "^0.5.11",
@@ -3752,6 +5222,8 @@
},
"node_modules/apache-arrow/node_modules/@types/node": {
"version": "24.13.2",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-24.13.2.tgz",
+ "integrity": "sha512-fRa09kZTgu8o71KFcDjUFuc7F+dEbZYZmkI0mg5YBTRs0yMKjYHsq/c0urDKeDb+D5qVgXOdFcuu+DZPKOITwA==",
"license": "MIT",
"dependencies": {
"undici-types": "~7.18.0"
@@ -3759,14 +5231,20 @@
},
"node_modules/apache-arrow/node_modules/undici-types": {
"version": "7.18.2",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz",
+ "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==",
"license": "MIT"
},
"node_modules/argparse": {
"version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
"license": "Python-2.0"
},
"node_modules/aria-query": {
"version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.1.tgz",
+ "integrity": "sha512-Z/ZeOgVl7bcSYZ/u/rh0fOpvEpq//LZmdbkXyc7syVzjPAhfOa9ebsdTSjEBDU4vs5nC98Kfduj1uFo0qyET3g==",
"license": "Apache-2.0",
"engines": {
"node": ">= 0.4"
@@ -3774,6 +5252,8 @@
},
"node_modules/array-back": {
"version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.3.tgz",
+ "integrity": "sha512-SGDvmg6QTYiTxCBkYVmThcoa67uLl35pyzRHdpCGBOcqFy6BtwnphoFPk7LhJshD+Yk1Kt35WGWeZPTgwR4Fhw==",
"license": "MIT",
"engines": {
"node": ">=12.17"
@@ -3781,11 +5261,15 @@
},
"node_modules/array-ify": {
"version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz",
+ "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==",
"dev": true,
"license": "MIT"
},
"node_modules/array-union": {
"version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
+ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -3794,6 +5278,8 @@
},
"node_modules/aws-msk-iam-sasl-signer-js": {
"version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/aws-msk-iam-sasl-signer-js/-/aws-msk-iam-sasl-signer-js-1.0.3.tgz",
+ "integrity": "sha512-bFsI5p7HAUtVxXLNWLgbcLGFKiUuoTphCNq/UoSW5669LXomh2qI7gAvY0JP8l0UaLXjNKr+D+MeQY0Gqm8RKg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -3810,6 +5296,8 @@
},
"node_modules/aws-msk-iam-sasl-signer-js/node_modules/@aws-crypto/sha256-js": {
"version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-4.0.0.tgz",
+ "integrity": "sha512-MHGJyjE7TX9aaqXj7zk2ppnFUOhaDs5sP+HtNS0evOxn72c+5njUmyJmpGd7TfyoDznZlHMmdo/xGUdu2NIjNQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -3820,11 +5308,15 @@
},
"node_modules/aws-msk-iam-sasl-signer-js/node_modules/@aws-crypto/sha256-js/node_modules/tslib": {
"version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
"dev": true,
"license": "0BSD"
},
"node_modules/aws-msk-iam-sasl-signer-js/node_modules/@aws-crypto/util": {
"version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-4.0.0.tgz",
+ "integrity": "sha512-2EnmPy2gsFZ6m8bwUQN4jq+IyXV3quHAcwPOS6ZA3k+geujiqI8aRokO2kFJe+idJ/P3v4qWI186rVMo0+zLDQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -3835,11 +5327,15 @@
},
"node_modules/aws-msk-iam-sasl-signer-js/node_modules/@aws-crypto/util/node_modules/tslib": {
"version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
"dev": true,
"license": "0BSD"
},
"node_modules/aws-msk-iam-sasl-signer-js/node_modules/@smithy/signature-v4": {
"version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-2.3.0.tgz",
+ "integrity": "sha512-ui/NlpILU+6HAQBfJX8BBsDXuKSNrjTSuOYArRblcrErwKFutjrCNb/OExfVRyj9+26F9J+ZmfWT+fKWuDrH3Q==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -3857,6 +5353,8 @@
},
"node_modules/aws-msk-iam-sasl-signer-js/node_modules/@smithy/types": {
"version": "2.12.0",
+ "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.12.0.tgz",
+ "integrity": "sha512-QwYgloJ0sVNBeBuBs65cIkTbfzV/Q6ZNPCJ99EICFEdJYG50nGIY/uYXp+TbsdJReIuPr0a0kXmCvren3MbRRw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -3868,6 +5366,8 @@
},
"node_modules/aws-sdk-client-mock": {
"version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/aws-sdk-client-mock/-/aws-sdk-client-mock-4.1.0.tgz",
+ "integrity": "sha512-h/tOYTkXEsAcV3//6C1/7U4ifSpKyJvb6auveAepqqNJl6TdZaPFEtKjBQNf8UxQdDP850knB2i/whq4zlsxJw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3878,6 +5378,8 @@
},
"node_modules/axobject-query": {
"version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz",
+ "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==",
"license": "Apache-2.0",
"engines": {
"node": ">= 0.4"
@@ -3885,6 +5387,8 @@
},
"node_modules/balanced-match": {
"version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz",
+ "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -3893,6 +5397,8 @@
},
"node_modules/base64-js": {
"version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
"dev": true,
"funding": [
{
@@ -3912,6 +5418,8 @@
},
"node_modules/baseline-browser-mapping": {
"version": "2.10.37",
+ "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.37.tgz",
+ "integrity": "sha512-girxaJ7WZssDOFhzCGZTDKoTa1gk6A1TbflaYTpykLJ4UU9Fz9kx1aREM8JCuoVHbL8X8T/mJg7w2oYSq72Oig==",
"dev": true,
"license": "Apache-2.0",
"bin": {
@@ -3923,21 +5431,29 @@
},
"node_modules/blake3-wasm": {
"version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/blake3-wasm/-/blake3-wasm-2.1.5.tgz",
+ "integrity": "sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==",
"dev": true,
"license": "MIT"
},
"node_modules/boolbase": {
"version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+ "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
"dev": true,
"license": "ISC"
},
"node_modules/bowser": {
"version": "2.14.1",
+ "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.14.1.tgz",
+ "integrity": "sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==",
"dev": true,
"license": "MIT"
},
"node_modules/brace-expansion": {
"version": "5.0.6",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz",
+ "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3949,6 +5465,8 @@
},
"node_modules/braces": {
"version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3960,6 +5478,8 @@
},
"node_modules/brotli-wasm": {
"version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/brotli-wasm/-/brotli-wasm-3.0.1.tgz",
+ "integrity": "sha512-U3K72/JAi3jITpdhZBqzSUq+DUY697tLxOuFXB+FpAE/Ug+5C3VZrv4uA674EUZHxNAuQ9wETXNqQkxZD6oL4A==",
"dev": true,
"license": "Apache-2.0",
"engines": {
@@ -3968,6 +5488,8 @@
},
"node_modules/browserslist": {
"version": "4.28.2",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz",
+ "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==",
"dev": true,
"funding": [
{
@@ -4000,6 +5522,8 @@
},
"node_modules/buffer": {
"version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz",
+ "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4009,6 +5533,8 @@
},
"node_modules/call-bind-apply-helpers": {
"version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
+ "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4021,6 +5547,8 @@
},
"node_modules/call-bound": {
"version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
+ "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4036,6 +5564,8 @@
},
"node_modules/callsites": {
"version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -4044,6 +5574,8 @@
},
"node_modules/camelcase": {
"version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -4052,6 +5584,8 @@
},
"node_modules/caniuse-lite": {
"version": "1.0.30001799",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001799.tgz",
+ "integrity": "sha512-hG1bReV+OUU+MOqK4t/ZWI0tZOyz3rqS9XuhOUz1cIcbwBKjOyJEJuw9ER5JuNyqxNk8u/JUVbGibBOL1yrjFw==",
"dev": true,
"funding": [
{
@@ -4071,6 +5605,8 @@
},
"node_modules/chalk": {
"version": "5.6.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz",
+ "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -4082,6 +5618,8 @@
},
"node_modules/chalk-template": {
"version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/chalk-template/-/chalk-template-0.4.0.tgz",
+ "integrity": "sha512-/ghrgmhfY8RaSdeo43hNXxpoHAtxdbskUHjPpfqUWGttFgycUhYPGx3YZBCnUCvOa7Doivn1IZec3DEGFoMgLg==",
"license": "MIT",
"dependencies": {
"chalk": "^4.1.2"
@@ -4095,6 +5633,8 @@
},
"node_modules/chalk-template/node_modules/ansi-styles": {
"version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"license": "MIT",
"dependencies": {
"color-convert": "^2.0.1"
@@ -4108,6 +5648,8 @@
},
"node_modules/chalk-template/node_modules/chalk": {
"version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"license": "MIT",
"dependencies": {
"ansi-styles": "^4.1.0",
@@ -4122,6 +5664,8 @@
},
"node_modules/chalk-template/node_modules/color-convert": {
"version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"license": "MIT",
"dependencies": {
"color-name": "~1.1.4"
@@ -4132,18 +5676,26 @@
},
"node_modules/chalk-template/node_modules/color-name": {
"version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"license": "MIT"
},
"node_modules/change-case": {
"version": "5.4.4",
+ "resolved": "https://registry.npmjs.org/change-case/-/change-case-5.4.4.tgz",
+ "integrity": "sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==",
"license": "MIT"
},
"node_modules/chardet": {
"version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.1.tgz",
+ "integrity": "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==",
"license": "MIT"
},
"node_modules/cheerio": {
"version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.2.0.tgz",
+ "integrity": "sha512-WDrybc/gKFpTYQutKIK6UvfcuxijIZfMfXaYm8NMsPQxSYvf+13fXUJ4rztGGbJcBQ/GF55gvrZ0Bc0bj/mqvg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4168,6 +5720,8 @@
},
"node_modules/cheerio-select": {
"version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz",
+ "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
@@ -4184,6 +5738,8 @@
},
"node_modules/cheerio/node_modules/undici": {
"version": "7.27.2",
+ "resolved": "https://registry.npmjs.org/undici/-/undici-7.27.2.tgz",
+ "integrity": "sha512-uZsKNuzQxDMUY6M3pIMvy5tvlGmtq8XJ2oLAkfRKGNu+1VQAIvLy2xIVG5ATZl5wDXl/tddByAWCizRbOme+TA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -4192,6 +5748,8 @@
},
"node_modules/cli-width": {
"version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz",
+ "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==",
"dev": true,
"license": "ISC",
"engines": {
@@ -4200,6 +5758,8 @@
},
"node_modules/cliui": {
"version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz",
+ "integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==",
"dev": true,
"license": "ISC",
"dependencies": {
@@ -4213,6 +5773,8 @@
},
"node_modules/clsx": {
"version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
+ "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==",
"license": "MIT",
"engines": {
"node": ">=6"
@@ -4220,6 +5782,8 @@
},
"node_modules/color-convert": {
"version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-3.1.3.tgz",
+ "integrity": "sha512-fasDH2ont2GqF5HpyO4w0+BcewlhHEZOFn9c1ckZdHpJ56Qb7MHhH/IcJZbBGgvdtwdwNbLvxiBEdg336iA9Sg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4231,6 +5795,8 @@
},
"node_modules/color-name": {
"version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz",
+ "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -4239,6 +5805,8 @@
},
"node_modules/command-line-args": {
"version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-6.0.2.tgz",
+ "integrity": "sha512-AIjYVxrV9X752LmPDLbVYv8aMCuHPSLZJXEo2qo/xJfv+NYhaZ4sMSF01rM+gHPaMgvPM0l5D/F+Qx+i2WfSmQ==",
"license": "MIT",
"dependencies": {
"array-back": "^6.2.3",
@@ -4260,6 +5828,8 @@
},
"node_modules/command-line-usage": {
"version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-7.0.4.tgz",
+ "integrity": "sha512-85UdvzTNx/+s5CkSgBm/0hzP80RFHAa7PsfeADE5ezZF3uHz3/Tqj9gIKGT9PTtpycc3Ua64T0oVulGfKxzfqg==",
"license": "MIT",
"dependencies": {
"array-back": "^6.2.2",
@@ -4273,6 +5843,8 @@
},
"node_modules/commander": {
"version": "14.0.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz",
+ "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==",
"license": "MIT",
"engines": {
"node": ">=20"
@@ -4280,6 +5852,8 @@
},
"node_modules/compare-func": {
"version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz",
+ "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4289,6 +5863,8 @@
},
"node_modules/complex.js": {
"version": "2.4.3",
+ "resolved": "https://registry.npmjs.org/complex.js/-/complex.js-2.4.3.tgz",
+ "integrity": "sha512-UrQVSUur14tNX6tiP4y8T4w4FeJAX3bi2cIv0pu/DTLFNxoq7z2Yh83Vfzztj6Px3X/lubqQ9IrPp7Bpn6p4MQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -4301,6 +5877,8 @@
},
"node_modules/condense-newlines": {
"version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/condense-newlines/-/condense-newlines-0.2.1.tgz",
+ "integrity": "sha512-P7X+QL9Hb9B/c8HI5BFFKmjgBu2XpQuF98WZ9XkO+dBGgk5XgwiQz7o1SmpglNWId3581UcS0SFAWfoIhMHPfg==",
"license": "MIT",
"dependencies": {
"extend-shallow": "^2.0.1",
@@ -4313,6 +5891,8 @@
},
"node_modules/config-chain": {
"version": "1.1.13",
+ "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz",
+ "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==",
"license": "MIT",
"dependencies": {
"ini": "^1.3.4",
@@ -4321,10 +5901,14 @@
},
"node_modules/config-chain/node_modules/ini": {
"version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
+ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
"license": "ISC"
},
"node_modules/conventional-changelog-angular": {
"version": "8.3.1",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-8.3.1.tgz",
+ "integrity": "sha512-6gfI3otXK5Ph5DfCOI1dblr+kN3FAm5a97hYoQkqNZxOaYa5WKfXH+AnpsmS+iUH2mgVC2Cg2Qw9m5OKcmNrIg==",
"dev": true,
"license": "ISC",
"dependencies": {
@@ -4336,6 +5920,8 @@
},
"node_modules/conventional-changelog-conventionalcommits": {
"version": "9.3.1",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-9.3.1.tgz",
+ "integrity": "sha512-dTYtpIacRpcZgrvBYvBfArMmK2xvIpv2TaxM0/ZI5CBtNUzvF2x0t15HsbRABWprS6UPmvj+PzHVjSx4qAVKyw==",
"dev": true,
"license": "ISC",
"dependencies": {
@@ -4347,6 +5933,8 @@
},
"node_modules/conventional-commits-parser": {
"version": "6.4.0",
+ "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-6.4.0.tgz",
+ "integrity": "sha512-tvRg7FIBNlyPzjdG8wWRlPHQJJHI7DylhtRGeU9Lq+JuoPh5BKpPRX83ZdLrvXuOSu5Eo/e7SzOQhU4Hd2Miuw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4362,11 +5950,15 @@
},
"node_modules/convert-source-map": {
"version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
"dev": true,
"license": "MIT"
},
"node_modules/cookie": {
"version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
+ "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
"dev": true,
"license": "MIT",
"engines": {
@@ -4375,6 +5967,8 @@
},
"node_modules/cosmiconfig": {
"version": "9.0.2",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.2.tgz",
+ "integrity": "sha512-gtTZxTDau1wL7Y7zifc2dd8jHSK/k6BTx/2Xp/BpdlAdnlYWFVt7qhJqgwi7637yRwRQ3qL4ZidbB4I8tA5VOg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4400,6 +5994,8 @@
},
"node_modules/cosmiconfig-typescript-loader": {
"version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-6.3.0.tgz",
+ "integrity": "sha512-Akr82WH1Wfqatyiqpj8HDkO2o2KmJRu1FhKfSNJP3K4IdXwHfEyL7MOb62i1AGQVLtIQM+iCE9CGOtrfhR+mmA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4416,6 +6012,8 @@
},
"node_modules/cross-spawn": {
"version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
"license": "MIT",
"dependencies": {
"path-key": "^3.1.0",
@@ -4428,6 +6026,8 @@
},
"node_modules/css-select": {
"version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz",
+ "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
@@ -4443,6 +6043,8 @@
},
"node_modules/css-tree": {
"version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.2.1.tgz",
+ "integrity": "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4455,6 +6057,8 @@
},
"node_modules/css-what": {
"version": "6.2.2",
+ "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz",
+ "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==",
"dev": true,
"license": "BSD-2-Clause",
"engines": {
@@ -4466,6 +6070,8 @@
},
"node_modules/csso": {
"version": "5.0.5",
+ "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz",
+ "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4478,6 +6084,8 @@
},
"node_modules/csso/node_modules/css-tree": {
"version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz",
+ "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4491,6 +6099,8 @@
},
"node_modules/csso/node_modules/mdn-data": {
"version": "2.0.28",
+ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz",
+ "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==",
"dev": true,
"license": "CC0-1.0"
},
@@ -4500,6 +6110,8 @@
},
"node_modules/debug": {
"version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4516,6 +6128,8 @@
},
"node_modules/decamelize": {
"version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+ "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -4524,11 +6138,15 @@
},
"node_modules/decimal.js": {
"version": "10.6.0",
+ "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz",
+ "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==",
"dev": true,
"license": "MIT"
},
"node_modules/deepmerge": {
"version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
+ "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
"dev": true,
"license": "MIT",
"engines": {
@@ -4537,6 +6155,8 @@
},
"node_modules/des.js": {
"version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz",
+ "integrity": "sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4546,6 +6166,8 @@
},
"node_modules/detect-libc": {
"version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
+ "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
"dev": true,
"license": "Apache-2.0",
"engines": {
@@ -4554,10 +6176,14 @@
},
"node_modules/devalue": {
"version": "5.8.1",
+ "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.8.1.tgz",
+ "integrity": "sha512-4CXDYRBGqN+57wVJkuXBYmpAVUSg3L6JAQa/DFqm238G73E1wuyc/JhGQJzN7vUf/CMphYau2zXbfWzDR5aTEw==",
"license": "MIT"
},
"node_modules/diff": {
"version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.2.tgz",
+ "integrity": "sha512-vtcDfH3TOjP8UekytvnHH1o1P4FcUdt4eQ1Y+Abap1tk/OB2MWQvcwS2ClCd1zuIhc3JKOx6p3kod8Vfys3E+A==",
"dev": true,
"license": "BSD-3-Clause",
"engines": {
@@ -4566,11 +6192,15 @@
},
"node_modules/diff-match-patch": {
"version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.5.tgz",
+ "integrity": "sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==",
"dev": true,
"license": "Apache-2.0"
},
"node_modules/dir-glob": {
"version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
+ "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4582,10 +6212,14 @@
},
"node_modules/discontinuous-range": {
"version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/discontinuous-range/-/discontinuous-range-1.0.0.tgz",
+ "integrity": "sha512-c68LpLbO+7kP/b1Hr1qs8/BJ09F5khZGTxqxZuhzxpmwJKOgRFHJWIb9/KmqnqHhLdO55aOxFH/EGBvUQbL/RQ==",
"license": "MIT"
},
"node_modules/dom-serializer": {
"version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
+ "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4599,6 +6233,8 @@
},
"node_modules/domelementtype": {
"version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
+ "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
"dev": true,
"funding": [
{
@@ -4610,6 +6246,8 @@
},
"node_modules/domhandler": {
"version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
+ "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
@@ -4624,6 +6262,8 @@
},
"node_modules/domutils": {
"version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz",
+ "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
@@ -4637,6 +6277,8 @@
},
"node_modules/dot-prop": {
"version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz",
+ "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4648,6 +6290,8 @@
},
"node_modules/dunder-proto": {
"version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
+ "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4661,10 +6305,14 @@
},
"node_modules/eastasianwidth": {
"version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
+ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
"license": "MIT"
},
"node_modules/editorconfig": {
"version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-1.0.7.tgz",
+ "integrity": "sha512-e0GOtq/aTQhVdNyDU9e02+wz9oDDM+SIOQxWME2QRjzRX5yyLAuHDE+0aE8vHb9XRC8XD37eO2u57+F09JqFhw==",
"license": "MIT",
"dependencies": {
"@one-ini/wasm": "0.1.1",
@@ -4681,10 +6329,14 @@
},
"node_modules/editorconfig/node_modules/balanced-match": {
"version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"license": "MIT"
},
"node_modules/editorconfig/node_modules/brace-expansion": {
"version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.1.tgz",
+ "integrity": "sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==",
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0"
@@ -4692,6 +6344,8 @@
},
"node_modules/editorconfig/node_modules/commander": {
"version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
+ "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==",
"license": "MIT",
"engines": {
"node": ">=14"
@@ -4699,6 +6353,8 @@
},
"node_modules/editorconfig/node_modules/minimatch": {
"version": "9.0.9",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
+ "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
"license": "ISC",
"dependencies": {
"brace-expansion": "^2.0.2"
@@ -4712,16 +6368,22 @@
},
"node_modules/electron-to-chromium": {
"version": "1.5.372",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.372.tgz",
+ "integrity": "sha512-M3yhbAlilnwqC8D21t28UCDGHyitShTmmLRU/H+b74P6Ski16Nb9HONYEaVpMj/pwC7BEo5B95FpjODLCWbtfA==",
"dev": true,
"license": "ISC"
},
"node_modules/emoji-regex": {
"version": "10.6.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz",
+ "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==",
"dev": true,
"license": "MIT"
},
"node_modules/encoding-sniffer": {
"version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz",
+ "integrity": "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4734,6 +6396,8 @@
},
"node_modules/encoding-sniffer/node_modules/iconv-lite": {
"version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4745,6 +6409,8 @@
},
"node_modules/entities": {
"version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+ "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
"dev": true,
"license": "BSD-2-Clause",
"engines": {
@@ -4756,6 +6422,8 @@
},
"node_modules/env-paths": {
"version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
+ "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
"dev": true,
"license": "MIT",
"engines": {
@@ -4764,6 +6432,8 @@
},
"node_modules/error-ex": {
"version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz",
+ "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4772,6 +6442,8 @@
},
"node_modules/error-stack-parser-es": {
"version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/error-stack-parser-es/-/error-stack-parser-es-1.0.5.tgz",
+ "integrity": "sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==",
"dev": true,
"license": "MIT",
"funding": {
@@ -4780,6 +6452,8 @@
},
"node_modules/es-define-property": {
"version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
+ "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
"dev": true,
"license": "MIT",
"engines": {
@@ -4788,6 +6462,8 @@
},
"node_modules/es-errors": {
"version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
+ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -4796,6 +6472,8 @@
},
"node_modules/es-object-atoms": {
"version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz",
+ "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4807,6 +6485,8 @@
},
"node_modules/es-toolkit": {
"version": "1.47.1",
+ "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.47.1.tgz",
+ "integrity": "sha512-5RAqEwf4P4E17p+W75KLOWw/nOvKZzSQpxM32IpI2KZLaVonjTrZ0Ai5ghMaVI9eKC2p8eoQgcBdkEDgzFk6+Q==",
"dev": true,
"license": "MIT",
"workspaces": [
@@ -4816,6 +6496,8 @@
},
"node_modules/esbuild": {
"version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz",
+ "integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==",
"hasInstallScript": true,
"license": "MIT",
"bin": {
@@ -4855,6 +6537,8 @@
},
"node_modules/escalade": {
"version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -4863,15 +6547,21 @@
},
"node_modules/escape-latex": {
"version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/escape-latex/-/escape-latex-1.2.0.tgz",
+ "integrity": "sha512-nV5aVWW1K0wEiUIEdZ4erkGGH8mDxGyxSeqPzRNtWP7ataw+/olFObw7hujFWlVjNsaDFw5VZ5NzVSIqRgfTiw==",
"dev": true,
"license": "MIT"
},
"node_modules/esm-env": {
"version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.2.2.tgz",
+ "integrity": "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==",
"license": "MIT"
},
"node_modules/esprima": {
"version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
"dev": true,
"license": "BSD-2-Clause",
"bin": {
@@ -4884,6 +6574,8 @@
},
"node_modules/esrap": {
"version": "2.2.11",
+ "resolved": "https://registry.npmjs.org/esrap/-/esrap-2.2.11.tgz",
+ "integrity": "sha512-gPdx+I+BjYEinNMQaBXFjbaJVyoPMU4ZODg5mE+M4DqVG9VusAVHHjcBX+zqyITlI0DIARwDMMzZwAWj36dRoQ==",
"license": "MIT",
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.4.15"
@@ -4899,6 +6591,8 @@
},
"node_modules/events": {
"version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
+ "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
"dev": true,
"license": "MIT",
"engines": {
@@ -4907,6 +6601,8 @@
},
"node_modules/execa": {
"version": "9.6.1",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-9.6.1.tgz",
+ "integrity": "sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4932,6 +6628,8 @@
},
"node_modules/extend-shallow": {
"version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==",
"license": "MIT",
"dependencies": {
"is-extendable": "^0.1.0"
@@ -4942,6 +6640,8 @@
},
"node_modules/fast-check": {
"version": "4.8.0",
+ "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-4.8.0.tgz",
+ "integrity": "sha512-GOJ158CUMnN6cSahsv4+ExARvIDuzzinFjkp0E9WtiBa5zcVeLozVkWaE4IzFcc+Y48Wp1EDlUZsXRyAztQcSg==",
"dev": true,
"funding": [
{
@@ -4963,10 +6663,14 @@
},
"node_modules/fast-deep-equal": {
"version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
"license": "MIT"
},
"node_modules/fast-glob": {
"version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
+ "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4982,11 +6686,15 @@
},
"node_modules/fast-string-truncated-width": {
"version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/fast-string-truncated-width/-/fast-string-truncated-width-3.0.3.tgz",
+ "integrity": "sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g==",
"dev": true,
"license": "MIT"
},
"node_modules/fast-string-width": {
"version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/fast-string-width/-/fast-string-width-3.0.2.tgz",
+ "integrity": "sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4995,6 +6703,8 @@
},
"node_modules/fast-uri": {
"version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz",
+ "integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==",
"funding": [
{
"type": "github",
@@ -5009,6 +6719,8 @@
},
"node_modules/fast-wrap-ansi": {
"version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/fast-wrap-ansi/-/fast-wrap-ansi-0.2.2.tgz",
+ "integrity": "sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5017,6 +6729,8 @@
},
"node_modules/fast-xml-builder": {
"version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.2.0.tgz",
+ "integrity": "sha512-00aAWieqff+ZJhsXA4g1g7M8k+7AYoMUUHF+/zFb5U6Uv/P0Vl4QZo84/IcufzYalLuEj9928bXN9PbbFzMF0Q==",
"dev": true,
"funding": [
{
@@ -5032,6 +6746,8 @@
},
"node_modules/fast-xml-parser": {
"version": "5.7.3",
+ "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.7.3.tgz",
+ "integrity": "sha512-C0AaNuC+mscy6vrAQKAc/rMq+zAPHodfHGZu4sGVehvAQt/JLG1O5zEcYcXSY5zSqr4YVgxsB+pHXTq0i7eDlg==",
"dev": true,
"funding": [
{
@@ -5052,6 +6768,8 @@
},
"node_modules/fastq": {
"version": "1.20.1",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz",
+ "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==",
"dev": true,
"license": "ISC",
"dependencies": {
@@ -5060,6 +6778,8 @@
},
"node_modules/figures": {
"version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/figures/-/figures-6.1.0.tgz",
+ "integrity": "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5074,6 +6794,8 @@
},
"node_modules/fill-range": {
"version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5085,6 +6807,8 @@
},
"node_modules/find-replace": {
"version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-5.0.2.tgz",
+ "integrity": "sha512-Y45BAiE3mz2QsrN2fb5QEtO4qb44NcS7en/0y9PEVsg351HsLeVclP8QPMH79Le9sH3rs5RSwJu99W0WPZO43Q==",
"license": "MIT",
"engines": {
"node": ">=14"
@@ -5100,6 +6824,8 @@
},
"node_modules/find-up": {
"version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+ "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5111,10 +6837,14 @@
},
"node_modules/flatbuffers": {
"version": "25.9.23",
+ "resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-25.9.23.tgz",
+ "integrity": "sha512-MI1qs7Lo4Syw0EOzUl0xjs2lsoeqFku44KpngfIduHBYvzm8h2+7K8YMQh1JtVVVrUvhLpNwqVi4DERegUJhPQ==",
"license": "Apache-2.0"
},
"node_modules/fluent-transpiler": {
"version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/fluent-transpiler/-/fluent-transpiler-0.4.1.tgz",
+ "integrity": "sha512-9CNRxPbnMDTt1hdtD2YPdbyH/p5o3xRgkcsZm0dgER+Kg2k3mdvDb4BJ6lVeFx+cGKp6GWPxcZ2n8R4b45JqJw==",
"license": "MIT",
"workspaces": [
".github"
@@ -5137,6 +6867,8 @@
},
"node_modules/foreground-child": {
"version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
+ "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==",
"license": "ISC",
"dependencies": {
"cross-spawn": "^7.0.6",
@@ -5151,6 +6883,8 @@
},
"node_modules/fraction.js": {
"version": "5.3.4",
+ "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.3.4.tgz",
+ "integrity": "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -5163,6 +6897,8 @@
},
"node_modules/fs-extra": {
"version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
+ "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5176,12 +6912,17 @@
},
"node_modules/fs.realpath": {
"version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
"dev": true,
"license": "ISC"
},
"node_modules/fsevents": {
"version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
"dev": true,
+ "hasInstallScript": true,
"license": "MIT",
"optional": true,
"os": [
@@ -5193,6 +6934,8 @@
},
"node_modules/function-bind": {
"version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
"dev": true,
"license": "MIT",
"funding": {
@@ -5201,6 +6944,8 @@
},
"node_modules/gensync": {
"version": "1.0.0-beta.2",
+ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -5209,6 +6954,8 @@
},
"node_modules/get-caller-file": {
"version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
"dev": true,
"license": "ISC",
"engines": {
@@ -5217,6 +6964,8 @@
},
"node_modules/get-east-asian-width": {
"version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz",
+ "integrity": "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -5228,6 +6977,8 @@
},
"node_modules/get-intrinsic": {
"version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
+ "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5251,6 +7002,8 @@
},
"node_modules/get-proto": {
"version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
+ "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5263,6 +7016,8 @@
},
"node_modules/get-stream": {
"version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz",
+ "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5278,6 +7033,8 @@
},
"node_modules/git-raw-commits": {
"version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-5.0.1.tgz",
+ "integrity": "sha512-Y+csSm2GD/PCSh6Isd/WiMjNAydu0VBiG9J7EdQsNA5P9uXvLayqjmTsNlK5Gs9IhblFZqOU0yid5Il5JPoLiQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5293,6 +7050,8 @@
},
"node_modules/gitignore-to-glob": {
"version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/gitignore-to-glob/-/gitignore-to-glob-0.3.0.tgz",
+ "integrity": "sha512-mk74BdnK7lIwDHnotHddx1wsjMOFIThpLY3cPNniJ/2fA/tlLzHnFxIdR+4sLOu5KGgQJdij4kjJ2RoUNnCNMA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -5301,6 +7060,9 @@
},
"node_modules/glob": {
"version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me",
"dev": true,
"license": "ISC",
"dependencies": {
@@ -5320,6 +7082,8 @@
},
"node_modules/glob-parent": {
"version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
"dev": true,
"license": "ISC",
"dependencies": {
@@ -5331,6 +7095,8 @@
},
"node_modules/global-directory": {
"version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/global-directory/-/global-directory-5.0.0.tgz",
+ "integrity": "sha512-1pgFdhK3J2LeM+dVf2Pd424yHx2ou338lC0ErNP2hPx4j8eW1Sp0XqSjNxtk6Tc4Kr5wlWtSvz8cn2yb7/SG/w==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5345,6 +7111,8 @@
},
"node_modules/globby": {
"version": "10.0.2",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz",
+ "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5363,6 +7131,8 @@
},
"node_modules/gopd": {
"version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -5374,11 +7144,15 @@
},
"node_modules/graceful-fs": {
"version": "4.2.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
"dev": true,
"license": "ISC"
},
"node_modules/has-flag": {
"version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"license": "MIT",
"engines": {
"node": ">=8"
@@ -5386,6 +7160,8 @@
},
"node_modules/has-symbols": {
"version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
+ "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -5397,10 +7173,14 @@
},
"node_modules/hash-wasm": {
"version": "4.12.0",
+ "resolved": "https://registry.npmjs.org/hash-wasm/-/hash-wasm-4.12.0.tgz",
+ "integrity": "sha512-+/2B2rYLb48I/evdOIhP+K/DD2ca2fgBjp6O+GBEnCDk2e4rpeXIK8GvIyRPjTezgmWn9gmKwkQjjx6BtqDHVQ==",
"license": "MIT"
},
"node_modules/hasown": {
"version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz",
+ "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5412,6 +7192,8 @@
},
"node_modules/hast-util-to-string": {
"version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/hast-util-to-string/-/hast-util-to-string-3.0.1.tgz",
+ "integrity": "sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==",
"license": "MIT",
"dependencies": {
"@types/hast": "^3.0.0"
@@ -5423,6 +7205,8 @@
},
"node_modules/htmlparser2": {
"version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.1.0.tgz",
+ "integrity": "sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==",
"dev": true,
"funding": [
"https://github.com/fb55/htmlparser2?sponsor=1",
@@ -5441,6 +7225,8 @@
},
"node_modules/htmlparser2/node_modules/entities": {
"version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz",
+ "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==",
"dev": true,
"license": "BSD-2-Clause",
"engines": {
@@ -5452,6 +7238,8 @@
},
"node_modules/human-signals": {
"version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.1.tgz",
+ "integrity": "sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==",
"dev": true,
"license": "Apache-2.0",
"engines": {
@@ -5460,6 +7248,8 @@
},
"node_modules/husky": {
"version": "9.1.7",
+ "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz",
+ "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==",
"dev": true,
"license": "MIT",
"bin": {
@@ -5474,6 +7264,8 @@
},
"node_modules/iconv-lite": {
"version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz",
+ "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==",
"license": "MIT",
"dependencies": {
"safer-buffer": ">= 2.1.2 < 3.0.0"
@@ -5488,10 +7280,14 @@
},
"node_modules/idb": {
"version": "8.0.3",
+ "resolved": "https://registry.npmjs.org/idb/-/idb-8.0.3.tgz",
+ "integrity": "sha512-LtwtVyVYO5BqRvcsKuB2iUMnHwPVByPCXFXOpuU96IZPPoPN6xjOGxZQ74pgSVVLQWtUOYgyeL4GE98BY5D3wg==",
"license": "ISC"
},
"node_modules/ieee754": {
"version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
"dev": true,
"funding": [
{
@@ -5511,6 +7307,8 @@
},
"node_modules/ignore": {
"version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
"dev": true,
"license": "MIT",
"engines": {
@@ -5519,6 +7317,8 @@
},
"node_modules/import-fresh": {
"version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
+ "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5534,6 +7334,8 @@
},
"node_modules/import-fresh/node_modules/resolve-from": {
"version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
"dev": true,
"license": "MIT",
"engines": {
@@ -5542,6 +7344,9 @@
},
"node_modules/inflight": {
"version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
"dev": true,
"license": "ISC",
"dependencies": {
@@ -5551,11 +7356,15 @@
},
"node_modules/inherits": {
"version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
"dev": true,
"license": "ISC"
},
"node_modules/ini": {
"version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-6.0.0.tgz",
+ "integrity": "sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ==",
"dev": true,
"license": "ISC",
"engines": {
@@ -5564,15 +7373,21 @@
},
"node_modules/is-arrayish": {
"version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
"dev": true,
"license": "MIT"
},
"node_modules/is-buffer": {
"version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
"license": "MIT"
},
"node_modules/is-extendable": {
"version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+ "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
@@ -5580,6 +7395,8 @@
},
"node_modules/is-extglob": {
"version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -5588,6 +7405,8 @@
},
"node_modules/is-fullwidth-code-point": {
"version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
"license": "MIT",
"engines": {
"node": ">=8"
@@ -5595,6 +7414,8 @@
},
"node_modules/is-glob": {
"version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5606,6 +7427,8 @@
},
"node_modules/is-number": {
"version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
"dev": true,
"license": "MIT",
"engines": {
@@ -5614,6 +7437,8 @@
},
"node_modules/is-obj": {
"version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz",
+ "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==",
"dev": true,
"license": "MIT",
"engines": {
@@ -5622,6 +7447,8 @@
},
"node_modules/is-plain-obj": {
"version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz",
+ "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -5633,6 +7460,8 @@
},
"node_modules/is-reference": {
"version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.3.tgz",
+ "integrity": "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==",
"license": "MIT",
"dependencies": {
"@types/estree": "^1.0.6"
@@ -5640,6 +7469,8 @@
},
"node_modules/is-stream": {
"version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz",
+ "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==",
"dev": true,
"license": "MIT",
"engines": {
@@ -5651,6 +7482,8 @@
},
"node_modules/is-unicode-supported": {
"version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz",
+ "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -5662,6 +7495,8 @@
},
"node_modules/is-whitespace": {
"version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/is-whitespace/-/is-whitespace-0.3.0.tgz",
+ "integrity": "sha512-RydPhl4S6JwAyj0JJjshWJEFG6hNye3pZFBRZaTUfZFwGHxzppNaNOVgQuS/E/SlhrApuMXrpnK1EEIXfdo3Dg==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
@@ -5669,10 +7504,14 @@
},
"node_modules/isexe": {
"version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
"license": "ISC"
},
"node_modules/jackspeak": {
"version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
+ "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
"license": "BlueOak-1.0.0",
"dependencies": {
"@isaacs/cliui": "^8.0.2"
@@ -5686,11 +7525,15 @@
},
"node_modules/javascript-natural-sort": {
"version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz",
+ "integrity": "sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==",
"dev": true,
"license": "MIT"
},
"node_modules/jiti": {
"version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz",
+ "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==",
"dev": true,
"license": "MIT",
"bin": {
@@ -5699,6 +7542,8 @@
},
"node_modules/js-beautify": {
"version": "1.15.4",
+ "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.15.4.tgz",
+ "integrity": "sha512-9/KXeZUKKJwqCXUdBxFJ3vPh467OCckSBmYDwSK/EtV090K+iMJ7zx2S3HLVDIWFQdqMIsZWbnaGiba18aWhaA==",
"license": "MIT",
"dependencies": {
"config-chain": "^1.1.13",
@@ -5718,10 +7563,14 @@
},
"node_modules/js-beautify/node_modules/balanced-match": {
"version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"license": "MIT"
},
"node_modules/js-beautify/node_modules/brace-expansion": {
"version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.1.tgz",
+ "integrity": "sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==",
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0"
@@ -5729,6 +7578,9 @@
},
"node_modules/js-beautify/node_modules/glob": {
"version": "10.5.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz",
+ "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==",
+ "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me",
"license": "ISC",
"dependencies": {
"foreground-child": "^3.1.0",
@@ -5747,6 +7599,8 @@
},
"node_modules/js-beautify/node_modules/minimatch": {
"version": "9.0.9",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
+ "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
"license": "ISC",
"dependencies": {
"brace-expansion": "^2.0.2"
@@ -5760,20 +7614,28 @@
},
"node_modules/js-cookie": {
"version": "3.0.8",
+ "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.8.tgz",
+ "integrity": "sha512-yeJd4aNAdYZQjaon2bpD/Gb0B/omw7HQOsynXXcOiWVCacbBcPlgn8S/d1X6blFSaHao7ozqtW7NZW19xpCtIw==",
"license": "MIT"
},
"node_modules/js-md4": {
"version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/js-md4/-/js-md4-0.3.2.tgz",
+ "integrity": "sha512-/GDnfQYsltsjRswQhN9fhv3EMw2sCpUdrdxyWDOUK7eyD++r3gRhzgiQgc/x4MAv2i1iuQ4lxO5mvqM3vj4bwA==",
"dev": true,
"license": "MIT"
},
"node_modules/js-tokens": {
"version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
"dev": true,
"license": "MIT"
},
"node_modules/js-yaml": {
"version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.2.0.tgz",
+ "integrity": "sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==",
"funding": [
{
"type": "github",
@@ -5794,6 +7656,8 @@
},
"node_modules/jsesc": {
"version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
+ "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
"license": "MIT",
"bin": {
"jsesc": "bin/jsesc"
@@ -5804,26 +7668,36 @@
},
"node_modules/json-bignum": {
"version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/json-bignum/-/json-bignum-0.0.3.tgz",
+ "integrity": "sha512-2WHyXj3OfHSgNyuzDbSxI1w2jgw5gkWSWhS7Qg4bWXx1nLk3jnbwfUeS0PSba3IzpTUWdHxBieELUzXRjQB2zg==",
"engines": {
"node": ">=0.8"
}
},
"node_modules/json-parse-even-better-errors": {
"version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
+ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
"dev": true,
"license": "MIT"
},
"node_modules/json-rpc-2.0": {
"version": "1.7.1",
+ "resolved": "https://registry.npmjs.org/json-rpc-2.0/-/json-rpc-2.0-1.7.1.tgz",
+ "integrity": "sha512-JqZjhjAanbpkXIzFE7u8mE/iFblawwlXtONaCvRqI+pyABVz7B4M1EUNpyVW+dZjqgQ2L5HFmZCmOCgUKm00hg==",
"dev": true,
"license": "MIT"
},
"node_modules/json-schema-traverse": {
"version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
"license": "MIT"
},
"node_modules/json5": {
"version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
"dev": true,
"license": "MIT",
"bin": {
@@ -5835,6 +7709,8 @@
},
"node_modules/jsonfile": {
"version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
+ "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==",
"dev": true,
"license": "MIT",
"optionalDependencies": {
@@ -5843,11 +7719,15 @@
},
"node_modules/just-extend": {
"version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-6.2.0.tgz",
+ "integrity": "sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==",
"dev": true,
"license": "MIT"
},
"node_modules/kafkajs": {
"version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/kafkajs/-/kafkajs-2.2.4.tgz",
+ "integrity": "sha512-j/YeapB1vfPT2iOIUn/vxdyKEuhuY2PxMBvf5JWux6iSaukAccrMtXEY/Lb7OvavDhOWME589bpLrEdnVHjfjA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -5856,6 +7736,8 @@
},
"node_modules/kind-of": {
"version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
"license": "MIT",
"dependencies": {
"is-buffer": "^1.1.5"
@@ -5866,6 +7748,8 @@
},
"node_modules/kleur": {
"version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz",
+ "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -5874,11 +7758,15 @@
},
"node_modules/libsodium": {
"version": "0.8.4",
+ "resolved": "https://registry.npmjs.org/libsodium/-/libsodium-0.8.4.tgz",
+ "integrity": "sha512-lMcYaRi0zcs7tarATsQUYC7rstliIXZuoq0c6zXSgNtSNtdvBgkSegjWhpMJAXzKX3SUSwIp7+zEsob+j3LuRw==",
"dev": true,
"license": "ISC"
},
"node_modules/libsodium-wrappers": {
"version": "0.8.4",
+ "resolved": "https://registry.npmjs.org/libsodium-wrappers/-/libsodium-wrappers-0.8.4.tgz",
+ "integrity": "sha512-mu8aAWucZjTB5O/BtGXtW4e1agy7uHxNYG7zPthmmD1jU43LCDmSWZLN4JhflbdPXj3yDO4lxM1O9hLDgIOXDw==",
"dev": true,
"license": "ISC",
"dependencies": {
@@ -5887,6 +7775,8 @@
},
"node_modules/license-check-and-add": {
"version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/license-check-and-add/-/license-check-and-add-4.0.5.tgz",
+ "integrity": "sha512-FySnMi3Kf/vO5jka8tcbVF1FhDFb8PWsQ8pg5Y7U/zkQgta+fIrJGcGHO58WFjfKlgvhneG1uQ00Fpxzhau3QA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -5902,6 +7792,8 @@
},
"node_modules/license-check-and-add/node_modules/ansi-regex": {
"version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz",
+ "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==",
"dev": true,
"license": "MIT",
"engines": {
@@ -5910,6 +7802,8 @@
},
"node_modules/license-check-and-add/node_modules/ansi-styles": {
"version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5921,6 +7815,8 @@
},
"node_modules/license-check-and-add/node_modules/cliui": {
"version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
+ "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
"dev": true,
"license": "ISC",
"dependencies": {
@@ -5931,6 +7827,8 @@
},
"node_modules/license-check-and-add/node_modules/color-convert": {
"version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5939,16 +7837,22 @@
},
"node_modules/license-check-and-add/node_modules/color-name": {
"version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
"dev": true,
"license": "MIT"
},
"node_modules/license-check-and-add/node_modules/emoji-regex": {
"version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
+ "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
"dev": true,
"license": "MIT"
},
"node_modules/license-check-and-add/node_modules/is-fullwidth-code-point": {
"version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==",
"dev": true,
"license": "MIT",
"engines": {
@@ -5957,6 +7861,8 @@
},
"node_modules/license-check-and-add/node_modules/string-width": {
"version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+ "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5970,6 +7876,8 @@
},
"node_modules/license-check-and-add/node_modules/strip-ansi": {
"version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5981,6 +7889,8 @@
},
"node_modules/license-check-and-add/node_modules/wrap-ansi": {
"version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
+ "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5994,11 +7904,15 @@
},
"node_modules/license-check-and-add/node_modules/y18n": {
"version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
+ "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==",
"dev": true,
"license": "ISC"
},
"node_modules/license-check-and-add/node_modules/yargs": {
"version": "13.3.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz",
+ "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6016,6 +7930,8 @@
},
"node_modules/license-check-and-add/node_modules/yargs-parser": {
"version": "13.1.2",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz",
+ "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==",
"dev": true,
"license": "ISC",
"dependencies": {
@@ -6025,6 +7941,8 @@
},
"node_modules/lightningcss": {
"version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz",
+ "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==",
"dev": true,
"license": "MPL-2.0",
"dependencies": {
@@ -6051,8 +7969,31 @@
"lightningcss-win32-x64-msvc": "1.32.0"
}
},
+ "node_modules/lightningcss-android-arm64": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz",
+ "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
"node_modules/lightningcss-darwin-arm64": {
"version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz",
+ "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==",
"cpu": [
"arm64"
],
@@ -6070,17 +8011,224 @@
"url": "https://opencollective.com/parcel"
}
},
+ "node_modules/lightningcss-darwin-x64": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz",
+ "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-freebsd-x64": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz",
+ "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm-gnueabihf": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz",
+ "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm64-gnu": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz",
+ "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm64-musl": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz",
+ "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-x64-gnu": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz",
+ "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-x64-musl": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz",
+ "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-win32-arm64-msvc": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz",
+ "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-win32-x64-msvc": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz",
+ "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
"node_modules/lines-and-columns": {
"version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
+ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
"dev": true,
"license": "MIT"
},
"node_modules/locate-character": {
"version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz",
+ "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==",
"license": "MIT"
},
"node_modules/locate-path": {
"version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+ "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6093,6 +8241,8 @@
},
"node_modules/lockfile-lint": {
"version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/lockfile-lint/-/lockfile-lint-5.0.0.tgz",
+ "integrity": "sha512-QcVIVITLZAhWYHU2wbNSOMgwc6EN4Y2sy6mjgS5aikYyRzgDIfotXUsCrm38En+3fZpc58Yu7DF9dNeT/goi1A==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -6111,6 +8261,8 @@
},
"node_modules/lockfile-lint-api": {
"version": "5.9.2",
+ "resolved": "https://registry.npmjs.org/lockfile-lint-api/-/lockfile-lint-api-5.9.2.tgz",
+ "integrity": "sha512-3QhxWxl3jT9GcMxuCnTsU8Tz5U6U1lKBlKBu2zOYOz/x3ONUoojEtky3uzoaaDgExcLqIX0Aqv2I7TZXE383CQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -6124,6 +8276,8 @@
},
"node_modules/lockfile-lint/node_modules/ansi-regex": {
"version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -6132,6 +8286,8 @@
},
"node_modules/lockfile-lint/node_modules/ansi-styles": {
"version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6146,6 +8302,8 @@
},
"node_modules/lockfile-lint/node_modules/cliui": {
"version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
+ "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
"dev": true,
"license": "ISC",
"dependencies": {
@@ -6159,6 +8317,8 @@
},
"node_modules/lockfile-lint/node_modules/color-convert": {
"version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6170,16 +8330,22 @@
},
"node_modules/lockfile-lint/node_modules/color-name": {
"version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true,
"license": "MIT"
},
"node_modules/lockfile-lint/node_modules/emoji-regex": {
"version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"dev": true,
"license": "MIT"
},
"node_modules/lockfile-lint/node_modules/string-width": {
"version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6193,6 +8359,8 @@
},
"node_modules/lockfile-lint/node_modules/strip-ansi": {
"version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6204,6 +8372,8 @@
},
"node_modules/lockfile-lint/node_modules/wrap-ansi": {
"version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6220,6 +8390,8 @@
},
"node_modules/lockfile-lint/node_modules/yargs": {
"version": "17.7.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
+ "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6237,6 +8409,8 @@
},
"node_modules/lockfile-lint/node_modules/yargs-parser": {
"version": "21.1.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+ "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
"dev": true,
"license": "ISC",
"engines": {
@@ -6245,20 +8419,28 @@
},
"node_modules/lodash.camelcase": {
"version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
+ "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==",
"license": "MIT"
},
"node_modules/lodash.groupby": {
"version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/lodash.groupby/-/lodash.groupby-4.6.0.tgz",
+ "integrity": "sha512-5dcWxm23+VAoz+awKmBaiBvzox8+RqMgFhi7UvX9DHZr2HdxHXM/Wrf8cfKpsW37RNrvtPn6hSwNqurSILbmJw==",
"dev": true,
"license": "MIT"
},
"node_modules/long": {
"version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz",
+ "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==",
"dev": true,
"license": "Apache-2.0"
},
"node_modules/lru-cache": {
"version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
"dev": true,
"license": "ISC",
"dependencies": {
@@ -6267,6 +8449,8 @@
},
"node_modules/magic-string": {
"version": "0.30.21",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
+ "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
"license": "MIT",
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.5.5"
@@ -6274,6 +8458,8 @@
},
"node_modules/math-intrinsics": {
"version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
+ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
"dev": true,
"license": "MIT",
"engines": {
@@ -6282,6 +8468,8 @@
},
"node_modules/mathjs": {
"version": "15.2.0",
+ "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-15.2.0.tgz",
+ "integrity": "sha512-UAQzSVob9rNLdGpqcFMYmSu9dkuLYy7Lr2hBEQS5SHQdknA9VppJz3cy2KkpMzTODunad6V6cNv+5kOLsePLow==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -6304,6 +8492,8 @@
},
"node_modules/mdast-util-to-string": {
"version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz",
+ "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==",
"license": "MIT",
"dependencies": {
"@types/mdast": "^4.0.0"
@@ -6315,11 +8505,15 @@
},
"node_modules/mdn-data": {
"version": "2.27.1",
+ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.27.1.tgz",
+ "integrity": "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==",
"dev": true,
"license": "CC0-1.0"
},
"node_modules/mdsvex": {
"version": "0.12.7",
+ "resolved": "https://registry.npmjs.org/mdsvex/-/mdsvex-0.12.7.tgz",
+ "integrity": "sha512-gx4bReLCUvq+MPErHXYeyX+TEq1hsS2KfiZtEOMNTcbibSouFy8AHc5h04KbGCl+g5tLuo4/lbgRVYRnc7bJZw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6336,11 +8530,15 @@
},
"node_modules/mdsvex/node_modules/@types/unist": {
"version": "2.0.11",
+ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz",
+ "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==",
"dev": true,
"license": "MIT"
},
"node_modules/meow": {
"version": "13.2.0",
+ "resolved": "https://registry.npmjs.org/meow/-/meow-13.2.0.tgz",
+ "integrity": "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -6352,6 +8550,8 @@
},
"node_modules/merge2": {
"version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -6360,6 +8560,8 @@
},
"node_modules/micromatch": {
"version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6372,6 +8574,8 @@
},
"node_modules/miniflare": {
"version": "4.20260611.0",
+ "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-4.20260611.0.tgz",
+ "integrity": "sha512-i+JwEo8vN96naz1WL3ntFgFyRluBDYL408zwhHKvR2jefJ464KsZ/gCmJAQ5k+oaWeb5Ug+s7yne5AyiAEswjg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6391,6 +8595,8 @@
},
"node_modules/miniflare/node_modules/undici": {
"version": "7.24.8",
+ "resolved": "https://registry.npmjs.org/undici/-/undici-7.24.8.tgz",
+ "integrity": "sha512-6KQ/+QxK49Z/p3HO6E5ZCZWNnCasyZLa5ExaVYyvPxUwKtbCPMKELJOqh7EqOle0t9cH/7d2TaaTRRa6Nhs4YQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -6399,11 +8605,15 @@
},
"node_modules/minimalistic-assert": {
"version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
+ "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==",
"dev": true,
"license": "ISC"
},
"node_modules/minimatch": {
"version": "10.2.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz",
+ "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
@@ -6418,6 +8628,8 @@
},
"node_modules/minipass": {
"version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz",
+ "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==",
"license": "BlueOak-1.0.0",
"engines": {
"node": ">=16 || 14 >=14.17"
@@ -6425,6 +8637,8 @@
},
"node_modules/mnemonist": {
"version": "0.38.3",
+ "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.3.tgz",
+ "integrity": "sha512-2K9QYubXx/NAjv4VLq1d1Ly8pWNC5L3BrixtdkyTegXWJIqY+zLNDhhX/A+ZwWt70tB1S8H4BE8FLYEFyNoOBw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6433,10 +8647,14 @@
},
"node_modules/moo": {
"version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/moo/-/moo-0.5.3.tgz",
+ "integrity": "sha512-m2fmM2dDm7GZQsY7KK2cme8agi+AAljILjQnof7p1ZMDe6dQ4bdnSMx0cPppudoeNv5hEFQirN6u+O4fDE0IWA==",
"license": "BSD-3-Clause"
},
"node_modules/mrmime": {
"version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz",
+ "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -6445,11 +8663,15 @@
},
"node_modules/ms": {
"version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"dev": true,
"license": "MIT"
},
"node_modules/mutation-server-protocol": {
"version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/mutation-server-protocol/-/mutation-server-protocol-0.4.1.tgz",
+ "integrity": "sha512-SBGK0j8hLDne7bktgThKI8kGvGTx3rY3LAeQTmOKZ5bVnL/7TorLMvcVF7dIPJCu5RNUWhkkuF53kurygYVt3g==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -6461,11 +8683,15 @@
},
"node_modules/mutation-testing-elements": {
"version": "3.7.3",
+ "resolved": "https://registry.npmjs.org/mutation-testing-elements/-/mutation-testing-elements-3.7.3.tgz",
+ "integrity": "sha512-SMeIPxngJpfjfNYctFpYQQtlBlZaVO0aoB3FKdwrI8Ee/2bkyUuCZzAOCLv1U9fnmfA37dPFq0Owduoxs2XgGQ==",
"dev": true,
"license": "Apache-2.0"
},
"node_modules/mutation-testing-metrics": {
"version": "3.7.3",
+ "resolved": "https://registry.npmjs.org/mutation-testing-metrics/-/mutation-testing-metrics-3.7.3.tgz",
+ "integrity": "sha512-B8QrP0ZomErzTPNlhrzKWPNBln+3afwBZPHv0Q7N8wZZTYxMptzb/Gdm3ExXVmioVYrtZAtsDs7W/T/b2AixOQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -6474,11 +8700,15 @@
},
"node_modules/mutation-testing-report-schema": {
"version": "3.7.3",
+ "resolved": "https://registry.npmjs.org/mutation-testing-report-schema/-/mutation-testing-report-schema-3.7.3.tgz",
+ "integrity": "sha512-BHm3MYq+ckO+t5CtlG8zpqxc75rdJCkxVlE+fGuGJM3F7tNCQ/OW2N+TQVHN3BHsYa84+BFc6g3AwDYkUsw2MA==",
"dev": true,
"license": "Apache-2.0"
},
"node_modules/mute-stream": {
"version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-3.0.0.tgz",
+ "integrity": "sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw==",
"dev": true,
"license": "ISC",
"engines": {
@@ -6487,6 +8717,8 @@
},
"node_modules/nanoid": {
"version": "3.3.12",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz",
+ "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==",
"dev": true,
"funding": [
{
@@ -6504,6 +8736,8 @@
},
"node_modules/nearley": {
"version": "2.20.1",
+ "resolved": "https://registry.npmjs.org/nearley/-/nearley-2.20.1.tgz",
+ "integrity": "sha512-+Mc8UaAebFzgV+KpI5n7DasuuQCHA89dmwm7JXw3TV43ukfNQ9DnBH3Mdb2g/I4Fdxc26pwimBWvjIw0UAILSQ==",
"license": "MIT",
"dependencies": {
"commander": "^2.19.0",
@@ -6524,10 +8758,14 @@
},
"node_modules/nearley/node_modules/commander": {
"version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
"license": "MIT"
},
"node_modules/nise": {
"version": "6.1.5",
+ "resolved": "https://registry.npmjs.org/nise/-/nise-6.1.5.tgz",
+ "integrity": "sha512-SnRDPDBjxZZoU2n0+gzzLtSvo1OZo7j6jnbXsoh3AFxEGhaFU7ZF0TmefuKERq79wxR2U+MPn7ArW+Tl+clC3A==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
@@ -6539,6 +8777,8 @@
},
"node_modules/nise/node_modules/@sinonjs/fake-timers": {
"version": "15.4.0",
+ "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.4.0.tgz",
+ "integrity": "sha512-DsG+8/LscQIQg68J6Ef3dv10u6nVyetYn923s3/sus5eaGfTo1of5WMZSLf0UJc9KDuKPilPH0UDJCjvNbDNCA==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
@@ -6547,6 +8787,8 @@
},
"node_modules/node-fetch": {
"version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
+ "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6566,6 +8808,8 @@
},
"node_modules/node-releases": {
"version": "2.0.47",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.47.tgz",
+ "integrity": "sha512-Uzmd6LXpouKo8EUK68IjH4+E01w/hXyV3R3g/geCJo+rXLNfh1xucB+LOzYEOQPSiUK3h/xZf0cQGcSsmyL2Og==",
"dev": true,
"license": "MIT",
"engines": {
@@ -6574,6 +8818,8 @@
},
"node_modules/nopt": {
"version": "7.2.1",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.1.tgz",
+ "integrity": "sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==",
"license": "ISC",
"dependencies": {
"abbrev": "^2.0.0"
@@ -6587,6 +8833,8 @@
},
"node_modules/npm-run-path": {
"version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-6.0.0.tgz",
+ "integrity": "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6602,6 +8850,8 @@
},
"node_modules/npm-run-path/node_modules/path-key": {
"version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz",
+ "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -6613,6 +8863,8 @@
},
"node_modules/nth-check": {
"version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
+ "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
@@ -6624,6 +8876,8 @@
},
"node_modules/object-hash": {
"version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
+ "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -6632,6 +8886,8 @@
},
"node_modules/object-inspect": {
"version": "1.13.4",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
+ "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
"dev": true,
"license": "MIT",
"engines": {
@@ -6643,11 +8899,15 @@
},
"node_modules/obliterator": {
"version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-1.6.1.tgz",
+ "integrity": "sha512-9WXswnqINnnhOG/5SLimUlzuU1hFJUc8zkwyD59Sd+dPOMf05PmnYG/d6Q7HZ+KmgkZJa1PxRso6QdM3sTNHig==",
"dev": true,
"license": "MIT"
},
"node_modules/obug": {
"version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.3.tgz",
+ "integrity": "sha512-9miFgM2OFba7hB+pRgvtV84pYTBaoTHohvmIgiRt6dRIzbwEOIaNaP+dIlGs2fNFoB0SeISs0Jz5WFVRid6Xyg==",
"dev": true,
"funding": [
"https://github.com/sponsors/sxzz",
@@ -6660,6 +8920,8 @@
},
"node_modules/once": {
"version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
"dev": true,
"license": "ISC",
"dependencies": {
@@ -6668,6 +8930,8 @@
},
"node_modules/p-limit": {
"version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6682,6 +8946,8 @@
},
"node_modules/p-locate": {
"version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+ "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6693,6 +8959,8 @@
},
"node_modules/p-try": {
"version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -6701,10 +8969,14 @@
},
"node_modules/package-json-from-dist": {
"version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
+ "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
"license": "BlueOak-1.0.0"
},
"node_modules/parent-module": {
"version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6716,6 +8988,8 @@
},
"node_modules/parse-json": {
"version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
+ "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6733,6 +9007,8 @@
},
"node_modules/parse-ms": {
"version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-4.0.0.tgz",
+ "integrity": "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -6744,6 +9020,8 @@
},
"node_modules/parse5": {
"version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz",
+ "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6755,6 +9033,8 @@
},
"node_modules/parse5-htmlparser2-tree-adapter": {
"version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz",
+ "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6767,6 +9047,8 @@
},
"node_modules/parse5-parser-stream": {
"version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz",
+ "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6778,6 +9060,8 @@
},
"node_modules/parse5/node_modules/entities": {
"version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz",
+ "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==",
"dev": true,
"license": "BSD-2-Clause",
"engines": {
@@ -6789,6 +9073,8 @@
},
"node_modules/path-exists": {
"version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+ "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -6797,6 +9083,8 @@
},
"node_modules/path-expression-matcher": {
"version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.5.0.tgz",
+ "integrity": "sha512-cbrerZV+6rvdQrrD+iGMcZFEiiSrbv9Tfdkvnusy6y0x0GKBXREFg/Y65GhIfm0tnLntThhzCnfKwp1WRjeCyQ==",
"dev": true,
"funding": [
{
@@ -6811,6 +9099,8 @@
},
"node_modules/path-is-absolute": {
"version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -6819,6 +9109,8 @@
},
"node_modules/path-key": {
"version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
"license": "MIT",
"engines": {
"node": ">=8"
@@ -6826,6 +9118,8 @@
},
"node_modules/path-scurry": {
"version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
+ "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
"license": "BlueOak-1.0.0",
"dependencies": {
"lru-cache": "^10.2.0",
@@ -6840,10 +9134,14 @@
},
"node_modules/path-scurry/node_modules/lru-cache": {
"version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
"license": "ISC"
},
"node_modules/path-to-regexp": {
"version": "8.4.2",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz",
+ "integrity": "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==",
"dev": true,
"license": "MIT",
"funding": {
@@ -6853,6 +9151,8 @@
},
"node_modules/path-type": {
"version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -6861,16 +9161,22 @@
},
"node_modules/pathe": {
"version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
+ "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
"dev": true,
"license": "MIT"
},
"node_modules/picocolors": {
"version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
"dev": true,
"license": "ISC"
},
"node_modules/picomatch": {
"version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz",
+ "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -6882,6 +9188,8 @@
},
"node_modules/postcss": {
"version": "8.5.15",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz",
+ "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==",
"dev": true,
"funding": [
{
@@ -6909,6 +9217,8 @@
},
"node_modules/pretty": {
"version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/pretty/-/pretty-2.0.0.tgz",
+ "integrity": "sha512-G9xUchgTEiNpormdYBl+Pha50gOUovT18IvAe7EYMZ1/f9W/WWMPRn+xI68yXNMUk3QXHDwo/1wV/4NejVNe1w==",
"license": "MIT",
"dependencies": {
"condense-newlines": "^0.2.1",
@@ -6921,6 +9231,8 @@
},
"node_modules/pretty-ms": {
"version": "9.3.0",
+ "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.3.0.tgz",
+ "integrity": "sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6935,11 +9247,15 @@
},
"node_modules/prism-svelte": {
"version": "0.4.7",
+ "resolved": "https://registry.npmjs.org/prism-svelte/-/prism-svelte-0.4.7.tgz",
+ "integrity": "sha512-yABh19CYbM24V7aS7TuPYRNMqthxwbvx6FF/Rw920YbyBWO3tnyPIqRMgHuSVsLmuHkkBS1Akyof463FVdkeDQ==",
"dev": true,
"license": "MIT"
},
"node_modules/prismjs": {
"version": "1.30.0",
+ "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz",
+ "integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==",
"license": "MIT",
"engines": {
"node": ">=6"
@@ -6947,6 +9263,8 @@
},
"node_modules/progress": {
"version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
+ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -6955,10 +9273,14 @@
},
"node_modules/proto-list": {
"version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
+ "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==",
"license": "ISC"
},
"node_modules/protobufjs": {
"version": "8.6.3",
+ "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-8.6.3.tgz",
+ "integrity": "sha512-alQyzT0j401LGBtwsqu6uprjR6pfNH1UJf9N6GBFMjIcd+HzTe0/HrjAbFCqun+zvnfLarrxAtMM2xvZ+kFZ5A==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
@@ -6970,6 +9292,8 @@
},
"node_modules/pure-rand": {
"version": "8.4.0",
+ "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-8.4.0.tgz",
+ "integrity": "sha512-IoM8YF/jY0hiugFo/wOWqfmarlE6J0wc6fDK1PhftMk7MGhVZl88sZimmqBBFomLOCSmcCCpsfj7wXASCpvK9A==",
"dev": true,
"funding": [
{
@@ -6985,6 +9309,8 @@
},
"node_modules/qs": {
"version": "6.15.2",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.2.tgz",
+ "integrity": "sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
@@ -6999,6 +9325,8 @@
},
"node_modules/queue-microtask": {
"version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
"dev": true,
"funding": [
{
@@ -7018,10 +9346,14 @@
},
"node_modules/railroad-diagrams": {
"version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz",
+ "integrity": "sha512-cz93DjNeLY0idrCNOH6PviZGRN9GJhsdm9hpn1YCS879fj4W+x5IFJhhkRZcwVgMmFF7R82UA/7Oh+R8lLZg6A==",
"license": "CC0-1.0"
},
"node_modules/randexp": {
"version": "0.4.6",
+ "resolved": "https://registry.npmjs.org/randexp/-/randexp-0.4.6.tgz",
+ "integrity": "sha512-80WNmd9DA0tmZrw9qQa62GPPWfuXJknrmVmLcxvq4uZBdYqb1wYoKTmnlGUchvVWe0XiLupYkBoXVOxz3C8DYQ==",
"license": "MIT",
"dependencies": {
"discontinuous-range": "1.0.0",
@@ -7033,6 +9365,8 @@
},
"node_modules/readable-stream": {
"version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -7046,6 +9380,8 @@
},
"node_modules/redos-detector": {
"version": "6.1.4",
+ "resolved": "https://registry.npmjs.org/redos-detector/-/redos-detector-6.1.4.tgz",
+ "integrity": "sha512-lPlka1rEH6kK42gtgokvvxMmpAvyc28DcRjQbGxeP5RJsJWgAduBOdGedVCDPdSyCr4ay/JDxq3nGYsJZyt8tA==",
"license": "MIT",
"dependencies": {
"regjsparser": "0.13.0"
@@ -7059,6 +9395,8 @@
},
"node_modules/regexparam": {
"version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/regexparam/-/regexparam-3.0.0.tgz",
+ "integrity": "sha512-RSYAtP31mvYLkAHrOlh25pCNQ5hWnT106VukGaaFfuJrZFkGRX5GhUAdPqpSDXxOhA2c4akmRuplv1mRqnBn6Q==",
"dev": true,
"license": "MIT",
"engines": {
@@ -7067,6 +9405,8 @@
},
"node_modules/regjsparser": {
"version": "0.13.0",
+ "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.13.0.tgz",
+ "integrity": "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q==",
"license": "BSD-2-Clause",
"dependencies": {
"jsesc": "~3.1.0"
@@ -7077,6 +9417,8 @@
},
"node_modules/require-directory": {
"version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
"dev": true,
"license": "MIT",
"engines": {
@@ -7085,6 +9427,8 @@
},
"node_modules/require-from-string": {
"version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
@@ -7092,11 +9436,15 @@
},
"node_modules/require-main-filename": {
"version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
+ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
"dev": true,
"license": "ISC"
},
"node_modules/resolve-from": {
"version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -7105,6 +9453,8 @@
},
"node_modules/ret": {
"version": "0.1.15",
+ "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
+ "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
"license": "MIT",
"engines": {
"node": ">=0.12"
@@ -7112,6 +9462,8 @@
},
"node_modules/reusify": {
"version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
+ "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -7121,6 +9473,8 @@
},
"node_modules/rolldown": {
"version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.3.tgz",
+ "integrity": "sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -7153,6 +9507,8 @@
},
"node_modules/run-parallel": {
"version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
"dev": true,
"funding": [
{
@@ -7175,6 +9531,8 @@
},
"node_modules/rxjs": {
"version": "7.8.2",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz",
+ "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -7183,6 +9541,8 @@
},
"node_modules/safe-buffer": {
"version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
"dev": true,
"funding": [
{
@@ -7202,10 +9562,14 @@
},
"node_modules/safer-buffer": {
"version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
"license": "MIT"
},
"node_modules/sast-json-schema": {
"version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/sast-json-schema/-/sast-json-schema-0.4.1.tgz",
+ "integrity": "sha512-GnOPf8rCTfysRtOzCJPoBZu8xKnY4LZ24jxCmcxsLUkmOTpK/DrbrJ97Xio4xkIH6USdzEZ5ZSdpTX8Gj03EuQ==",
"license": "MIT",
"workspaces": [
".github"
@@ -7227,6 +9591,8 @@
},
"node_modules/sax": {
"version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/sax/-/sax-1.6.0.tgz",
+ "integrity": "sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==",
"dev": true,
"license": "BlueOak-1.0.0",
"engines": {
@@ -7235,11 +9601,15 @@
},
"node_modules/seedrandom": {
"version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz",
+ "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==",
"dev": true,
"license": "MIT"
},
"node_modules/semver": {
"version": "7.8.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.4.tgz",
+ "integrity": "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==",
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
@@ -7250,16 +9620,22 @@
},
"node_modules/set-blocking": {
"version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+ "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==",
"dev": true,
"license": "ISC"
},
"node_modules/set-cookie-parser": {
"version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-3.1.0.tgz",
+ "integrity": "sha512-kjnC1DXBHcxaOaOXBHBeRtltsDG2nUiUni+jP92M9gYdW12rsmx92UsfpH7o5tDRs7I1ZZPSQJQGv3UaRfCiuw==",
"dev": true,
"license": "MIT"
},
"node_modules/sharp": {
"version": "0.34.5",
+ "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz",
+ "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==",
"dev": true,
"hasInstallScript": true,
"license": "Apache-2.0",
@@ -7303,6 +9679,8 @@
},
"node_modules/shebang-command": {
"version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
"license": "MIT",
"dependencies": {
"shebang-regex": "^3.0.0"
@@ -7313,6 +9691,8 @@
},
"node_modules/shebang-regex": {
"version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
"license": "MIT",
"engines": {
"node": ">=8"
@@ -7320,6 +9700,8 @@
},
"node_modules/side-channel": {
"version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz",
+ "integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -7338,6 +9720,8 @@
},
"node_modules/side-channel-list": {
"version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz",
+ "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -7353,6 +9737,8 @@
},
"node_modules/side-channel-map": {
"version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
+ "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -7370,6 +9756,8 @@
},
"node_modules/side-channel-weakmap": {
"version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
+ "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -7388,6 +9776,8 @@
},
"node_modules/signal-exit": {
"version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
+ "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
"license": "ISC",
"engines": {
"node": ">=14"
@@ -7398,6 +9788,8 @@
},
"node_modules/sinon": {
"version": "18.0.1",
+ "resolved": "https://registry.npmjs.org/sinon/-/sinon-18.0.1.tgz",
+ "integrity": "sha512-a2N2TDY1uGviajJ6r4D1CyRAkzE9NNVlYOV1wX5xQDuAk0ONgzgRl0EjCQuRCPxOwp13ghsMwt9Gdldujs39qw==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
@@ -7415,6 +9807,8 @@
},
"node_modules/sirv": {
"version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.2.tgz",
+ "integrity": "sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -7428,6 +9822,8 @@
},
"node_modules/slash": {
"version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
"dev": true,
"license": "MIT",
"engines": {
@@ -7436,6 +9832,8 @@
},
"node_modules/smtp-address-parser": {
"version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/smtp-address-parser/-/smtp-address-parser-1.1.0.tgz",
+ "integrity": "sha512-Gz11jbNU0plrReU9Sj7fmshSBxxJ9ShdD2q4ktHIHo/rpTH6lFyQoYHYKINPJtPe8aHFnsbtW46Ls0tCCBsIZg==",
"license": "MIT",
"dependencies": {
"nearley": "^2.20.1"
@@ -7446,6 +9844,8 @@
},
"node_modules/source-map": {
"version": "0.7.6",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz",
+ "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==",
"dev": true,
"license": "BSD-3-Clause",
"engines": {
@@ -7454,6 +9854,8 @@
},
"node_modules/source-map-js": {
"version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
"dev": true,
"license": "BSD-3-Clause",
"engines": {
@@ -7462,11 +9864,15 @@
},
"node_modules/sprintf-js": {
"version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
"dev": true,
"license": "BSD-3-Clause"
},
"node_modules/stream-browserify": {
"version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz",
+ "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -7476,6 +9882,8 @@
},
"node_modules/string_decoder": {
"version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -7484,6 +9892,8 @@
},
"node_modules/string-width": {
"version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz",
+ "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -7501,6 +9911,8 @@
"node_modules/string-width-cjs": {
"name": "string-width",
"version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"license": "MIT",
"dependencies": {
"emoji-regex": "^8.0.0",
@@ -7513,6 +9925,8 @@
},
"node_modules/string-width-cjs/node_modules/ansi-regex": {
"version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
"license": "MIT",
"engines": {
"node": ">=8"
@@ -7520,10 +9934,14 @@
},
"node_modules/string-width-cjs/node_modules/emoji-regex": {
"version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"license": "MIT"
},
"node_modules/string-width-cjs/node_modules/strip-ansi": {
"version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"license": "MIT",
"dependencies": {
"ansi-regex": "^5.0.1"
@@ -7534,6 +9952,8 @@
},
"node_modules/strip-ansi": {
"version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz",
+ "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==",
"license": "MIT",
"dependencies": {
"ansi-regex": "^6.2.2"
@@ -7548,6 +9968,8 @@
"node_modules/strip-ansi-cjs": {
"name": "strip-ansi",
"version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"license": "MIT",
"dependencies": {
"ansi-regex": "^5.0.1"
@@ -7558,6 +9980,8 @@
},
"node_modules/strip-ansi-cjs/node_modules/ansi-regex": {
"version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
"license": "MIT",
"engines": {
"node": ">=8"
@@ -7565,6 +9989,8 @@
},
"node_modules/strip-final-newline": {
"version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-4.0.0.tgz",
+ "integrity": "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -7576,6 +10002,8 @@
},
"node_modules/strnum": {
"version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.4.0.tgz",
+ "integrity": "sha512-sHrVyWWdq28RbhjuJdZsA1SnGRJV6NiXbk6AXBxDOsgAcA+lmpUZCYjOdLBxkXMwis6RRe7dlZt4VlIWFVzkmg==",
"dev": true,
"funding": [
{
@@ -7590,6 +10018,8 @@
},
"node_modules/supports-color": {
"version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"license": "MIT",
"dependencies": {
"has-flag": "^4.0.0"
@@ -7600,6 +10030,8 @@
},
"node_modules/svelte": {
"version": "5.56.3",
+ "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.56.3.tgz",
+ "integrity": "sha512-w7JvrM5IFl5cmfbY0TLik9o7mjRUJmRMhOR51tBPu708Gr/MjbGs7VnJnr/B0CaXeI4vtnOh7RKxDr0cwhMdDA==",
"license": "MIT",
"dependencies": {
"@jridgewell/remapping": "^2.3.4",
@@ -7625,6 +10057,8 @@
},
"node_modules/svgo": {
"version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/svgo/-/svgo-4.0.1.tgz",
+ "integrity": "sha512-XDpWUOPC6FEibaLzjfe0ucaV0YrOjYotGJO1WpF0Zd+n6ZGEQUsSugaoLq9QkEZtAfQIxT42UChcssDVPP3+/w==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -7649,6 +10083,8 @@
},
"node_modules/svgo/node_modules/commander": {
"version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz",
+ "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -7657,6 +10093,8 @@
},
"node_modules/table-layout": {
"version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-4.1.1.tgz",
+ "integrity": "sha512-iK5/YhZxq5GO5z8wb0bY1317uDF3Zjpha0QFFLA8/trAoiLbQD0HUbMesEaxyzUgDxi2QlcbM8IvqOlEjgoXBA==",
"license": "MIT",
"dependencies": {
"array-back": "^6.2.2",
@@ -7668,11 +10106,15 @@
},
"node_modules/tiny-emitter": {
"version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz",
+ "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==",
"dev": true,
"license": "MIT"
},
"node_modules/tinybench": {
"version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-6.0.2.tgz",
+ "integrity": "sha512-FlHoQpcFvCzeXK5kVPvV7IVgW/hs/B36QWTz876iSdeJguBDfdTSRQmYmaHX+fQNt4hp+gEFB2XXw+8hT4/y8A==",
"dev": true,
"license": "MIT",
"engines": {
@@ -7681,6 +10123,8 @@
},
"node_modules/tinyexec": {
"version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.2.4.tgz",
+ "integrity": "sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -7689,6 +10133,8 @@
},
"node_modules/tinyglobby": {
"version": "0.2.17",
+ "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz",
+ "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -7704,6 +10150,8 @@
},
"node_modules/tinyglobby/node_modules/fdir": {
"version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
+ "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -7720,6 +10168,8 @@
},
"node_modules/tinyglobby/node_modules/picomatch": {
"version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
+ "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
"dev": true,
"license": "MIT",
"engines": {
@@ -7731,10 +10181,14 @@
},
"node_modules/tinykeys": {
"version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/tinykeys/-/tinykeys-3.0.0.tgz",
+ "integrity": "sha512-nazawuGv5zx6MuDfDY0rmfXjuOGhD5XU2z0GLURQ1nzl0RUe9OuCJq+0u8xxJZINHe+mr7nw8PWYYZ9WhMFujw==",
"license": "MIT"
},
"node_modules/to-regex-range": {
"version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -7746,6 +10200,8 @@
},
"node_modules/totalist": {
"version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz",
+ "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -7754,11 +10210,15 @@
},
"node_modules/tr46": {
"version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
"dev": true,
"license": "MIT"
},
"node_modules/tree-kill": {
"version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz",
+ "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==",
"dev": true,
"license": "MIT",
"bin": {
@@ -7767,10 +10227,14 @@
},
"node_modules/tslib": {
"version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
"license": "0BSD"
},
"node_modules/tstyche": {
"version": "7.2.1",
+ "resolved": "https://registry.npmjs.org/tstyche/-/tstyche-7.2.1.tgz",
+ "integrity": "sha512-XMaaGk8Mrv+LMULdaK2H8jix1dLvKAi9lO/HTZZuK/tV0H3pD/9nCuCTIsHotpZ3VScOzv8ZGT2/6UvdSxzHgw==",
"dev": true,
"license": "MIT",
"bin": {
@@ -7793,6 +10257,8 @@
},
"node_modules/tunnel": {
"version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
+ "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -7801,6 +10267,8 @@
},
"node_modules/type-detect": {
"version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
+ "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
"dev": true,
"license": "MIT",
"engines": {
@@ -7809,6 +10277,8 @@
},
"node_modules/typed-function": {
"version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/typed-function/-/typed-function-4.2.2.tgz",
+ "integrity": "sha512-VwaXim9Gp1bngi/q3do8hgttYn2uC3MoT/gfuMWylnj1IeZBUAyPddHZlo1K05BDoj8DYPpMdiHqH1dDYdJf2A==",
"dev": true,
"license": "MIT",
"engines": {
@@ -7817,6 +10287,8 @@
},
"node_modules/typed-inject": {
"version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/typed-inject/-/typed-inject-5.0.0.tgz",
+ "integrity": "sha512-0Ql2ORqBORLMdAW89TQKZsb1PQkFGImFfVmncXWe7a+AA3+7dh7Se9exxZowH4kbnlvKEFkMxUYdHUpjYWFJaA==",
"dev": true,
"license": "Apache-2.0",
"engines": {
@@ -7825,6 +10297,8 @@
},
"node_modules/typed-rest-client": {
"version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-2.3.1.tgz",
+ "integrity": "sha512-k4kX5Up6qA68D0Cby2AK+6+vM5k3qTxe+/3FqhnHRExjY5cfbOnzjQZbP/LXleF8hVoDvDqxlgk9KK83HoBZlQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -7840,6 +10314,8 @@
},
"node_modules/typescript": {
"version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz",
+ "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==",
"dev": true,
"license": "Apache-2.0",
"peer": true,
@@ -7853,6 +10329,8 @@
},
"node_modules/typical": {
"version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/typical/-/typical-7.3.0.tgz",
+ "integrity": "sha512-ya4mg/30vm+DOWfBg4YK3j2WD6TWtRkCbasOJr40CseYENzCUby/7rIvXA99JGsQHeNxLbnXdyLLxKSv3tauFw==",
"license": "MIT",
"engines": {
"node": ">=12.17"
@@ -7860,11 +10338,15 @@
},
"node_modules/underscore": {
"version": "1.13.8",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.8.tgz",
+ "integrity": "sha512-DXtD3ZtEQzc7M8m4cXotyHR+FAS18C64asBYY5vqZexfYryNNnDc02W4hKg3rdQuqOYas1jkseX0+nZXjTXnvQ==",
"dev": true,
"license": "MIT"
},
"node_modules/undici": {
"version": "8.4.1",
+ "resolved": "https://registry.npmjs.org/undici/-/undici-8.4.1.tgz",
+ "integrity": "sha512-RNHlB4fxZK0IrkhBsxhlbx7s8kFWwr7rzzOqj5nvZugw3ig3RsB7KW3zVlV0eu8POl+rx5d1hmL7rRg0z1owow==",
"dev": true,
"license": "MIT",
"engines": {
@@ -7873,11 +10355,15 @@
},
"node_modules/undici-types": {
"version": "7.24.6",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz",
+ "integrity": "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==",
"dev": true,
"license": "MIT"
},
"node_modules/unenv": {
"version": "2.0.0-rc.24",
+ "resolved": "https://registry.npmjs.org/unenv/-/unenv-2.0.0-rc.24.tgz",
+ "integrity": "sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -7886,6 +10372,8 @@
},
"node_modules/unicorn-magic": {
"version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz",
+ "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -7897,6 +10385,8 @@
},
"node_modules/unist-util-is": {
"version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz",
+ "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==",
"dev": true,
"license": "MIT",
"funding": {
@@ -7906,6 +10396,8 @@
},
"node_modules/unist-util-stringify-position": {
"version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz",
+ "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -7918,11 +10410,15 @@
},
"node_modules/unist-util-stringify-position/node_modules/@types/unist": {
"version": "2.0.11",
+ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz",
+ "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==",
"dev": true,
"license": "MIT"
},
"node_modules/unist-util-visit": {
"version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz",
+ "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -7937,6 +10433,8 @@
},
"node_modules/unist-util-visit-parents": {
"version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz",
+ "integrity": "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -7950,16 +10448,22 @@
},
"node_modules/unist-util-visit-parents/node_modules/@types/unist": {
"version": "2.0.11",
+ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz",
+ "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==",
"dev": true,
"license": "MIT"
},
"node_modules/unist-util-visit/node_modules/@types/unist": {
"version": "2.0.11",
+ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz",
+ "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==",
"dev": true,
"license": "MIT"
},
"node_modules/universalify": {
"version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
+ "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -7968,6 +10472,8 @@
},
"node_modules/update-browserslist-db": {
"version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz",
+ "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==",
"dev": true,
"funding": [
{
@@ -7997,15 +10503,21 @@
},
"node_modules/uri-js-replace": {
"version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/uri-js-replace/-/uri-js-replace-1.0.1.tgz",
+ "integrity": "sha512-W+C9NWNLFOoBI2QWDp4UT9pv65r2w5Cx+3sTYFvtMdDBxkKt1syCqsUdSFAChbEe1uK5TfS04wt/nGwmaeIQ0g==",
"license": "MIT"
},
"node_modules/util-deprecate": {
"version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
"dev": true,
"license": "MIT"
},
"node_modules/uuid": {
"version": "14.0.0",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-14.0.0.tgz",
+ "integrity": "sha512-Qo+uWgilfSmAhXCMav1uYFynlQO7fMFiMVZsQqZRMIXp0O7rR7qjkj+cPvBHLgBqi960QCoo/PH2/6ZtVqKvrg==",
"funding": [
"https://github.com/sponsors/broofa",
"https://github.com/sponsors/ctavan"
@@ -8017,6 +10529,8 @@
},
"node_modules/vfile-message": {
"version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz",
+ "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -8030,11 +10544,15 @@
},
"node_modules/vfile-message/node_modules/@types/unist": {
"version": "2.0.11",
+ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz",
+ "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==",
"dev": true,
"license": "MIT"
},
"node_modules/vite": {
"version": "8.0.16",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.16.tgz",
+ "integrity": "sha512-h9bXPmJichP5fLmVQo3PyaGSDE2n3aPuomeAlVRm0JLmt4rY6zmPKd59HYI4LNW8oTK7tlTsuC7l/m7awx9Jcw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -8111,6 +10629,8 @@
},
"node_modules/vite-plugin-llms": {
"version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/vite-plugin-llms/-/vite-plugin-llms-1.0.2.tgz",
+ "integrity": "sha512-MLO/9nUSpwCKkjip88cseLihIxhOpHc3GzOrNfbUPS+xp7hbBfPF0LgauyYfTJfPT/GcCPVEqrsy3MQ9JUv+MQ==",
"dev": true,
"license": "MIT",
"peerDependencies": {
@@ -8119,6 +10639,8 @@
},
"node_modules/vite-plugin-mkcert": {
"version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/vite-plugin-mkcert/-/vite-plugin-mkcert-2.1.0.tgz",
+ "integrity": "sha512-UQS5iyknruwCsvqDPsKRyHIVSVfv/iGdRPmUPaM1JRwNJo8wo/MubzJ66ckWwOLxFU4wW90oZq9GviV87nRHsg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -8135,6 +10657,8 @@
},
"node_modules/vite-plugin-mkcert/node_modules/supports-color": {
"version": "10.2.2",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-10.2.2.tgz",
+ "integrity": "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==",
"dev": true,
"license": "MIT",
"engines": {
@@ -8146,10 +10670,14 @@
},
"node_modules/vite-plugin-sitemap": {
"version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/vite-plugin-sitemap/-/vite-plugin-sitemap-0.8.2.tgz",
+ "integrity": "sha512-bqIw6NVOXg6je81lzX8Lm0vjf8/QSAp8di8fYQzZ3ZdVicOm8+6idBGALJiy1R1FiXNIK8rgORO6HBqXyHW+iQ==",
"dev": true
},
"node_modules/vite-plugin-sri": {
"version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/vite-plugin-sri/-/vite-plugin-sri-0.0.2.tgz",
+ "integrity": "sha512-oTpYWvS9xmwee3kK39cr8p2KbQ+/HzOG0bxo0dzMogJ4lR11favOzrapwb2eASVt5rX3LEzG25bEqoSY4CUniA==",
"dev": true,
"license": "ISC",
"dependencies": {
@@ -8159,6 +10687,8 @@
},
"node_modules/vite/node_modules/picomatch": {
"version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
+ "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
"dev": true,
"license": "MIT",
"engines": {
@@ -8170,6 +10700,8 @@
},
"node_modules/vitefu": {
"version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-1.1.3.tgz",
+ "integrity": "sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg==",
"dev": true,
"license": "MIT",
"workspaces": [
@@ -8188,16 +10720,23 @@
},
"node_modules/weapon-regex": {
"version": "1.3.6",
+ "resolved": "https://registry.npmjs.org/weapon-regex/-/weapon-regex-1.3.6.tgz",
+ "integrity": "sha512-wsf1m1jmMrso5nhwVFJJHSubEBf3+pereGd7+nBKtYJ18KoB/PWJOHS3WRkwS04VrOU0iJr2bZU+l1QaTJ+9nA==",
"dev": true,
"license": "Apache-2.0"
},
"node_modules/webidl-conversions": {
"version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
"dev": true,
"license": "BSD-2-Clause"
},
"node_modules/whatwg-encoding": {
"version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz",
+ "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==",
+ "deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -8209,6 +10748,8 @@
},
"node_modules/whatwg-encoding/node_modules/iconv-lite": {
"version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -8220,6 +10761,8 @@
},
"node_modules/whatwg-mimetype": {
"version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz",
+ "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -8228,6 +10771,8 @@
},
"node_modules/whatwg-url": {
"version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+ "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -8237,6 +10782,8 @@
},
"node_modules/which": {
"version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"license": "ISC",
"dependencies": {
"isexe": "^2.0.0"
@@ -8250,11 +10797,15 @@
},
"node_modules/which-module": {
"version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz",
+ "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==",
"dev": true,
"license": "ISC"
},
"node_modules/wordwrapjs": {
"version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-5.1.1.tgz",
+ "integrity": "sha512-0yweIbkINJodk27gX9LBGMzyQdBDan3s/dEAiwBOj+Mf0PPyWL6/rikalkv8EeD0E8jm4o5RXEOrFTP3NXbhJg==",
"license": "MIT",
"engines": {
"node": ">=12.17"
@@ -8262,6 +10813,8 @@
},
"node_modules/workerd": {
"version": "1.20260611.1",
+ "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20260611.1.tgz",
+ "integrity": "sha512-CS/640T7pIJ2HYX6x2DwKFGbcSckAWN3tgcdq+ptB6SaqjWUhlzIgA/YhPuwIU+/NnMnGpqOFX/hC18Oyge63w==",
"dev": true,
"hasInstallScript": true,
"license": "Apache-2.0",
@@ -8281,6 +10834,8 @@
},
"node_modules/worktop": {
"version": "0.8.0-next.18",
+ "resolved": "https://registry.npmjs.org/worktop/-/worktop-0.8.0-next.18.tgz",
+ "integrity": "sha512-+TvsA6VAVoMC3XDKR5MoC/qlLqDixEfOBysDEKnPIPou/NvoPWCAuXHXMsswwlvmEuvX56lQjvELLyLuzTKvRw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -8293,6 +10848,8 @@
},
"node_modules/wrangler": {
"version": "4.100.0",
+ "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-4.100.0.tgz",
+ "integrity": "sha512-dSQO7DO+mD6XDzkVWIWBoGLO3yw+lacWSc/KhFvd7pgfpth+kX98qb5SGRHZN8ACCDhhfwzDLXwB6qHsIHhfBg==",
"dev": true,
"license": "MIT OR Apache-2.0",
"dependencies": {
@@ -8395,6 +10952,8 @@
},
"node_modules/wrangler/node_modules/@esbuild/darwin-arm64": {
"version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz",
+ "integrity": "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==",
"cpu": [
"arm64"
],
@@ -8767,6 +11326,8 @@
},
"node_modules/wrangler/node_modules/esbuild": {
"version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz",
+ "integrity": "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
@@ -8807,11 +11368,15 @@
},
"node_modules/wrangler/node_modules/path-to-regexp": {
"version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz",
+ "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==",
"dev": true,
"license": "MIT"
},
"node_modules/wrap-ansi": {
"version": "9.0.2",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz",
+ "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -8829,6 +11394,8 @@
"node_modules/wrap-ansi-cjs": {
"name": "wrap-ansi",
"version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
"license": "MIT",
"dependencies": {
"ansi-styles": "^4.0.0",
@@ -8844,6 +11411,8 @@
},
"node_modules/wrap-ansi-cjs/node_modules/ansi-regex": {
"version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
"license": "MIT",
"engines": {
"node": ">=8"
@@ -8851,6 +11420,8 @@
},
"node_modules/wrap-ansi-cjs/node_modules/ansi-styles": {
"version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"license": "MIT",
"dependencies": {
"color-convert": "^2.0.1"
@@ -8864,6 +11435,8 @@
},
"node_modules/wrap-ansi-cjs/node_modules/color-convert": {
"version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"license": "MIT",
"dependencies": {
"color-name": "~1.1.4"
@@ -8874,14 +11447,20 @@
},
"node_modules/wrap-ansi-cjs/node_modules/color-name": {
"version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"license": "MIT"
},
"node_modules/wrap-ansi-cjs/node_modules/emoji-regex": {
"version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"license": "MIT"
},
"node_modules/wrap-ansi-cjs/node_modules/string-width": {
"version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"license": "MIT",
"dependencies": {
"emoji-regex": "^8.0.0",
@@ -8894,6 +11473,8 @@
},
"node_modules/wrap-ansi-cjs/node_modules/strip-ansi": {
"version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"license": "MIT",
"dependencies": {
"ansi-regex": "^5.0.1"
@@ -8904,11 +11485,15 @@
},
"node_modules/wrappy": {
"version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
"dev": true,
"license": "ISC"
},
"node_modules/ws": {
"version": "8.20.1",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.1.tgz",
+ "integrity": "sha512-It4dO0K5v//JtTXuPkfEOaI3uUN87iYPnqo/ZzqCoG3g8uhA66QUMs/SrM0YK7/NAu+r4LMh/9dq2A7k+rHs+w==",
"dev": true,
"license": "MIT",
"engines": {
@@ -8929,6 +11514,8 @@
},
"node_modules/xml-naming": {
"version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/xml-naming/-/xml-naming-0.1.0.tgz",
+ "integrity": "sha512-k8KO9hrMyNk6tUWqUfkTEZbezRRpONVOzUTnc97VnCvyj6Tf9lyUR9EDAIeiVLv56jsMcoXEwjW8Kv5yPY52lw==",
"dev": true,
"funding": [
{
@@ -8943,6 +11530,8 @@
},
"node_modules/y18n": {
"version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
"dev": true,
"license": "ISC",
"engines": {
@@ -8951,11 +11540,15 @@
},
"node_modules/yallist": {
"version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
"dev": true,
"license": "ISC"
},
"node_modules/yargs": {
"version": "18.0.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.0.0.tgz",
+ "integrity": "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -8972,6 +11565,8 @@
},
"node_modules/yargs-parser": {
"version": "22.0.0",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz",
+ "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==",
"dev": true,
"license": "ISC",
"engines": {
@@ -8980,6 +11575,8 @@
},
"node_modules/yoctocolors": {
"version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.2.tgz",
+ "integrity": "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==",
"dev": true,
"license": "MIT",
"engines": {
@@ -8991,6 +11588,8 @@
},
"node_modules/youch": {
"version": "4.1.0-beta.10",
+ "resolved": "https://registry.npmjs.org/youch/-/youch-4.1.0-beta.10.tgz",
+ "integrity": "sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -9003,6 +11602,8 @@
},
"node_modules/youch-core": {
"version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/youch-core/-/youch-core-0.3.3.tgz",
+ "integrity": "sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -9012,6 +11613,8 @@
},
"node_modules/youch/node_modules/cookie": {
"version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz",
+ "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -9024,10 +11627,14 @@
},
"node_modules/zimmerframe": {
"version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/zimmerframe/-/zimmerframe-1.1.4.tgz",
+ "integrity": "sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==",
"license": "MIT"
},
"node_modules/zod": {
"version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz",
+ "integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==",
"dev": true,
"license": "MIT",
"funding": {
@@ -9036,10 +11643,10 @@
},
"packages/arrow": {
"name": "@datastream/arrow",
- "version": "0.5.0",
+ "version": "0.6.0",
"license": "MIT",
"dependencies": {
- "@datastream/core": "0.5.0",
+ "@datastream/core": "0.6.0",
"apache-arrow": "21.1.0"
},
"engines": {
@@ -9048,10 +11655,10 @@
},
"packages/aws": {
"name": "@datastream/aws",
- "version": "0.5.0",
+ "version": "0.6.0",
"license": "MIT",
"dependencies": {
- "@datastream/core": "0.5.0"
+ "@datastream/core": "0.6.0"
},
"devDependencies": {
"@aws-sdk/client-cloudwatch-logs": "^3.0.0",
@@ -9121,10 +11728,10 @@
},
"packages/base64": {
"name": "@datastream/base64",
- "version": "0.5.0",
+ "version": "0.6.0",
"license": "MIT",
"dependencies": {
- "@datastream/core": "0.5.0"
+ "@datastream/core": "0.6.0"
},
"engines": {
"node": ">=24"
@@ -9132,10 +11739,10 @@
},
"packages/charset": {
"name": "@datastream/charset",
- "version": "0.5.0",
+ "version": "0.6.0",
"license": "MIT",
"dependencies": {
- "@datastream/core": "0.5.0",
+ "@datastream/core": "0.6.0",
"chardet": "2.1.1",
"iconv-lite": "0.7.2"
},
@@ -9145,10 +11752,10 @@
},
"packages/compress": {
"name": "@datastream/compress",
- "version": "0.5.0",
+ "version": "0.6.0",
"license": "MIT",
"dependencies": {
- "@datastream/core": "0.5.0"
+ "@datastream/core": "0.6.0"
},
"devDependencies": {
"brotli-wasm": "^3.0.0"
@@ -9167,10 +11774,10 @@
},
"packages/core": {
"name": "@datastream/core",
- "version": "0.5.0",
+ "version": "0.6.0",
"license": "MIT",
"devDependencies": {
- "@datastream/object": "0.5.0"
+ "@datastream/object": "0.6.0"
},
"engines": {
"node": ">=24"
@@ -9178,11 +11785,11 @@
},
"packages/csv": {
"name": "@datastream/csv",
- "version": "0.5.0",
+ "version": "0.6.0",
"license": "MIT",
"dependencies": {
- "@datastream/core": "0.5.0",
- "@datastream/object": "0.5.0"
+ "@datastream/core": "0.6.0",
+ "@datastream/object": "0.6.0"
},
"engines": {
"node": ">=24"
@@ -9190,10 +11797,10 @@
},
"packages/digest": {
"name": "@datastream/digest",
- "version": "0.5.0",
+ "version": "0.6.0",
"license": "MIT",
"dependencies": {
- "@datastream/core": "0.5.0",
+ "@datastream/core": "0.6.0",
"hash-wasm": "4.12.0"
},
"engines": {
@@ -9202,13 +11809,13 @@
},
"packages/duckdb": {
"name": "@datastream/duckdb",
- "version": "0.5.0",
+ "version": "0.6.0",
"license": "MIT",
"dependencies": {
- "@datastream/core": "0.5.0"
+ "@datastream/core": "0.6.0"
},
"devDependencies": {
- "@datastream/arrow": "0.5.0",
+ "@datastream/arrow": "0.6.0",
"@duckdb/duckdb-wasm": "1.33.1-dev45.0",
"@duckdb/node-api": "1.5.3-r.1",
"apache-arrow": "21.1.0"
@@ -9235,10 +11842,10 @@
},
"packages/encrypt": {
"name": "@datastream/encrypt",
- "version": "0.5.0",
+ "version": "0.6.0",
"license": "MIT",
"dependencies": {
- "@datastream/core": "0.5.0"
+ "@datastream/core": "0.6.0"
},
"devDependencies": {
"libsodium-wrappers": ">=0.7.0"
@@ -9257,10 +11864,10 @@
},
"packages/fetch": {
"name": "@datastream/fetch",
- "version": "0.5.0",
+ "version": "0.6.0",
"license": "MIT",
"dependencies": {
- "@datastream/core": "0.5.0"
+ "@datastream/core": "0.6.0"
},
"engines": {
"node": ">=24"
@@ -9268,10 +11875,10 @@
},
"packages/file": {
"name": "@datastream/file",
- "version": "0.5.0",
+ "version": "0.6.0",
"license": "MIT",
"dependencies": {
- "@datastream/core": "0.5.0"
+ "@datastream/core": "0.6.0"
},
"engines": {
"node": ">=24"
@@ -9279,10 +11886,10 @@
},
"packages/indexeddb": {
"name": "@datastream/indexeddb",
- "version": "0.5.0",
+ "version": "0.6.0",
"license": "MIT",
"dependencies": {
- "@datastream/core": "0.5.0",
+ "@datastream/core": "0.6.0",
"idb": "8.0.3"
},
"engines": {
@@ -9291,10 +11898,10 @@
},
"packages/ipfs": {
"name": "@datastream/ipfs",
- "version": "0.5.0",
+ "version": "0.6.0",
"license": "MIT",
"dependencies": {
- "@datastream/core": "0.5.0"
+ "@datastream/core": "0.6.0"
},
"engines": {
"node": ">=24"
@@ -9302,10 +11909,10 @@
},
"packages/json": {
"name": "@datastream/json",
- "version": "0.5.0",
+ "version": "0.6.0",
"license": "MIT",
"dependencies": {
- "@datastream/core": "0.5.0"
+ "@datastream/core": "0.6.0"
},
"engines": {
"node": ">=24"
@@ -9313,10 +11920,10 @@
},
"packages/kafka": {
"name": "@datastream/kafka",
- "version": "0.5.0",
+ "version": "0.6.0",
"license": "MIT",
"dependencies": {
- "@datastream/core": "0.5.0"
+ "@datastream/core": "0.6.0"
},
"devDependencies": {
"kafkajs": "^2.0.0"
@@ -9335,10 +11942,10 @@
},
"packages/object": {
"name": "@datastream/object",
- "version": "0.5.0",
+ "version": "0.6.0",
"license": "MIT",
"dependencies": {
- "@datastream/core": "0.5.0"
+ "@datastream/core": "0.6.0"
},
"engines": {
"node": ">=24"
@@ -9346,10 +11953,10 @@
},
"packages/protobuf": {
"name": "@datastream/protobuf",
- "version": "0.5.0",
+ "version": "0.6.0",
"license": "MIT",
"dependencies": {
- "@datastream/core": "0.5.0"
+ "@datastream/core": "0.6.0"
},
"devDependencies": {
"protobufjs": "^8.0.0"
@@ -9368,10 +11975,10 @@
},
"packages/schema-registry": {
"name": "@datastream/schema-registry",
- "version": "0.5.0",
+ "version": "0.6.0",
"license": "MIT",
"dependencies": {
- "@datastream/core": "0.5.0"
+ "@datastream/core": "0.6.0"
},
"engines": {
"node": ">=24"
@@ -9379,10 +11986,10 @@
},
"packages/string": {
"name": "@datastream/string",
- "version": "0.5.0",
+ "version": "0.6.0",
"license": "MIT",
"dependencies": {
- "@datastream/core": "0.5.0"
+ "@datastream/core": "0.6.0"
},
"engines": {
"node": ">=24"
@@ -9390,10 +11997,10 @@
},
"packages/validate": {
"name": "@datastream/validate",
- "version": "0.5.0",
+ "version": "0.6.0",
"license": "MIT",
"dependencies": {
- "@datastream/core": "0.5.0",
+ "@datastream/core": "0.6.0",
"ajv-cmd": "0.13.3"
},
"engines": {
@@ -9401,7 +12008,7 @@
}
},
"websites/datastream.js.org": {
- "version": "0.5.0",
+ "version": "0.6.0",
"dependencies": {
"@plausible-analytics/tracker": "0.4.5",
"@willfarrell-ds/svelte": "0.0.0-alpha.6",
diff --git a/package.json b/package.json
index 5985f26..1352db4 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@datastream/monorepo",
- "version": "0.5.0",
+ "version": "0.6.0",
"description": "Streams made easy.",
"private": true,
"type": "module",
diff --git a/packages/arrow/package.json b/packages/arrow/package.json
index ab12ca0..e28dff0 100644
--- a/packages/arrow/package.json
+++ b/packages/arrow/package.json
@@ -1,6 +1,6 @@
{
"name": "@datastream/arrow",
- "version": "0.5.0",
+ "version": "0.6.0",
"description": "Apache Arrow record batch transform streams",
"type": "module",
"engines": {
@@ -64,7 +64,7 @@
},
"homepage": "https://datastream.js.org",
"dependencies": {
- "@datastream/core": "0.5.0",
+ "@datastream/core": "0.6.0",
"apache-arrow": "21.1.0"
}
}
diff --git a/packages/aws/package.json b/packages/aws/package.json
index 40dfcb4..4579a48 100644
--- a/packages/aws/package.json
+++ b/packages/aws/package.json
@@ -1,6 +1,6 @@
{
"name": "@datastream/aws",
- "version": "0.5.0",
+ "version": "0.6.0",
"description": "AWS service streaming integrations for CloudWatch Logs, DynamoDB, DynamoDB Streams, Kinesis, Lambda, S3, SNS, and SQS",
"type": "module",
"engines": {
@@ -187,7 +187,7 @@
},
"homepage": "https://datastream.js.org",
"dependencies": {
- "@datastream/core": "0.5.0"
+ "@datastream/core": "0.6.0"
},
"peerDependencies": {
"@aws-sdk/client-cloudwatch-logs": "^3.0.0",
diff --git a/packages/base64/package.json b/packages/base64/package.json
index cf2f23a..c77452b 100644
--- a/packages/base64/package.json
+++ b/packages/base64/package.json
@@ -1,6 +1,6 @@
{
"name": "@datastream/base64",
- "version": "0.5.0",
+ "version": "0.6.0",
"description": "Base64 encoding and decoding transform streams",
"type": "module",
"engines": {
@@ -61,6 +61,6 @@
},
"homepage": "https://datastream.js.org",
"dependencies": {
- "@datastream/core": "0.5.0"
+ "@datastream/core": "0.6.0"
}
}
diff --git a/packages/charset/package.json b/packages/charset/package.json
index bda3669..b118e78 100644
--- a/packages/charset/package.json
+++ b/packages/charset/package.json
@@ -1,6 +1,6 @@
{
"name": "@datastream/charset",
- "version": "0.5.0",
+ "version": "0.6.0",
"description": "Character encoding detection, decoding, and conversion streams",
"type": "module",
"engines": {
@@ -109,7 +109,7 @@
},
"homepage": "https://datastream.js.org",
"dependencies": {
- "@datastream/core": "0.5.0",
+ "@datastream/core": "0.6.0",
"chardet": "2.1.1",
"iconv-lite": "0.7.2"
}
diff --git a/packages/compress/package.json b/packages/compress/package.json
index 4b0c567..5e2c3bf 100644
--- a/packages/compress/package.json
+++ b/packages/compress/package.json
@@ -1,6 +1,6 @@
{
"name": "@datastream/compress",
- "version": "0.5.0",
+ "version": "0.6.0",
"description": "Compression and decompression streams for gzip, deflate, brotli, and zstd",
"type": "module",
"engines": {
@@ -125,7 +125,7 @@
},
"homepage": "https://datastream.js.org",
"dependencies": {
- "@datastream/core": "0.5.0"
+ "@datastream/core": "0.6.0"
},
"devDependencies": {
"brotli-wasm": "^3.0.0"
diff --git a/packages/core/package.json b/packages/core/package.json
index 094a4ac..d42e7a0 100644
--- a/packages/core/package.json
+++ b/packages/core/package.json
@@ -1,6 +1,6 @@
{
"name": "@datastream/core",
- "version": "0.5.0",
+ "version": "0.6.0",
"description": "Stream creation utilities and pipeline functions for Web Streams API and Node.js streams",
"type": "module",
"engines": {
@@ -62,6 +62,6 @@
"homepage": "https://datastream.js.org",
"dependencies": {},
"devDependencies": {
- "@datastream/object": "0.5.0"
+ "@datastream/object": "0.6.0"
}
}
diff --git a/packages/csv/package.json b/packages/csv/package.json
index 272fe94..dcd6154 100644
--- a/packages/csv/package.json
+++ b/packages/csv/package.json
@@ -1,6 +1,6 @@
{
"name": "@datastream/csv",
- "version": "0.5.0",
+ "version": "0.6.0",
"description": "CSV parsing and formatting transform streams",
"type": "module",
"engines": {
@@ -64,7 +64,7 @@
},
"homepage": "https://datastream.js.org",
"dependencies": {
- "@datastream/core": "0.5.0",
- "@datastream/object": "0.5.0"
+ "@datastream/core": "0.6.0",
+ "@datastream/object": "0.6.0"
}
}
diff --git a/packages/digest/package.json b/packages/digest/package.json
index 34b109e..626cca9 100644
--- a/packages/digest/package.json
+++ b/packages/digest/package.json
@@ -1,6 +1,6 @@
{
"name": "@datastream/digest",
- "version": "0.5.0",
+ "version": "0.6.0",
"description": "Cryptographic hash digest pass-through streams",
"type": "module",
"engines": {
@@ -61,7 +61,7 @@
},
"homepage": "https://datastream.js.org",
"dependencies": {
- "@datastream/core": "0.5.0",
+ "@datastream/core": "0.6.0",
"hash-wasm": "4.12.0"
}
}
diff --git a/packages/duckdb/package.json b/packages/duckdb/package.json
index bdcf9e3..ad768e9 100644
--- a/packages/duckdb/package.json
+++ b/packages/duckdb/package.json
@@ -1,6 +1,6 @@
{
"name": "@datastream/duckdb",
- "version": "0.5.0",
+ "version": "0.6.0",
"description": "DuckDB writable streams (copy-from) for Node and browser",
"type": "module",
"engines": {
@@ -64,7 +64,7 @@
},
"homepage": "https://datastream.js.org",
"dependencies": {
- "@datastream/core": "0.5.0"
+ "@datastream/core": "0.6.0"
},
"peerDependencies": {
"@duckdb/duckdb-wasm": "^1.33.1-dev45.0",
@@ -83,7 +83,7 @@
}
},
"devDependencies": {
- "@datastream/arrow": "0.5.0",
+ "@datastream/arrow": "0.6.0",
"@duckdb/duckdb-wasm": "1.33.1-dev45.0",
"@duckdb/node-api": "1.5.3-r.1",
"apache-arrow": "21.1.0"
diff --git a/packages/encrypt/package.json b/packages/encrypt/package.json
index 9924185..86ca642 100644
--- a/packages/encrypt/package.json
+++ b/packages/encrypt/package.json
@@ -1,6 +1,6 @@
{
"name": "@datastream/encrypt",
- "version": "0.5.0",
+ "version": "0.6.0",
"description": "Symmetric encryption/decryption streams",
"type": "module",
"engines": {
@@ -60,7 +60,7 @@
},
"homepage": "https://datastream.js.org",
"dependencies": {
- "@datastream/core": "0.5.0"
+ "@datastream/core": "0.6.0"
},
"devDependencies": {
"libsodium-wrappers": ">=0.7.0"
diff --git a/packages/fetch/package.json b/packages/fetch/package.json
index e9cde0c..27b73e8 100644
--- a/packages/fetch/package.json
+++ b/packages/fetch/package.json
@@ -1,6 +1,6 @@
{
"name": "@datastream/fetch",
- "version": "0.5.0",
+ "version": "0.6.0",
"description": "HTTP fetch-based readable and writable streams with pagination and rate limiting",
"type": "module",
"engines": {
@@ -61,6 +61,6 @@
},
"homepage": "https://datastream.js.org",
"dependencies": {
- "@datastream/core": "0.5.0"
+ "@datastream/core": "0.6.0"
}
}
diff --git a/packages/file/package.json b/packages/file/package.json
index bc27772..7088e83 100644
--- a/packages/file/package.json
+++ b/packages/file/package.json
@@ -1,6 +1,6 @@
{
"name": "@datastream/file",
- "version": "0.5.0",
+ "version": "0.6.0",
"description": "File system readable and writable streams with extension type enforcement",
"type": "module",
"engines": {
@@ -61,6 +61,6 @@
},
"homepage": "https://datastream.js.org",
"dependencies": {
- "@datastream/core": "0.5.0"
+ "@datastream/core": "0.6.0"
}
}
diff --git a/packages/indexeddb/package.json b/packages/indexeddb/package.json
index c2be39d..a01e1f8 100644
--- a/packages/indexeddb/package.json
+++ b/packages/indexeddb/package.json
@@ -1,6 +1,6 @@
{
"name": "@datastream/indexeddb",
- "version": "0.5.0",
+ "version": "0.6.0",
"description": "IndexedDB readable and writable streams for browser storage",
"type": "module",
"engines": {
@@ -61,7 +61,7 @@
},
"homepage": "https://datastream.js.org",
"dependencies": {
- "@datastream/core": "0.5.0",
+ "@datastream/core": "0.6.0",
"idb": "8.0.3"
}
}
diff --git a/packages/ipfs/package.json b/packages/ipfs/package.json
index a3b1988..54b7749 100644
--- a/packages/ipfs/package.json
+++ b/packages/ipfs/package.json
@@ -1,6 +1,6 @@
{
"name": "@datastream/ipfs",
- "version": "0.5.0",
+ "version": "0.6.0",
"description": "IPFS get and add streaming operations",
"type": "module",
"engines": {
@@ -62,6 +62,6 @@
},
"homepage": "https://datastream.js.org",
"dependencies": {
- "@datastream/core": "0.5.0"
+ "@datastream/core": "0.6.0"
}
}
diff --git a/packages/json/package.json b/packages/json/package.json
index 66d4cc8..e0f3539 100644
--- a/packages/json/package.json
+++ b/packages/json/package.json
@@ -1,6 +1,6 @@
{
"name": "@datastream/json",
- "version": "0.5.0",
+ "version": "0.6.0",
"description": "JSON and NDJSON (JSON Lines) parsing and formatting transform streams",
"type": "module",
"engines": {
@@ -64,6 +64,6 @@
},
"homepage": "https://datastream.js.org",
"dependencies": {
- "@datastream/core": "0.5.0"
+ "@datastream/core": "0.6.0"
}
}
diff --git a/packages/kafka/package.json b/packages/kafka/package.json
index 3bee628..460ef38 100644
--- a/packages/kafka/package.json
+++ b/packages/kafka/package.json
@@ -1,6 +1,6 @@
{
"name": "@datastream/kafka",
- "version": "0.5.0",
+ "version": "0.6.0",
"description": "Kafka producer and consumer streams (Node, via kafkajs)",
"type": "module",
"engines": {
@@ -65,7 +65,7 @@
},
"homepage": "https://datastream.js.org",
"dependencies": {
- "@datastream/core": "0.5.0"
+ "@datastream/core": "0.6.0"
},
"peerDependencies": {
"kafkajs": "^2.0.0"
diff --git a/packages/object/package.json b/packages/object/package.json
index 497c70e..33d9627 100644
--- a/packages/object/package.json
+++ b/packages/object/package.json
@@ -1,6 +1,6 @@
{
"name": "@datastream/object",
- "version": "0.5.0",
+ "version": "0.6.0",
"description": "Object transform streams for picking, omitting, pivoting, batching, and key mapping",
"type": "module",
"engines": {
@@ -61,6 +61,6 @@
},
"homepage": "https://datastream.js.org",
"dependencies": {
- "@datastream/core": "0.5.0"
+ "@datastream/core": "0.6.0"
}
}
diff --git a/packages/protobuf/package.json b/packages/protobuf/package.json
index 6f12238..cce1bb7 100644
--- a/packages/protobuf/package.json
+++ b/packages/protobuf/package.json
@@ -1,6 +1,6 @@
{
"name": "@datastream/protobuf",
- "version": "0.5.0",
+ "version": "0.6.0",
"description": "Protobuf encode/decode and length-prefix framing transform streams",
"type": "module",
"engines": {
@@ -65,7 +65,7 @@
},
"homepage": "https://datastream.js.org",
"dependencies": {
- "@datastream/core": "0.5.0"
+ "@datastream/core": "0.6.0"
},
"devDependencies": {
"protobufjs": "^8.0.0"
diff --git a/packages/schema-registry/package.json b/packages/schema-registry/package.json
index 25e43d4..1c0ab0d 100644
--- a/packages/schema-registry/package.json
+++ b/packages/schema-registry/package.json
@@ -1,6 +1,6 @@
{
"name": "@datastream/schema-registry",
- "version": "0.5.0",
+ "version": "0.6.0",
"description": "Schema-Registry wire-format framing transform streams (Confluent and AWS Glue)",
"type": "module",
"engines": {
@@ -66,6 +66,6 @@
},
"homepage": "https://datastream.js.org",
"dependencies": {
- "@datastream/core": "0.5.0"
+ "@datastream/core": "0.6.0"
}
}
diff --git a/packages/string/package.json b/packages/string/package.json
index f5c495c..9601481 100644
--- a/packages/string/package.json
+++ b/packages/string/package.json
@@ -1,6 +1,6 @@
{
"name": "@datastream/string",
- "version": "0.5.0",
+ "version": "0.6.0",
"description": "String transform streams for splitting, replacing, counting, and deduplication",
"type": "module",
"engines": {
@@ -61,6 +61,6 @@
},
"homepage": "https://datastream.js.org",
"dependencies": {
- "@datastream/core": "0.5.0"
+ "@datastream/core": "0.6.0"
}
}
diff --git a/packages/validate/package.json b/packages/validate/package.json
index 849633f..b5ded71 100644
--- a/packages/validate/package.json
+++ b/packages/validate/package.json
@@ -1,6 +1,6 @@
{
"name": "@datastream/validate",
- "version": "0.5.0",
+ "version": "0.6.0",
"description": "JSON Schema validation transform streams using Ajv",
"type": "module",
"engines": {
@@ -61,7 +61,7 @@
},
"homepage": "https://datastream.js.org",
"dependencies": {
- "@datastream/core": "0.5.0",
+ "@datastream/core": "0.6.0",
"ajv-cmd": "0.13.3"
}
}
diff --git a/stryker.node-test.config.json b/stryker.node-test.config.json
new file mode 100644
index 0000000..75a973d
--- /dev/null
+++ b/stryker.node-test.config.json
@@ -0,0 +1,20 @@
+{
+ "$schema": "./node_modules/@stryker-mutator/core/schema/stryker-schema.json",
+ "packageManager": "npm",
+ "testRunner": "node-test",
+ "nodeTest": {
+ "testFiles": ["packages/encrypt/**/*.test.js"],
+ "nodeArgs": ["--conditions=node"],
+ "concurrency": false
+ },
+ "coverageAnalysis": "perTest",
+ "mutate": [
+ "packages/encrypt/**/*.node.mjs",
+ "!**/*.map",
+ "!**/node_modules/**"
+ ],
+ "plugins": ["@stryker-mutator/node-test-runner"],
+ "reporters": ["progress", "clear-text"],
+ "thresholds": { "high": 100, "low": 100, "break": 0 },
+ "tempDirName": "/tmp/stryker/@datastream/node-test"
+}
diff --git a/websites/datastream.js.org/package.json b/websites/datastream.js.org/package.json
index 2d53031..cc3a0d7 100644
--- a/websites/datastream.js.org/package.json
+++ b/websites/datastream.js.org/package.json
@@ -2,7 +2,7 @@
"name": "datastream.js.org",
"description": "SvelteKit SSR",
"private": true,
- "version": "0.5.0",
+ "version": "0.6.0",
"type": "module",
"engines": {
"node": ">=24"
From dafb3abfb348907e2adf6236bc6906b66c88e61f Mon Sep 17 00:00:00 2001
From: will Farrell
Date: Mon, 15 Jun 2026 15:30:46 -0600
Subject: [PATCH 19/27] test: impvoe coverage
Signed-off-by: will Farrell
---
.gitignore | 4 +
biome.json | 19 ++-
packages/aws/s3.js | 28 +++--
packages/aws/s3.test.js | 48 ++++++++
packages/core/index.test.js | 42 +++++++
packages/csv/index.test.js | 1 +
packages/protobuf/index.js | 109 ++++++++++--------
packages/protobuf/index.test.js | 58 ++++++++++
.../src/routes/docs/+layout.svelte | 1 +
9 files changed, 250 insertions(+), 60 deletions(-)
diff --git a/.gitignore b/.gitignore
index 8127047..2ed9060 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,6 +17,10 @@ lerna-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
+# Stryker mutation testing output
+reports
+.stryker-tmp
+
# Runtime data
pids
*.pid
diff --git a/biome.json b/biome.json
index 5d77c5d..2ef7228 100644
--- a/biome.json
+++ b/biome.json
@@ -1,5 +1,5 @@
{
- "$schema": "https://biomejs.dev/schemas/2.4.16/schema.json",
+ "$schema": "https://biomejs.dev/schemas/2.5.0/schema.json",
"vcs": {
"enabled": true,
"clientKind": "git",
@@ -50,6 +50,23 @@
"linter": {
"enabled": false
}
+ },
+ "linter": {
+ "rules": {
+ "a11y": {
+ "useSemanticElements": "off"
+ }
+ }
+ }
+ },
+ {
+ "includes": ["**/*.svg"],
+ "linter": {
+ "rules": {
+ "a11y": {
+ "noSvgWithoutTitle": "off"
+ }
+ }
}
}
]
diff --git a/packages/aws/s3.js b/packages/aws/s3.js
index b3a22f6..507bead 100644
--- a/packages/aws/s3.js
+++ b/packages/aws/s3.js
@@ -100,15 +100,17 @@ export const awsS3ChecksumStream = (
let filled = 0;
while (filled < partSize) {
const head = pending[0];
- const need = partSize - filled;
- if (head.byteLength <= need) {
- part.set(head, filled);
- filled += head.byteLength;
+ // Copy as much of the head chunk as the part still needs. `rest` is
+ // whatever is left of the head afterwards: drop the head once it is fully
+ // consumed, otherwise keep the remainder at the front for the next part.
+ const take = Math.min(head.byteLength, partSize - filled);
+ part.set(head.subarray(0, take), filled);
+ filled += take;
+ const rest = head.subarray(take);
+ if (rest.byteLength === 0) {
pending.shift();
} else {
- part.set(head.subarray(0, need), filled);
- pending[0] = head.subarray(need);
- filled += need;
+ pending[0] = rest;
}
}
pendingLen -= partSize;
@@ -117,15 +119,17 @@ export const awsS3ChecksumStream = (
const passThrough = async (chunk) => {
if (typeof chunk === "string") {
chunk = new TextEncoder().encode(chunk);
- } else if (!(chunk instanceof Uint8Array)) {
- // Match the old _concatBuffers handling of ArrayBuffer/Buffer inputs.
+ } else {
+ // Normalize ArrayBuffer/Buffer/Uint8Array to a plain Uint8Array so
+ // takePart's subarray/set views are always valid.
chunk = new Uint8Array(chunk);
}
pending.push(chunk);
pendingLen += chunk.byteLength;
- // Peel off every whole part the buffered bytes can supply; any trailing
- // partial part stays buffered for the next chunk (or the final flush).
- while (pendingLen >= partSize) {
+ // Digest every whole part the buffered bytes can supply; any trailing
+ // partial part (< partSize) stays buffered for the next chunk or the flush.
+ const wholeParts = Math.floor(pendingLen / partSize);
+ for (let part = 0; part < wholeParts; part++) {
const checksum = await crypto.subtle.digest(algorithm, takePart());
checksums.push(checksum);
}
diff --git a/packages/aws/s3.test.js b/packages/aws/s3.test.js
index eaa3b1b..4b35764 100644
--- a/packages/aws/s3.test.js
+++ b/packages/aws/s3.test.js
@@ -266,6 +266,38 @@ test(`${variant}: awsS3ChecksumStream should make multi-part checksum with small
deepStrictEqual(result.s3.partSize, 50);
});
+test(`${variant}: awsS3ChecksumStream should emit a trailing partial part below partSize`, async (_t) => {
+ // 130 bytes at partSize 50 -> two whole parts (100) plus a 30-byte remainder
+ // the flush digests: exactly three checksums. A non-exact multiple pins the
+ // floor() part-count so it cannot round/ceil into a phantom extra part.
+ const input = "x".repeat(130);
+ const options = {
+ ChecksumAlgorithm: "SHA256",
+ partSize: 50,
+ };
+
+ const stream = [createReadableStream(input), awsS3ChecksumStream(options)];
+ const result = await pipeline(stream);
+
+ deepStrictEqual(result.s3.checksums.length, 3);
+});
+
+test(`${variant}: awsS3ChecksumStream should assemble parts that span multiple chunks`, async (_t) => {
+ // Four 30-byte chunks (120 bytes) at partSize 50: each whole part is filled
+ // from more than one buffered chunk, exercising the partial-chunk carry-over
+ // (a part needs 50 = 30 + 20, leaving a 10-byte tail of the second chunk).
+ const input = Array.from({ length: 4 }, () => new Uint8Array(30).fill(7));
+ const options = {
+ ChecksumAlgorithm: "SHA256",
+ partSize: 50,
+ };
+
+ const stream = [createReadableStream(input), awsS3ChecksumStream(options)];
+ const result = await pipeline(stream);
+
+ deepStrictEqual(result.s3.checksums.length, 3);
+});
+
test(`${variant}: awsS3ChecksumStream should make checksum with custom resultKey`, async (_t) => {
const input = "x".repeat(16_384);
const options = {
@@ -295,6 +327,22 @@ test(`${variant}: awsS3ChecksumStream should handle Uint8Array input`, async (_t
deepStrictEqual(result.s3.checksums.length, 2);
});
+test(`${variant}: awsS3ChecksumStream should handle ArrayBuffer input`, async (_t) => {
+ // An ArrayBuffer is neither a string nor a Uint8Array, exercising the
+ // `new Uint8Array(chunk)` coercion branch. Wrapped in an array so object-mode
+ // delivery keeps it an ArrayBuffer rather than chunking it into Uint8Arrays.
+ const input = [new TextEncoder().encode("x".repeat(100)).buffer];
+ const options = {
+ ChecksumAlgorithm: "SHA256",
+ partSize: 50,
+ };
+
+ const stream = [createReadableStream(input), awsS3ChecksumStream(options)];
+ const result = await pipeline(stream);
+
+ deepStrictEqual(result.s3.checksums.length, 2);
+});
+
test(`${variant}: awsS3GetObjectStream should use custom client option`, async (_t) => {
const client = mockClient(S3Client);
client
diff --git a/packages/core/index.test.js b/packages/core/index.test.js
index 838e4c1..a6d4d57 100644
--- a/packages/core/index.test.js
+++ b/packages/core/index.test.js
@@ -2287,6 +2287,48 @@ test(`${variant}: createWritableStream propagates a rejecting async final`, asyn
// does this; these tests pin both behaviours so neither can regress.
// ===========================================================================
+// pipejoin's teardown is build-agnostic: the node build loads under both the
+// node and webstream conditions, so this runs under every variant to keep the
+// teardown `settled` re-entry guard and the already-destroyed skip covered in
+// both builds (the variant-gated tests below would leave those branches uncovered
+// under webstream).
+test(`${variant}: pipejoin teardown is idempotent and skips already-destroyed streams`, async (_t) => {
+ const source = createReadableStream(["a", "b", "c"]);
+ const failing = createTransformStream(() => {
+ throw new Error("teardown-failure");
+ });
+ const sink = createWritableStream();
+ // Count how often the already-destroyed erroring stream gets destroy()ed: Node
+ // tears `failing` down on throw, so teardown's loop must SKIP it (the
+ // `!stream.destroyed` guard) — it must end at exactly one destroy, not two.
+ let failingDestroyCalls = 0;
+ const failingDestroy = failing.destroy.bind(failing);
+ failing.destroy = (error) => {
+ failingDestroyCalls++;
+ return failingDestroy(error);
+ };
+ // Destroying the streams re-emits 'error', re-entering teardown; the `settled`
+ // guard must short-circuit so onError fires exactly once, not once per stream.
+ let onErrorCalls = 0;
+ pipejoin([source, failing, sink], () => {
+ onErrorCalls++;
+ });
+ await timeout(50);
+ strictEqual(
+ onErrorCalls,
+ 1,
+ "onError must fire exactly once (settled guard)",
+ );
+ strictEqual(
+ failingDestroyCalls,
+ 1,
+ "already-destroyed stream must not be re-destroyed",
+ );
+ strictEqual(source.destroyed, true);
+ strictEqual(failing.destroyed, true);
+ strictEqual(sink.destroyed, true);
+});
+
if (variant === "node") {
// A mid-chain error must destroy the upstream source AND the downstream sink,
// not just the stream that threw. With bare `.pipe()` the source survives and
diff --git a/packages/csv/index.test.js b/packages/csv/index.test.js
index 276291d..2eddaef 100644
--- a/packages/csv/index.test.js
+++ b/packages/csv/index.test.js
@@ -1950,6 +1950,7 @@ test(`${variant}: csvArrayToObject should keep a __proto__ header as an own data
const row = output[0];
// The __proto__ column must be stored as an own data property, not lost.
ok(Object.hasOwn(row, "__proto__"));
+ // biome-ignore lint/suspicious/noProto: intentionally reading the own data property literally named "__proto__" to assert prototype-pollution safety.
strictEqual(row.__proto__, "polluted");
strictEqual(row.safe, "ok");
});
diff --git a/packages/protobuf/index.js b/packages/protobuf/index.js
index 4828131..963c77b 100644
--- a/packages/protobuf/index.js
+++ b/packages/protobuf/index.js
@@ -75,57 +75,72 @@ export const protobufLengthPrefixUnframeStream = (
{ maxMessageSize = Number.POSITIVE_INFINITY } = {},
streamOptions = {},
) => {
- // Growable ring-free byte buffer: `buffer` is the backing store (capacity),
- // `start` is the first unconsumed byte and `end` is one past the last buffered
- // byte. readMessage advances `start` instead of re-slicing per message, and
- // append() writes into spare tail capacity — compacting/doubling only when the
- // chunk doesn't fit. The old `concat([buffer, chunk])` per chunk was O(n²) both
- // across many small messages (per-message re-slice) and across one large
- // message spanning many chunks (full re-copy each append); this is amortized
- // O(n) for both.
- let buffer = new Uint8Array(0);
- let start = 0;
- let end = 0;
+ // Buffer incoming chunks as a list instead of one growable byte buffer: the
+ // varint length prefix is parsed across chunk boundaries and each message is
+ // copied out exactly once. This keeps the hot path free of per-chunk realloc
+ // and — just as importantly — free of capacity-reuse branches whose only effect
+ // is speed (and which mutation testing cannot distinguish from the slow path).
+ const pending = [];
+ let pendingLen = 0;
- const append = (chunk) => {
- if (buffer.length - end >= chunk.length) {
- // Fits in the existing tail capacity — no copy of prior bytes.
- buffer.set(chunk, end);
- end += chunk.length;
- return;
+ // Byte at absolute position `pos` (0 <= pos < pendingLen) across the chunks.
+ const byteAt = (pos) => {
+ let index = 0;
+ while (pos >= pending[index].byteLength) {
+ pos -= pending[index].byteLength;
+ index += 1;
}
- // Doesn't fit at the tail. Reclaim the consumed prefix [0, start); grow
- // (doubling) only when even the reclaimed space is insufficient.
- const used = end - start;
- const capacity = Math.max(used + chunk.length, buffer.length * 2);
- if (capacity > buffer.length) {
- const next = new Uint8Array(capacity);
- next.set(buffer.subarray(start, end), 0);
- buffer = next;
- } else {
- buffer.copyWithin(0, start, end);
+ return pending[index][pos];
+ };
+
+ // Drop the first `count` bytes off the front of the buffered chunks.
+ const skip = (count) => {
+ while (count > 0) {
+ const head = pending[0];
+ const n = Math.min(head.byteLength, count);
+ count -= n;
+ pendingLen -= n;
+ const rest = head.subarray(n);
+ if (rest.byteLength === 0) {
+ pending.shift();
+ } else {
+ pending[0] = rest;
+ }
+ }
+ };
+
+ // Copy the first `count` bytes off the front of the buffered chunks into a new
+ // contiguous Uint8Array, consuming them.
+ const take = (count) => {
+ const out = new Uint8Array(count);
+ let filled = 0;
+ while (filled < count) {
+ const head = pending[0];
+ const n = Math.min(head.byteLength, count - filled);
+ out.set(head.subarray(0, n), filled);
+ filled += n;
+ const rest = head.subarray(n);
+ if (rest.byteLength === 0) {
+ pending.shift();
+ } else {
+ pending[0] = rest;
+ }
}
- start = 0;
- end = used;
- buffer.set(chunk, end);
- end += chunk.length;
+ pendingLen -= count;
+ return out;
};
- // Pull one complete length-prefixed message off the front of the buffered
- // region [start, end), or return null when the bytes don't yet hold a full
- // prefix+message.
+ // Pull one complete length-prefixed message off the front, or return null when
+ // the buffered bytes don't yet hold a full prefix + body.
const readMessage = () => {
let length = 0;
let scale = 1;
- let offset = start;
+ let prefixBytes = 0;
let complete = false;
- // offset only ever advances by 1 from start, so it lands on `end` exactly;
- // `!==` (rather than `<`) avoids a phantom read one past the end being
- // indistinguishable from the real terminating-byte case.
- while (offset !== end) {
- const byte = buffer[offset];
+ while (prefixBytes < pendingLen) {
+ const byte = byteAt(prefixBytes);
length += (byte & 0x7f) * scale;
- offset += 1;
+ prefixBytes += 1;
if ((byte & 0x80) === 0) {
complete = true;
break;
@@ -140,16 +155,16 @@ export const protobufLengthPrefixUnframeStream = (
`Protobuf message exceeds maxMessageSize (${maxMessageSize} bytes)`,
);
}
- if (end - offset < length) {
+ if (pendingLen - prefixBytes < length) {
return null;
}
- const message = buffer.slice(offset, offset + length);
- start = offset + length;
- return message;
+ skip(prefixBytes);
+ return take(length);
};
const transform = (chunk, enqueue) => {
- append(chunk);
+ pending.push(chunk);
+ pendingLen += chunk.byteLength;
let message = readMessage();
while (message !== null) {
enqueue(message);
@@ -158,7 +173,7 @@ export const protobufLengthPrefixUnframeStream = (
};
const flush = () => {
- if (end - start > 0) {
+ if (pendingLen > 0) {
throw new Error(
"Protobuf unframe stream ended with an incomplete message",
);
diff --git a/packages/protobuf/index.test.js b/packages/protobuf/index.test.js
index 24f7591..c3d179b 100644
--- a/packages/protobuf/index.test.js
+++ b/packages/protobuf/index.test.js
@@ -243,6 +243,64 @@ test(`${variant}: unframe reassembles messages split across byte-sized chunks`,
);
});
+test(`${variant}: unframe reassembles a body split mid-chunk with trailing frames`, async () => {
+ // Two chunks where the split falls inside bigMessage's body, so a single
+ // message is assembled from a partial first chunk plus a second chunk that
+ // also carries the following frames. This drives the multi-chunk copy path:
+ // the body spans two buffered chunks and the second chunk's tail (the next
+ // frames) must be retained, not discarded.
+ const encoded = await encodeAll([bigMessage, ...messages], { Type });
+ const frames = await streamToArray(
+ pipejoin([
+ createReadableStream(encoded),
+ protobufLengthPrefixFrameStream(),
+ ]),
+ );
+ const stream = concat(frames);
+ // 100 lands inside bigMessage's body (2-byte prefix + ~200-byte body), and the
+ // remainder carries the rest of that body plus all three trailing frames.
+ const splitAt = 100;
+ const chunks = [stream.subarray(0, splitAt), stream.subarray(splitAt)];
+ const unframed = await streamToArray(
+ pipejoin([
+ createReadableStream(chunks),
+ protobufLengthPrefixUnframeStream({ maxMessageSize: 4096 }),
+ ]),
+ );
+ deepStrictEqual(
+ unframed.map((b) => toPlain(Type.decode(b))),
+ [bigMessage, ...messages],
+ );
+});
+
+test(`${variant}: unframe reassembles many small messages fed one byte at a time`, async () => {
+ // Many small messages, fed one byte at a time, so every prefix and body
+ // straddles chunk boundaries and the buffered-chunk list is repeatedly drained
+ // down to a partial message and refilled.
+ const small = Array.from({ length: 20 }, (_, i) => ({
+ id: i,
+ name: `m${i}`,
+ }));
+ const encoded = await encodeAll(small, { Type });
+ const frames = await streamToArray(
+ pipejoin([
+ createReadableStream(encoded),
+ protobufLengthPrefixFrameStream(),
+ ]),
+ );
+ const byteChunks = Array.from(concat(frames), (b) => Uint8Array.of(b));
+ const unframed = await streamToArray(
+ pipejoin([
+ createReadableStream(byteChunks),
+ protobufLengthPrefixUnframeStream({ maxMessageSize: 4096 }),
+ ]),
+ );
+ deepStrictEqual(
+ unframed.map((b) => toPlain(Type.decode(b))),
+ small,
+ );
+});
+
test(`${variant}: unframe throws when a message exceeds maxMessageSize`, async () => {
const encoded = await encodeAll([bigMessage], { Type });
const frames = await streamToArray(
diff --git a/websites/datastream.js.org/src/routes/docs/+layout.svelte b/websites/datastream.js.org/src/routes/docs/+layout.svelte
index 163c02b..895123d 100644
--- a/websites/datastream.js.org/src/routes/docs/+layout.svelte
+++ b/websites/datastream.js.org/src/routes/docs/+layout.svelte
@@ -1,5 +1,6 @@
From 2aa7ee4723fc5e2332487ad2368b84fc8d335f8c Mon Sep 17 00:00:00 2001
From: will Farrell
Date: Mon, 15 Jun 2026 15:41:52 -0600
Subject: [PATCH 20/27] chore: dep update
Signed-off-by: will Farrell
---
package-lock.json | 590 +++++++++++++++++------------------
package.json | 3 +
packages/duckdb/package.json | 2 +-
3 files changed, 299 insertions(+), 296 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 00cdddb..d8d59cf 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -151,17 +151,17 @@
}
},
"node_modules/@aws-sdk/checksums": {
- "version": "3.1000.5",
- "resolved": "https://registry.npmjs.org/@aws-sdk/checksums/-/checksums-3.1000.5.tgz",
- "integrity": "sha512-zOXUUnilC6lgCsQtp77p/QNPmRlTES9Xi6tlDwbR6kfC/kz5PCzZckgHWm5z+8DskdwuMAbFDq61x3zr10GEEQ==",
+ "version": "3.1000.6",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/checksums/-/checksums-3.1000.6.tgz",
+ "integrity": "sha512-RMCrCteiUwYTEv2G9zfP/BEuKHv57665vVieJyp9cf8VgilWxP/KrWVtMdfdDlIH8nFhvu3rIMc29z3ebGEZ1w==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/crc32": "5.2.0",
"@aws-crypto/crc32c": "5.2.0",
"@aws-crypto/util": "5.2.0",
- "@aws-sdk/core": "^3.974.20",
- "@aws-sdk/types": "^3.973.12",
+ "@aws-sdk/core": "^3.974.21",
+ "@aws-sdk/types": "^3.973.13",
"@smithy/core": "^3.24.6",
"@smithy/types": "^4.14.3",
"tslib": "^2.6.2"
@@ -171,17 +171,17 @@
}
},
"node_modules/@aws-sdk/client-cloudwatch-logs": {
- "version": "3.1068.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudwatch-logs/-/client-cloudwatch-logs-3.1068.0.tgz",
- "integrity": "sha512-3OlaC3Grl2fovhdEqkOTctcXIjrouwmY4a0Bkg7q7jgAwAP09/intv/RJ1RD/FDEq+xzV5tsWGKMFowN6idZhQ==",
+ "version": "3.1069.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudwatch-logs/-/client-cloudwatch-logs-3.1069.0.tgz",
+ "integrity": "sha512-cfATk797z1U+oQ4ti486xjBbz7pFOMfMfGw87Zi4TIavaos3cOIHR9V4POD33JM49H1BeiaP1WYRahZJqFVvQg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.974.20",
- "@aws-sdk/credential-provider-node": "^3.972.55",
- "@aws-sdk/types": "^3.973.12",
+ "@aws-sdk/core": "^3.974.21",
+ "@aws-sdk/credential-provider-node": "^3.972.56",
+ "@aws-sdk/types": "^3.973.13",
"@smithy/core": "^3.24.6",
"@smithy/fetch-http-handler": "^5.4.6",
"@smithy/node-http-handler": "^4.7.6",
@@ -193,17 +193,17 @@
}
},
"node_modules/@aws-sdk/client-cognito-identity": {
- "version": "3.1068.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.1068.0.tgz",
- "integrity": "sha512-by2Qj3f9BI9X4cY0n160R3uzkMpI6k9PmGA8QLAuzr8HzkiNrYFygMEPhIEdqBFHQPD/8AXNUs45HYjEDsQ33g==",
+ "version": "3.1069.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.1069.0.tgz",
+ "integrity": "sha512-2otjCOXhvw3ZbV8JGHn+4ztdn8J5DJ/nvP3ZIIBANPD69BU+5RhJnSbA+tPk3S7LJpEep6DJHWQ8ZJn40tCixg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.974.20",
- "@aws-sdk/credential-provider-node": "^3.972.55",
- "@aws-sdk/types": "^3.973.12",
+ "@aws-sdk/core": "^3.974.21",
+ "@aws-sdk/credential-provider-node": "^3.972.56",
+ "@aws-sdk/types": "^3.973.13",
"@smithy/core": "^3.24.6",
"@smithy/fetch-http-handler": "^5.4.6",
"@smithy/node-http-handler": "^4.7.6",
@@ -215,19 +215,19 @@
}
},
"node_modules/@aws-sdk/client-dynamodb": {
- "version": "3.1068.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-dynamodb/-/client-dynamodb-3.1068.0.tgz",
- "integrity": "sha512-DOMUWnLSFHaRC0EixpWMnrQcQaV08P5rzAUdRTEkx72NaDRF0Q6+3QdtqX8ocyHfySzwMwOE9/vHRmhNvWHl/g==",
+ "version": "3.1069.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-dynamodb/-/client-dynamodb-3.1069.0.tgz",
+ "integrity": "sha512-cVnKUba/cdaFfslzw2+IAZGwna8mG0A5yFBELUQ6j7L/vqzEcW7l17ogkCmXhIcsoYAO8WA25c82Tgjet0Fpdw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.974.20",
- "@aws-sdk/credential-provider-node": "^3.972.55",
- "@aws-sdk/dynamodb-codec": "^3.973.20",
- "@aws-sdk/middleware-endpoint-discovery": "^3.972.18",
- "@aws-sdk/types": "^3.973.12",
+ "@aws-sdk/core": "^3.974.21",
+ "@aws-sdk/credential-provider-node": "^3.972.56",
+ "@aws-sdk/dynamodb-codec": "^3.973.21",
+ "@aws-sdk/middleware-endpoint-discovery": "^3.972.19",
+ "@aws-sdk/types": "^3.973.13",
"@smithy/core": "^3.24.6",
"@smithy/fetch-http-handler": "^5.4.6",
"@smithy/node-http-handler": "^4.7.6",
@@ -239,17 +239,17 @@
}
},
"node_modules/@aws-sdk/client-dynamodb-streams": {
- "version": "3.1068.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-dynamodb-streams/-/client-dynamodb-streams-3.1068.0.tgz",
- "integrity": "sha512-8cbPgM++tpgsD+aj0azisy2Lyvb/9zu7iRd3SF2f64O8ea5mQP6wTRUWGNaPtuviBlogJZpCwJP5w0nrzFWtxQ==",
+ "version": "3.1069.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-dynamodb-streams/-/client-dynamodb-streams-3.1069.0.tgz",
+ "integrity": "sha512-w3fPJsb8ejGO34xrdET0MznR54EY0MBroRvxtBnt6fUSnMESr7/vLnuTyvZeAArfxlRcOBgqWy1Etirf6Na6VA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.974.20",
- "@aws-sdk/credential-provider-node": "^3.972.55",
- "@aws-sdk/types": "^3.973.12",
+ "@aws-sdk/core": "^3.974.21",
+ "@aws-sdk/credential-provider-node": "^3.972.56",
+ "@aws-sdk/types": "^3.973.13",
"@smithy/core": "^3.24.6",
"@smithy/fetch-http-handler": "^5.4.6",
"@smithy/node-http-handler": "^4.7.6",
@@ -261,17 +261,17 @@
}
},
"node_modules/@aws-sdk/client-glue": {
- "version": "3.1068.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-glue/-/client-glue-3.1068.0.tgz",
- "integrity": "sha512-T/2aZGVaDDuSSQ3OWhWowBZ3P2hQGIV+16idxiA0Z8WevLWgbzztSGScDyYa7ohe/J/BY0XiYsBavLYtv+yGlg==",
+ "version": "3.1069.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-glue/-/client-glue-3.1069.0.tgz",
+ "integrity": "sha512-OY6jQlYGmDalvl7ljluyEtf3xlsvKbO9zi7oDQTb/UOPSDPVWXmHNQ2O0nr+9amuWqkoig/A3B1OqHaaB4knIw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.974.20",
- "@aws-sdk/credential-provider-node": "^3.972.55",
- "@aws-sdk/types": "^3.973.12",
+ "@aws-sdk/core": "^3.974.21",
+ "@aws-sdk/credential-provider-node": "^3.972.56",
+ "@aws-sdk/types": "^3.973.13",
"@smithy/core": "^3.24.6",
"@smithy/fetch-http-handler": "^5.4.6",
"@smithy/node-http-handler": "^4.7.6",
@@ -283,17 +283,17 @@
}
},
"node_modules/@aws-sdk/client-kinesis": {
- "version": "3.1068.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-kinesis/-/client-kinesis-3.1068.0.tgz",
- "integrity": "sha512-0+5P4CJFf/K5/EBxzRR97OLeQqe3GazyCjV47/ksyTnfr+Bif2UhvZ2Kq6c+s/dqie6LPP4NFAB5Q8D/TZ3+og==",
+ "version": "3.1069.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-kinesis/-/client-kinesis-3.1069.0.tgz",
+ "integrity": "sha512-0p58wlFSVZRgm3J/aoBLoe0It6C+wqGxJkGnZaODY3TQBR7dBkZ12ULaIy6+zH6xXceqH6tuP5Cn2PuSR2avFw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.974.20",
- "@aws-sdk/credential-provider-node": "^3.972.55",
- "@aws-sdk/types": "^3.973.12",
+ "@aws-sdk/core": "^3.974.21",
+ "@aws-sdk/credential-provider-node": "^3.972.56",
+ "@aws-sdk/types": "^3.973.13",
"@smithy/core": "^3.24.6",
"@smithy/fetch-http-handler": "^5.4.6",
"@smithy/node-http-handler": "^4.7.6",
@@ -305,17 +305,17 @@
}
},
"node_modules/@aws-sdk/client-lambda": {
- "version": "3.1068.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-lambda/-/client-lambda-3.1068.0.tgz",
- "integrity": "sha512-GitXCytcrvezkAQbyT+cYMrGPCM9zdh9sU8FrQr1vyniVijXk2X4ZBf2WZwDQcenNPMJyN5YdtUAbmUJCrfZDg==",
+ "version": "3.1069.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-lambda/-/client-lambda-3.1069.0.tgz",
+ "integrity": "sha512-35QhvxgI6H1cxpq9vspmefqDxWI16Jhwpo2wp8TzMRodphzWrHaoCxRXYwGlobhbycplhto3k61XXV8gvlzZJg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.974.20",
- "@aws-sdk/credential-provider-node": "^3.972.55",
- "@aws-sdk/types": "^3.973.12",
+ "@aws-sdk/core": "^3.974.21",
+ "@aws-sdk/credential-provider-node": "^3.972.56",
+ "@aws-sdk/types": "^3.973.13",
"@smithy/core": "^3.24.6",
"@smithy/fetch-http-handler": "^5.4.6",
"@smithy/node-http-handler": "^4.7.6",
@@ -327,21 +327,21 @@
}
},
"node_modules/@aws-sdk/client-s3": {
- "version": "3.1068.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.1068.0.tgz",
- "integrity": "sha512-lFgaIpxZvloNbJvQ337YPdMXhzI2zJdDw13nATVGnkAGNoNPx4ksD84AQAcuW75hsaaMaIuNmXU9sSx6+FTirA==",
+ "version": "3.1069.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.1069.0.tgz",
+ "integrity": "sha512-zkwCW4D88foQ0YHyjVyFhDOIWG+IWiTGXYg8+kUgH6M19son3OsZLvioZGyZdNtlRgLNYfQGBjfArSJOYYt2QQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/sha1-browser": "5.2.0",
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.974.20",
- "@aws-sdk/credential-provider-node": "^3.972.55",
- "@aws-sdk/middleware-flexible-checksums": "^3.974.30",
- "@aws-sdk/middleware-sdk-s3": "^3.972.51",
- "@aws-sdk/signature-v4-multi-region": "^3.996.34",
- "@aws-sdk/types": "^3.973.12",
+ "@aws-sdk/core": "^3.974.21",
+ "@aws-sdk/credential-provider-node": "^3.972.56",
+ "@aws-sdk/middleware-flexible-checksums": "^3.974.31",
+ "@aws-sdk/middleware-sdk-s3": "^3.972.52",
+ "@aws-sdk/signature-v4-multi-region": "^3.996.35",
+ "@aws-sdk/types": "^3.973.13",
"@smithy/core": "^3.24.6",
"@smithy/fetch-http-handler": "^5.4.6",
"@smithy/node-http-handler": "^4.7.6",
@@ -353,17 +353,17 @@
}
},
"node_modules/@aws-sdk/client-sns": {
- "version": "3.1068.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-sns/-/client-sns-3.1068.0.tgz",
- "integrity": "sha512-xIjKGG2yzUhX+IHqq0B/8D6zKKr32+LmYUy/OnV5dDj+j+eUJD7J3Ca6kMVDPI6eWe/fCtdHCgsnZtxhf1LMqg==",
+ "version": "3.1069.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-sns/-/client-sns-3.1069.0.tgz",
+ "integrity": "sha512-qiBqtJQWsWsjX6T0fRuxAs6yNx61003j/YskIq7XAiQ11yZ0PPByn4nqVqu3zJDMWiwbQyf3QBBLYLp5NPbaoA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.974.20",
- "@aws-sdk/credential-provider-node": "^3.972.55",
- "@aws-sdk/types": "^3.973.12",
+ "@aws-sdk/core": "^3.974.21",
+ "@aws-sdk/credential-provider-node": "^3.972.56",
+ "@aws-sdk/types": "^3.973.13",
"@smithy/core": "^3.24.6",
"@smithy/fetch-http-handler": "^5.4.6",
"@smithy/node-http-handler": "^4.7.6",
@@ -375,18 +375,18 @@
}
},
"node_modules/@aws-sdk/client-sqs": {
- "version": "3.1068.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-sqs/-/client-sqs-3.1068.0.tgz",
- "integrity": "sha512-hatCfVf61RsSO5Qjrf7JKln4KiPDprXNJhpx9DNOmyeW1v+i7KNhbawk4d1wAnQ72YciOfhAhyRFec6UZqcnzQ==",
+ "version": "3.1069.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-sqs/-/client-sqs-3.1069.0.tgz",
+ "integrity": "sha512-WVTfzUgaivDgee2802UInuZZFdNspYO2ba8yb56q+qgbDdDCAmk0k35MAmFnTn0hMoiJcDg+6/sk3iCc+aUqwg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.974.20",
- "@aws-sdk/credential-provider-node": "^3.972.55",
- "@aws-sdk/middleware-sdk-sqs": "^3.972.30",
- "@aws-sdk/types": "^3.973.12",
+ "@aws-sdk/core": "^3.974.21",
+ "@aws-sdk/credential-provider-node": "^3.972.56",
+ "@aws-sdk/middleware-sdk-sqs": "^3.972.31",
+ "@aws-sdk/types": "^3.973.13",
"@smithy/core": "^3.24.6",
"@smithy/fetch-http-handler": "^5.4.6",
"@smithy/node-http-handler": "^4.7.6",
@@ -398,18 +398,18 @@
}
},
"node_modules/@aws-sdk/client-sts": {
- "version": "3.1068.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.1068.0.tgz",
- "integrity": "sha512-WCUEpfdsSSO7zsXi7GUwHR+A5HZDQNsGktFJxOm73ZU+WLlBKRDzKdWZdYOpNkgBpXxy5KCeVMvXuaq2s1zn7w==",
+ "version": "3.1069.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.1069.0.tgz",
+ "integrity": "sha512-AJZ9Ujy0NL5KWb4NjP80FeHEgFDb5MvFnNDls3motxOedpyp4vXC5PtOLOlX4eh5k2PysLOQzamfBWee09dXqw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.974.20",
- "@aws-sdk/credential-provider-node": "^3.972.55",
- "@aws-sdk/signature-v4-multi-region": "^3.996.34",
- "@aws-sdk/types": "^3.973.12",
+ "@aws-sdk/core": "^3.974.21",
+ "@aws-sdk/credential-provider-node": "^3.972.56",
+ "@aws-sdk/signature-v4-multi-region": "^3.996.35",
+ "@aws-sdk/types": "^3.973.13",
"@smithy/core": "^3.24.6",
"@smithy/fetch-http-handler": "^5.4.6",
"@smithy/node-http-handler": "^4.7.6",
@@ -421,14 +421,14 @@
}
},
"node_modules/@aws-sdk/core": {
- "version": "3.974.20",
- "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.974.20.tgz",
- "integrity": "sha512-7sDi2B2N3mc3nf1nz6FyEx/FCrJ1N1QnBmraHHQNabFaeAh2IaOOLml48/rHOD1bICHgTRkbBgNTvUzEr5Z35g==",
+ "version": "3.974.21",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.974.21.tgz",
+ "integrity": "sha512-P5JAHvn4dTi96UsAGS67LVOqqpUNNRhnfFXqzCYtdBIGZtqBue4CXvRr9YenOO7PALj/Pn8uuyw53FBCiCYw8w==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/types": "^3.973.12",
- "@aws-sdk/xml-builder": "^3.972.29",
+ "@aws-sdk/types": "^3.973.13",
+ "@aws-sdk/xml-builder": "^3.972.30",
"@aws/lambda-invoke-store": "^0.2.2",
"@smithy/core": "^3.24.6",
"@smithy/signature-v4": "^5.4.6",
@@ -441,14 +441,14 @@
}
},
"node_modules/@aws-sdk/credential-provider-cognito-identity": {
- "version": "3.972.45",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.972.45.tgz",
- "integrity": "sha512-4L/REssieLON1hVsTzZucP1p2u5jmPNejyh/9BCGZXr93IalBbhRPCrtKIKwMTu9yRGr/bcKzhrQocByKLSzLQ==",
+ "version": "3.972.46",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.972.46.tgz",
+ "integrity": "sha512-xQ+zJxuP4MZGsr6TIVVgsLRsxaBu1YqOFNbZMaNskqbTF2d9F8ibBLOMFV1BkUBOvI6ShwhlNViOQcK1Od/RPg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/nested-clients": "^3.997.20",
- "@aws-sdk/types": "^3.973.12",
+ "@aws-sdk/nested-clients": "^3.997.21",
+ "@aws-sdk/types": "^3.973.13",
"@smithy/core": "^3.24.6",
"@smithy/types": "^4.14.3",
"tslib": "^2.6.2"
@@ -458,14 +458,14 @@
}
},
"node_modules/@aws-sdk/credential-provider-env": {
- "version": "3.972.46",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.46.tgz",
- "integrity": "sha512-+GPXVS2srMOlH74S+SmC1gVuP2TvUZ0siuC0onKO93q+udP+M72dmY8wJfVQ5CX9z/9X5A1HHwz5yRIGBtskvQ==",
+ "version": "3.972.47",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.47.tgz",
+ "integrity": "sha512-3YoPwJczcc+MtX2xxXaYaOOWO6xKUJr1ZIIDIFuninr51BYONVVcF/CP8K2xfVRC/PztJjqKWxNGFH7BWQAw1Q==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.974.20",
- "@aws-sdk/types": "^3.973.12",
+ "@aws-sdk/core": "^3.974.21",
+ "@aws-sdk/types": "^3.973.13",
"@smithy/core": "^3.24.6",
"@smithy/types": "^4.14.3",
"tslib": "^2.6.2"
@@ -475,14 +475,14 @@
}
},
"node_modules/@aws-sdk/credential-provider-http": {
- "version": "3.972.48",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.48.tgz",
- "integrity": "sha512-fA5loSdlocacRxyUXtpoHSMuk5rsIKRDzQYVMnMxjcmFeZshaJlJ8lymy/hYKji6sne/UmNGj5pxuEs6kq/Qcg==",
+ "version": "3.972.49",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.49.tgz",
+ "integrity": "sha512-2UtGUPy+x3lqyceHrtC1uEuVxBZbDalPF6KAFqBwYgm4edWdBrZKNnCqzDs7KynWUvEC6mrR+ojRk+ZgQz9C2w==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.974.20",
- "@aws-sdk/types": "^3.973.12",
+ "@aws-sdk/core": "^3.974.21",
+ "@aws-sdk/types": "^3.973.13",
"@smithy/core": "^3.24.6",
"@smithy/fetch-http-handler": "^5.4.6",
"@smithy/node-http-handler": "^4.7.6",
@@ -494,21 +494,21 @@
}
},
"node_modules/@aws-sdk/credential-provider-ini": {
- "version": "3.972.53",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.972.53.tgz",
- "integrity": "sha512-ZfdhIOR41q8TcWEnUac+gCOb+O2LBWdHLmjedXpXz4IEFW2ppNuFcm6p0sMTavpM+zD5TYfpH5Gp7guRyqSgsQ==",
+ "version": "3.972.54",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.972.54.tgz",
+ "integrity": "sha512-Hx4gO4YRjFwitf3MVl3cDwYe1aryJthC4txVl9b+JAURovA50M2ywf9r8j1E/Q6SCTPT4qQpjOAbKYIC9CG+Vw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.974.20",
- "@aws-sdk/credential-provider-env": "^3.972.46",
- "@aws-sdk/credential-provider-http": "^3.972.48",
- "@aws-sdk/credential-provider-login": "^3.972.52",
- "@aws-sdk/credential-provider-process": "^3.972.46",
- "@aws-sdk/credential-provider-sso": "^3.972.52",
- "@aws-sdk/credential-provider-web-identity": "^3.972.52",
- "@aws-sdk/nested-clients": "^3.997.20",
- "@aws-sdk/types": "^3.973.12",
+ "@aws-sdk/core": "^3.974.21",
+ "@aws-sdk/credential-provider-env": "^3.972.47",
+ "@aws-sdk/credential-provider-http": "^3.972.49",
+ "@aws-sdk/credential-provider-login": "^3.972.53",
+ "@aws-sdk/credential-provider-process": "^3.972.47",
+ "@aws-sdk/credential-provider-sso": "^3.972.53",
+ "@aws-sdk/credential-provider-web-identity": "^3.972.53",
+ "@aws-sdk/nested-clients": "^3.997.21",
+ "@aws-sdk/types": "^3.973.13",
"@smithy/core": "^3.24.6",
"@smithy/credential-provider-imds": "^4.3.7",
"@smithy/types": "^4.14.3",
@@ -519,15 +519,15 @@
}
},
"node_modules/@aws-sdk/credential-provider-login": {
- "version": "3.972.52",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.52.tgz",
- "integrity": "sha512-9hu2oR0qH7Fst5Tzdx+UWxm+w5zCXtErTLtOOW5hwwQc170CLwOeniRxyFY6s9mHfGEfC5zFukNBdKBwJR8mhQ==",
+ "version": "3.972.53",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.53.tgz",
+ "integrity": "sha512-+71sluhkgPqdhbbD3UDwUpj24GCkng9HQx6z7qoBFb8dwkF4ktpOcVKDeHpgg8PvBgLYwAnUYLTEGRC/PniCiQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.974.20",
- "@aws-sdk/nested-clients": "^3.997.20",
- "@aws-sdk/types": "^3.973.12",
+ "@aws-sdk/core": "^3.974.21",
+ "@aws-sdk/nested-clients": "^3.997.21",
+ "@aws-sdk/types": "^3.973.13",
"@smithy/core": "^3.24.6",
"@smithy/types": "^4.14.3",
"tslib": "^2.6.2"
@@ -537,19 +537,19 @@
}
},
"node_modules/@aws-sdk/credential-provider-node": {
- "version": "3.972.55",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.55.tgz",
- "integrity": "sha512-zMGLa/dhESVqmCD7mmIFFKSwSFrJGScvCXcjvBZEVOOMauFS5JRQvLTMukFpMEFWiV6dTAlsen2ATDBulLPtbg==",
+ "version": "3.972.56",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.56.tgz",
+ "integrity": "sha512-iI+4o0dvQQ4NHel4FMDiFy5q2gaU/ryLK3niOsoPccAt9WLFRkV4XTYPWRr9XvmBUqEzXG73S4p/8gm0Lu/W3A==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/credential-provider-env": "^3.972.46",
- "@aws-sdk/credential-provider-http": "^3.972.48",
- "@aws-sdk/credential-provider-ini": "^3.972.53",
- "@aws-sdk/credential-provider-process": "^3.972.46",
- "@aws-sdk/credential-provider-sso": "^3.972.52",
- "@aws-sdk/credential-provider-web-identity": "^3.972.52",
- "@aws-sdk/types": "^3.973.12",
+ "@aws-sdk/credential-provider-env": "^3.972.47",
+ "@aws-sdk/credential-provider-http": "^3.972.49",
+ "@aws-sdk/credential-provider-ini": "^3.972.54",
+ "@aws-sdk/credential-provider-process": "^3.972.47",
+ "@aws-sdk/credential-provider-sso": "^3.972.53",
+ "@aws-sdk/credential-provider-web-identity": "^3.972.53",
+ "@aws-sdk/types": "^3.973.13",
"@smithy/core": "^3.24.6",
"@smithy/credential-provider-imds": "^4.3.7",
"@smithy/types": "^4.14.3",
@@ -560,14 +560,14 @@
}
},
"node_modules/@aws-sdk/credential-provider-process": {
- "version": "3.972.46",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.46.tgz",
- "integrity": "sha512-VUoNFBIjWrUN8NbFiQiuxQEgFjvziAlBRPK+ddh27aj65gk0BYu6bLZnrdrNZwpW6vAihtSUtEMQ1PUJ32QRPA==",
+ "version": "3.972.47",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.47.tgz",
+ "integrity": "sha512-tAizPm9IFo/PHn06c+LQJlzfY2AGOlyF0CUljFejrU6LcZBjnk8pmbZK3/xoIDdnIzjEdbClfvY3mXfr818ZEg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.974.20",
- "@aws-sdk/types": "^3.973.12",
+ "@aws-sdk/core": "^3.974.21",
+ "@aws-sdk/types": "^3.973.13",
"@smithy/core": "^3.24.6",
"@smithy/types": "^4.14.3",
"tslib": "^2.6.2"
@@ -577,16 +577,16 @@
}
},
"node_modules/@aws-sdk/credential-provider-sso": {
- "version": "3.972.52",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.972.52.tgz",
- "integrity": "sha512-nb2/n4o/HQf+FVpVbZe9vCTFngmuDoIsltMgLAtjixaKzvzhB4J8WSDFyWgnErgLHk55ctWH+I4PU+LIHhyffg==",
+ "version": "3.972.53",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.972.53.tgz",
+ "integrity": "sha512-pUXE3fu4tfEDV8BksIgf4dXvuIH10FhwHMl/wu8rBD5T1sMpryQWFVitH3kdPS90wlgrGYJQ/meQTSPacyZfeg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.974.20",
- "@aws-sdk/nested-clients": "^3.997.20",
- "@aws-sdk/token-providers": "3.1066.0",
- "@aws-sdk/types": "^3.973.12",
+ "@aws-sdk/core": "^3.974.21",
+ "@aws-sdk/nested-clients": "^3.997.21",
+ "@aws-sdk/token-providers": "3.1069.0",
+ "@aws-sdk/types": "^3.973.13",
"@smithy/core": "^3.24.6",
"@smithy/types": "^4.14.3",
"tslib": "^2.6.2"
@@ -596,15 +596,15 @@
}
},
"node_modules/@aws-sdk/credential-provider-web-identity": {
- "version": "3.972.52",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.52.tgz",
- "integrity": "sha512-lKj6aRSGbqLmpYmM24bY7a1Xmfcq2vkE3hv8CSPYfc1yCu0BPu/XEJ1L4Fm61MsU6ULLNSG8UGsffNoFUBjESA==",
+ "version": "3.972.53",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.53.tgz",
+ "integrity": "sha512-JmMGlhVvSj8uSG9CpeDkJAXT35H89tc6v84iMgEIE75q4yp1MKVVKvopv6Gg28HJIR7hMNkojRF8H2m5W44wyg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.974.20",
- "@aws-sdk/nested-clients": "^3.997.20",
- "@aws-sdk/types": "^3.973.12",
+ "@aws-sdk/core": "^3.974.21",
+ "@aws-sdk/nested-clients": "^3.997.21",
+ "@aws-sdk/types": "^3.973.13",
"@smithy/core": "^3.24.6",
"@smithy/types": "^4.14.3",
"tslib": "^2.6.2"
@@ -614,25 +614,25 @@
}
},
"node_modules/@aws-sdk/credential-providers": {
- "version": "3.1068.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.1068.0.tgz",
- "integrity": "sha512-DN7UewD/XKGfNGWXZsTECWRj3IsULkE7aG+fPwqPf13CnX4UmNvj80g1xieJ0lVdMQ2h0L3gZpn2ClIY06+/vQ==",
+ "version": "3.1069.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.1069.0.tgz",
+ "integrity": "sha512-9emJtp/7OMOhfK2aIk0MdAfCF5v/2ERU3ZriVxAmZXIsoXtq5zmkZumN45/guHk15ZJ9XleKvgI0Ug+sXPZ9GA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/client-cognito-identity": "3.1068.0",
- "@aws-sdk/core": "^3.974.20",
- "@aws-sdk/credential-provider-cognito-identity": "^3.972.45",
- "@aws-sdk/credential-provider-env": "^3.972.46",
- "@aws-sdk/credential-provider-http": "^3.972.48",
- "@aws-sdk/credential-provider-ini": "^3.972.53",
- "@aws-sdk/credential-provider-login": "^3.972.52",
- "@aws-sdk/credential-provider-node": "^3.972.55",
- "@aws-sdk/credential-provider-process": "^3.972.46",
- "@aws-sdk/credential-provider-sso": "^3.972.52",
- "@aws-sdk/credential-provider-web-identity": "^3.972.52",
- "@aws-sdk/nested-clients": "^3.997.20",
- "@aws-sdk/types": "^3.973.12",
+ "@aws-sdk/client-cognito-identity": "3.1069.0",
+ "@aws-sdk/core": "^3.974.21",
+ "@aws-sdk/credential-provider-cognito-identity": "^3.972.46",
+ "@aws-sdk/credential-provider-env": "^3.972.47",
+ "@aws-sdk/credential-provider-http": "^3.972.49",
+ "@aws-sdk/credential-provider-ini": "^3.972.54",
+ "@aws-sdk/credential-provider-login": "^3.972.53",
+ "@aws-sdk/credential-provider-node": "^3.972.56",
+ "@aws-sdk/credential-provider-process": "^3.972.47",
+ "@aws-sdk/credential-provider-sso": "^3.972.53",
+ "@aws-sdk/credential-provider-web-identity": "^3.972.53",
+ "@aws-sdk/nested-clients": "^3.997.21",
+ "@aws-sdk/types": "^3.973.13",
"@smithy/core": "^3.24.6",
"@smithy/credential-provider-imds": "^4.3.7",
"@smithy/types": "^4.14.3",
@@ -643,13 +643,13 @@
}
},
"node_modules/@aws-sdk/dynamodb-codec": {
- "version": "3.973.20",
- "resolved": "https://registry.npmjs.org/@aws-sdk/dynamodb-codec/-/dynamodb-codec-3.973.20.tgz",
- "integrity": "sha512-SFfxiqVgWeIe+RsJJNAMD//2IfehT4bLpGyNJRB0MgHmOIJtdcfMnR1k7KYyaHokSoQVdncVa9O9DIGa4eqcwg==",
+ "version": "3.973.21",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/dynamodb-codec/-/dynamodb-codec-3.973.21.tgz",
+ "integrity": "sha512-wfAWZ6oIrsDOFyYm9bDQNva/WCmvIrVqP3dSCePN5YYWCGWWXkikn5YC0wPSxF92M8kQFPfdVpMaTTV1mRk4Lw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.974.20",
+ "@aws-sdk/core": "^3.974.21",
"@smithy/core": "^3.24.6",
"@smithy/types": "^4.14.3",
"tslib": "^2.6.2"
@@ -659,9 +659,9 @@
}
},
"node_modules/@aws-sdk/endpoint-cache": {
- "version": "3.972.7",
- "resolved": "https://registry.npmjs.org/@aws-sdk/endpoint-cache/-/endpoint-cache-3.972.7.tgz",
- "integrity": "sha512-LkwS3ZOUNL5kHzmz3dDx8lE3HOhZmf2VGjbJ/tMUZJYWWl3J0RJTZM7RFz1MLt06WDVvlShcAjY/RzhYlqLL7g==",
+ "version": "3.972.8",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/endpoint-cache/-/endpoint-cache-3.972.8.tgz",
+ "integrity": "sha512-bBmkG0Dnhfq0/T4Z0PpUr7HkncBVaWvvCbvafeaUM+yC9wa8GGjLJmonq0QL17REB9WivgGeYgWQ5A80Uw5UnQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -673,9 +673,9 @@
}
},
"node_modules/@aws-sdk/lib-storage": {
- "version": "3.1068.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/lib-storage/-/lib-storage-3.1068.0.tgz",
- "integrity": "sha512-BGUS3EXFe+y87odXsC5enyBv4z/QT3EDydv+iTe9hCUr57ndAXCfJbvcm3f+s3aHS5FUDL3WozaBAcrsNeVhyQ==",
+ "version": "3.1069.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/lib-storage/-/lib-storage-3.1069.0.tgz",
+ "integrity": "sha512-i5XY2ZNaBOVXCHrmSe/4YG8Bl1X/qa/WjMbSF7DYXaN1F1x0Q4kQwce+HIYWym0S2/1ljm2aorul5bdU/k7fSA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -690,18 +690,18 @@
"node": ">=20.0.0"
},
"peerDependencies": {
- "@aws-sdk/client-s3": "^3.1068.0"
+ "@aws-sdk/client-s3": "^3.1069.0"
}
},
"node_modules/@aws-sdk/middleware-endpoint-discovery": {
- "version": "3.972.18",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-endpoint-discovery/-/middleware-endpoint-discovery-3.972.18.tgz",
- "integrity": "sha512-1vKJt/6MBB/MBMRM3qzCMdW70syJY8u2DH+dq7yCnPn7wVJmyeAzAa/sK1lIbbYh8BVLbM5FspsT4zbe885gOw==",
+ "version": "3.972.19",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-endpoint-discovery/-/middleware-endpoint-discovery-3.972.19.tgz",
+ "integrity": "sha512-FMgyzUq3Jh+ONRYxryBRNdBd+FUX8PwRl07ccQknNdoms6KCeAEusCkl6whqpDrPQ6OH0ddeSifKyqYSs2DLIw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/endpoint-cache": "^3.972.7",
- "@aws-sdk/types": "^3.973.12",
+ "@aws-sdk/endpoint-cache": "^3.972.8",
+ "@aws-sdk/types": "^3.973.13",
"@smithy/core": "^3.24.6",
"@smithy/types": "^4.14.3",
"tslib": "^2.6.2"
@@ -711,13 +711,13 @@
}
},
"node_modules/@aws-sdk/middleware-flexible-checksums": {
- "version": "3.974.30",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.974.30.tgz",
- "integrity": "sha512-OaIhub+3yTgfFWPzKO8OzOZFIMUoJaiS5v67y3spQg7SoULGoMx4jKVBbE+uhnzkiZXQ+rEDS0RqrK4/aD1yJw==",
+ "version": "3.974.31",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.974.31.tgz",
+ "integrity": "sha512-Yzj6NRYVZdBaCp7o1BwHGyeDBfixdeToLIAMprshIITEdl9wKVSiidVOfeaiH8FyeC1hBmBfDZFvs/aH1Y3xpw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/checksums": "^3.1000.5",
+ "@aws-sdk/checksums": "^3.1000.6",
"tslib": "^2.6.2"
},
"engines": {
@@ -725,15 +725,15 @@
}
},
"node_modules/@aws-sdk/middleware-sdk-s3": {
- "version": "3.972.51",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.972.51.tgz",
- "integrity": "sha512-keQgcIUTcHL0Qn7guhsuLaxQU36r9norCrxgaPH4DNCwon4TPtXdI/UdYuycl9vj3Dlwc3YR1dfL3U+6iIwJ6w==",
+ "version": "3.972.52",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.972.52.tgz",
+ "integrity": "sha512-rerjP08onRqkBh0AcCqip6GkKvESapmLoTgi1xysZ4C6a1xMrIMtTBcEbUb6EY71oeajnigeUD4KwZjtIO+aWQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.974.20",
- "@aws-sdk/signature-v4-multi-region": "^3.996.34",
- "@aws-sdk/types": "^3.973.12",
+ "@aws-sdk/core": "^3.974.21",
+ "@aws-sdk/signature-v4-multi-region": "^3.996.35",
+ "@aws-sdk/types": "^3.973.13",
"@smithy/core": "^3.24.6",
"@smithy/types": "^4.14.3",
"tslib": "^2.6.2"
@@ -743,13 +743,13 @@
}
},
"node_modules/@aws-sdk/middleware-sdk-sqs": {
- "version": "3.972.30",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sqs/-/middleware-sdk-sqs-3.972.30.tgz",
- "integrity": "sha512-PVAj7VgWK/ZxCXnkgC4B7cdJyUN99Nsr7IEduHt4A1GieuB+ZnU5bSifHwapbr17wrFkmdxfSh+aA0Lj+Ads6w==",
+ "version": "3.972.31",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sqs/-/middleware-sdk-sqs-3.972.31.tgz",
+ "integrity": "sha512-56ifsBmK9bLn5EE/t6c0nmjOB1BO8cJDLkA1VOlsN1GR85ROqnaCwVDspqcwsLaBDgPlwyYNedoDIoT3t6Ho1A==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/types": "^3.973.12",
+ "@aws-sdk/types": "^3.973.13",
"@smithy/core": "^3.24.6",
"@smithy/types": "^4.14.3",
"tslib": "^2.6.2"
@@ -759,17 +759,17 @@
}
},
"node_modules/@aws-sdk/nested-clients": {
- "version": "3.997.20",
- "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.997.20.tgz",
- "integrity": "sha512-IYJuLpXp2DEILVQpQOy0PMpkftv0AHEOCn52o0atyOaumA0CdWQ3klPyXdViGYLbNpESsVFMVybvHUeZAuiGxA==",
+ "version": "3.997.21",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.997.21.tgz",
+ "integrity": "sha512-eC7Vl7Qom/BGhZjG9GEqPwdQ/fk45hg1t5LP4EUxG5d1fdshLbaxCiwh/tszUzDX/4mW40mu2QsbeJJRPBbqUw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.974.20",
- "@aws-sdk/signature-v4-multi-region": "^3.996.34",
- "@aws-sdk/types": "^3.973.12",
+ "@aws-sdk/core": "^3.974.21",
+ "@aws-sdk/signature-v4-multi-region": "^3.996.35",
+ "@aws-sdk/types": "^3.973.13",
"@smithy/core": "^3.24.6",
"@smithy/fetch-http-handler": "^5.4.6",
"@smithy/node-http-handler": "^4.7.6",
@@ -781,13 +781,13 @@
}
},
"node_modules/@aws-sdk/signature-v4-multi-region": {
- "version": "3.996.34",
- "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.996.34.tgz",
- "integrity": "sha512-mx1L5qlumSOt/nKM3BFaHE2HVkWwz0i4Bw0pyYO42FfX/FeLlo8YI6csC0gSPprEk6fTIqI+CZN9RwUwKd5krQ==",
+ "version": "3.996.35",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.996.35.tgz",
+ "integrity": "sha512-6L/VWs+Wch2stHemCGTmUNqKLMzURxQDK5boNG3Jn3kAOp71meDUuS5sbObpEvFxHDq0uWeSLFDNSYsjNt+Dlg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/types": "^3.973.12",
+ "@aws-sdk/types": "^3.973.13",
"@smithy/signature-v4": "^5.4.6",
"@smithy/types": "^4.14.3",
"tslib": "^2.6.2"
@@ -797,15 +797,15 @@
}
},
"node_modules/@aws-sdk/token-providers": {
- "version": "3.1066.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.1066.0.tgz",
- "integrity": "sha512-UqEUJq7dqa44hneLDUcX7UJy95cg8YqEWyakRpvIPnrNS3Mq+UlQHgCDGu5pvwAPtlIW4qcYbvW6reG6++FyvA==",
+ "version": "3.1069.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.1069.0.tgz",
+ "integrity": "sha512-ks4X+kngC3PA5howV7Qu1TgG4bfC4jPykKdvw3nmBSXR9yZxRJouBholFSNQ5kY3L+Fgwyw+LCjzQmNi+KR91g==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.974.20",
- "@aws-sdk/nested-clients": "^3.997.20",
- "@aws-sdk/types": "^3.973.12",
+ "@aws-sdk/core": "^3.974.21",
+ "@aws-sdk/nested-clients": "^3.997.21",
+ "@aws-sdk/types": "^3.973.13",
"@smithy/core": "^3.24.6",
"@smithy/types": "^4.14.3",
"tslib": "^2.6.2"
@@ -815,9 +815,9 @@
}
},
"node_modules/@aws-sdk/types": {
- "version": "3.973.12",
- "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.973.12.tgz",
- "integrity": "sha512-43ajd1NF0RMgX5k0hxCNUyEdrtFUsb2aHT2QvpktSC/2Eyb2Jr/JPVqdp0XIoaHWikZJq5tNWSLO6kB5q2eMCA==",
+ "version": "3.973.13",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.973.13.tgz",
+ "integrity": "sha512-pEHZqRkAlHfnfAU9tK+WpKv/gBNjGJrHMgA3A0iYRGyswBS2t0pfez+lWlwktb3Bqa0ovh7w/QJTFwp3fDxLNg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -829,13 +829,13 @@
}
},
"node_modules/@aws-sdk/util-format-url": {
- "version": "3.972.22",
- "resolved": "https://registry.npmjs.org/@aws-sdk/util-format-url/-/util-format-url-3.972.22.tgz",
- "integrity": "sha512-ygzBtG3xDxvMWTg3EjlZ5FSYxUiRCsCZvKPk+sOhXeMcDTdzPqIGQipiUiIYJm/Om8h8qXyhchMb0baW1PhE+w==",
+ "version": "3.972.23",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/util-format-url/-/util-format-url-3.972.23.tgz",
+ "integrity": "sha512-+KAkQBGX3CSFd7/xs+pz+j+D7rWXj4fviHn+Ykb4T4cfrOJFI3yfy+y+wvZ0vUIhVNy2wEKwFkhk4+tAoMFppw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.974.20",
+ "@aws-sdk/core": "^3.974.21",
"tslib": "^2.6.2"
},
"engines": {
@@ -843,9 +843,9 @@
}
},
"node_modules/@aws-sdk/util-locate-window": {
- "version": "3.965.7",
- "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.965.7.tgz",
- "integrity": "sha512-M0D6oIpohdNHjc7udzTHEQyot0+0iuA36jc2I9Hps+f/GtKi2HO/pyijQnCnNcwZqLB5+rtn81z3eZK/GyjAmA==",
+ "version": "3.965.8",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.965.8.tgz",
+ "integrity": "sha512-uUbMs1cBZPafD0ohUj6EwNf0fPZ534NvBxHox4hjX+0Rxq5paSYUem7+hi833pYrzrcnBATKIYpR02MDXT5M9g==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -866,9 +866,9 @@
}
},
"node_modules/@aws-sdk/xml-builder": {
- "version": "3.972.29",
- "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.29.tgz",
- "integrity": "sha512-fk0niuGFxfi8yIJuMVM4mhwObkiQSuwZFj3tAPrLVx64Pk3BkrEIpqjzHKY4hKoEBUD6Jg/S74Zj9jy+5F3DnQ==",
+ "version": "3.972.30",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.30.tgz",
+ "integrity": "sha512-StElZPEoBquWwNqw1AcfpzEyZqJvFxouG+mpDNYlcH6ZOrqd2CuIryv+8LV8gNHZUOyKyJF3Dq9vxaXEmDR9TQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -2219,39 +2219,39 @@
"license": "MIT"
},
"node_modules/@duckdb/node-api": {
- "version": "1.5.3-r.1",
- "resolved": "https://registry.npmjs.org/@duckdb/node-api/-/node-api-1.5.3-r.1.tgz",
- "integrity": "sha512-Z68b/SfFoECdmVNis708kGoamabox1NezejKyU6bPucoTig8DNTAVKU9R9gT4wl5c5qZ3RUy+jpe6F5Xa6Z3Iw==",
+ "version": "1.5.3-r.3",
+ "resolved": "https://registry.npmjs.org/@duckdb/node-api/-/node-api-1.5.3-r.3.tgz",
+ "integrity": "sha512-FzuL6sevuFfEFwkgiUMRMUAj4TaVqV//L0oo2FVZ9s9oYpLpALF9qZyQv2ucclTNQZwDCkm8+e6yLMc6t8IjlA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@duckdb/node-bindings": "1.5.3-r.1"
+ "@duckdb/node-bindings": "1.5.3-r.3"
}
},
"node_modules/@duckdb/node-bindings": {
- "version": "1.5.3-r.1",
- "resolved": "https://registry.npmjs.org/@duckdb/node-bindings/-/node-bindings-1.5.3-r.1.tgz",
- "integrity": "sha512-vDMuaEFd0JnboKdDw8hSN47OS0u3hw++YCCApPM3uYCFFuIK0RKXTqKe0pTLEMo4IIv3qVJym/rpDhqPLMUEuA==",
+ "version": "1.5.3-r.3",
+ "resolved": "https://registry.npmjs.org/@duckdb/node-bindings/-/node-bindings-1.5.3-r.3.tgz",
+ "integrity": "sha512-Dphw1a9kKXZnCiWX1YCEAJsQ7WJQO2Ikgxy7m8jy0QVXqAwB9esr5NGsuEL3vMKL7velZHeZCjGOMnHZEcIsdg==",
"dev": true,
"license": "MIT",
"dependencies": {
"detect-libc": "^2.1.2"
},
"optionalDependencies": {
- "@duckdb/node-bindings-darwin-arm64": "1.5.3-r.1",
- "@duckdb/node-bindings-darwin-x64": "1.5.3-r.1",
- "@duckdb/node-bindings-linux-arm64": "1.5.3-r.1",
- "@duckdb/node-bindings-linux-arm64-musl": "1.5.3-r.1",
- "@duckdb/node-bindings-linux-x64": "1.5.3-r.1",
- "@duckdb/node-bindings-linux-x64-musl": "1.5.3-r.1",
- "@duckdb/node-bindings-win32-arm64": "1.5.3-r.1",
- "@duckdb/node-bindings-win32-x64": "1.5.3-r.1"
+ "@duckdb/node-bindings-darwin-arm64": "1.5.3-r.3",
+ "@duckdb/node-bindings-darwin-x64": "1.5.3-r.3",
+ "@duckdb/node-bindings-linux-arm64": "1.5.3-r.3",
+ "@duckdb/node-bindings-linux-arm64-musl": "1.5.3-r.3",
+ "@duckdb/node-bindings-linux-x64": "1.5.3-r.3",
+ "@duckdb/node-bindings-linux-x64-musl": "1.5.3-r.3",
+ "@duckdb/node-bindings-win32-arm64": "1.5.3-r.3",
+ "@duckdb/node-bindings-win32-x64": "1.5.3-r.3"
}
},
"node_modules/@duckdb/node-bindings-darwin-arm64": {
- "version": "1.5.3-r.1",
- "resolved": "https://registry.npmjs.org/@duckdb/node-bindings-darwin-arm64/-/node-bindings-darwin-arm64-1.5.3-r.1.tgz",
- "integrity": "sha512-r87Cc/NB3cC6Jfxh4wv/j2N1XUxm/dMoPa6QwdvOsU/KyU3IwDRed5hpAVIxbp7SYXs8IEnws3E/m+toNVZt2A==",
+ "version": "1.5.3-r.3",
+ "resolved": "https://registry.npmjs.org/@duckdb/node-bindings-darwin-arm64/-/node-bindings-darwin-arm64-1.5.3-r.3.tgz",
+ "integrity": "sha512-ttD8QBesgzHu7Sc4qouuIGLM7PWedLW8GvFbnZEyMqk24mQz1HWFgaT0ivw6nDRaDPUQLB9QnAOq8MZUh1zWHQ==",
"cpu": [
"arm64"
],
@@ -2263,9 +2263,9 @@
]
},
"node_modules/@duckdb/node-bindings-darwin-x64": {
- "version": "1.5.3-r.1",
- "resolved": "https://registry.npmjs.org/@duckdb/node-bindings-darwin-x64/-/node-bindings-darwin-x64-1.5.3-r.1.tgz",
- "integrity": "sha512-S/8JXK2OR5fzSKvWdpdOuLCuzv+TUxnhLxA8twXYEC09GqimW6DIdvLquOVuykvfbBpoImz8UJpA+zOIpqlHEQ==",
+ "version": "1.5.3-r.3",
+ "resolved": "https://registry.npmjs.org/@duckdb/node-bindings-darwin-x64/-/node-bindings-darwin-x64-1.5.3-r.3.tgz",
+ "integrity": "sha512-Vp9MYtoYf6zUWHdCmHXwUcJlHq3YaaIeULWeSiPUM1hsDflLiZKXtz5i250Ulz03VsfWBjpO4wdM99sjjrYKkg==",
"cpu": [
"x64"
],
@@ -2277,9 +2277,9 @@
]
},
"node_modules/@duckdb/node-bindings-linux-arm64": {
- "version": "1.5.3-r.1",
- "resolved": "https://registry.npmjs.org/@duckdb/node-bindings-linux-arm64/-/node-bindings-linux-arm64-1.5.3-r.1.tgz",
- "integrity": "sha512-bpa3d42iGTOZ2YOviUA/PGT/GGnnkmPR5W2hccAPEgfN2Doz1A7A5T899K9TIVCkdxwr7Xxoa7CiqMgzPgxdJg==",
+ "version": "1.5.3-r.3",
+ "resolved": "https://registry.npmjs.org/@duckdb/node-bindings-linux-arm64/-/node-bindings-linux-arm64-1.5.3-r.3.tgz",
+ "integrity": "sha512-3HLcrzQE83947JS51UVR7C9qnXQMltCOk4Dnhiz1CD+9u32DGLMgPTIIxclk7O+Q7EwfqzD8JV86Ud+LT1crcQ==",
"cpu": [
"arm64"
],
@@ -2294,9 +2294,9 @@
]
},
"node_modules/@duckdb/node-bindings-linux-arm64-musl": {
- "version": "1.5.3-r.1",
- "resolved": "https://registry.npmjs.org/@duckdb/node-bindings-linux-arm64-musl/-/node-bindings-linux-arm64-musl-1.5.3-r.1.tgz",
- "integrity": "sha512-gNcmx+ChrGW5Ykc446mV4P+IgaEDq8fO7Y8aYeGA+XRIdy2fpZCsjo99Vv5zUKlY0IuvGwM0WFUF03oA0KksBQ==",
+ "version": "1.5.3-r.3",
+ "resolved": "https://registry.npmjs.org/@duckdb/node-bindings-linux-arm64-musl/-/node-bindings-linux-arm64-musl-1.5.3-r.3.tgz",
+ "integrity": "sha512-IadRyx+98FEynKLXAk2MzReinFgduiDXgNd5Z8c5VKch+8FgBfqkEUYGOnBMMUPT8kuheKdLj23vpWXaCzOgoQ==",
"cpu": [
"arm64"
],
@@ -2311,9 +2311,9 @@
]
},
"node_modules/@duckdb/node-bindings-linux-x64": {
- "version": "1.5.3-r.1",
- "resolved": "https://registry.npmjs.org/@duckdb/node-bindings-linux-x64/-/node-bindings-linux-x64-1.5.3-r.1.tgz",
- "integrity": "sha512-gCuxN9jabTJVJnYq59n0ba5AR1nix17v5OT3VXNzx/iZldX1MH5Gihp8of7OTaQILGuZ+APqCASL3s5fBgrqFg==",
+ "version": "1.5.3-r.3",
+ "resolved": "https://registry.npmjs.org/@duckdb/node-bindings-linux-x64/-/node-bindings-linux-x64-1.5.3-r.3.tgz",
+ "integrity": "sha512-TXndAL0ZoETq17Df6wB+SUZjLGDmOsKuDSySxB+wy6sHfpRtbDgQibyXRlajVeUkRDwSzBFC5ymy16YG0Fl4iw==",
"cpu": [
"x64"
],
@@ -2328,9 +2328,9 @@
]
},
"node_modules/@duckdb/node-bindings-linux-x64-musl": {
- "version": "1.5.3-r.1",
- "resolved": "https://registry.npmjs.org/@duckdb/node-bindings-linux-x64-musl/-/node-bindings-linux-x64-musl-1.5.3-r.1.tgz",
- "integrity": "sha512-ZVEofh6i8RKbbnAYJvU+/BatDW2tR3ee4Uvcm5b7lz53FWXsCyqh5Kh8LBRuUBq5rurOoWmrVry/g1i7wBZgjg==",
+ "version": "1.5.3-r.3",
+ "resolved": "https://registry.npmjs.org/@duckdb/node-bindings-linux-x64-musl/-/node-bindings-linux-x64-musl-1.5.3-r.3.tgz",
+ "integrity": "sha512-5bulS16YhftXcarki4tvCufVslntpQDLOEF6RZ+FSMOGiv5d7SDXqklmVRy4DKW3C5ekgN7S2oYzuGL/ss9BuA==",
"cpu": [
"x64"
],
@@ -2345,9 +2345,9 @@
]
},
"node_modules/@duckdb/node-bindings-win32-arm64": {
- "version": "1.5.3-r.1",
- "resolved": "https://registry.npmjs.org/@duckdb/node-bindings-win32-arm64/-/node-bindings-win32-arm64-1.5.3-r.1.tgz",
- "integrity": "sha512-RHEfClLwLZo/aZrBKZn9ugZEnlB8ucnM61T+B9tYKCsz5RT29ueVVzyTLvuHemc5W3cZPki8xsohno8Txl6qeQ==",
+ "version": "1.5.3-r.3",
+ "resolved": "https://registry.npmjs.org/@duckdb/node-bindings-win32-arm64/-/node-bindings-win32-arm64-1.5.3-r.3.tgz",
+ "integrity": "sha512-55Vu13S0jUudiAGlNWJd7UvlW1iKjwWehD8s93jBCNm0AdE/EJN4nz5rQ0IuWzPWXpMjAYuKu00yE7NdtbTyug==",
"cpu": [
"arm64"
],
@@ -2359,9 +2359,9 @@
]
},
"node_modules/@duckdb/node-bindings-win32-x64": {
- "version": "1.5.3-r.1",
- "resolved": "https://registry.npmjs.org/@duckdb/node-bindings-win32-x64/-/node-bindings-win32-x64-1.5.3-r.1.tgz",
- "integrity": "sha512-Ff6lenczCvN9g/3hjBKkn/bZe2DwxUOVrC+eNYZnqdSHcpGP6K4knV7eWIjEkOC5cZoki+Cwd822L3ivt22/5Q==",
+ "version": "1.5.3-r.3",
+ "resolved": "https://registry.npmjs.org/@duckdb/node-bindings-win32-x64/-/node-bindings-win32-x64-1.5.3-r.3.tgz",
+ "integrity": "sha512-rlOc9ltWQNHuDq99Ah8XaD80nN1ucrSK5AcH/7ibSp9ogX/jswPYlRVE7ODFJAjnQNf8bVvs++Mp+wyGvuG7ag==",
"cpu": [
"x64"
],
@@ -4379,14 +4379,14 @@
}
},
"node_modules/@smithy/core": {
- "version": "3.24.7",
- "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.24.7.tgz",
- "integrity": "sha512-KoUi4M1f3BG6kzN1FnCwL7oyFptTbyBJKjR6yhSib+JHRdUmM1o+VwsFtJ66NZCkCzVfJMWRHJNo0R0jznp0Pg==",
+ "version": "3.25.0",
+ "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.25.0.tgz",
+ "integrity": "sha512-TTD6el7tvKyafkXBf7XO3jLOE+qVxOTrLjp/fEGiV3BMfUHK/LfdYlQO9YgZvzxC7kqA3H/IhJXNqQgnbgjb7A==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/crc32": "5.2.0",
- "@smithy/types": "^4.14.4",
+ "@smithy/types": "^4.15.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -4394,14 +4394,14 @@
}
},
"node_modules/@smithy/credential-provider-imds": {
- "version": "4.3.9",
- "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.3.9.tgz",
- "integrity": "sha512-ZlfJ/4Fa3jYb+3eaohPfG9utX9HmdhFNcFtpoGAhUhdynAOmGXtmigbi7eEiONKM+ykHw8RwKuDEb85Lx7t7fA==",
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.4.0.tgz",
+ "integrity": "sha512-pPQmNdEvMJttv9z2kdYxoui83p/nr32zjMf0aMfmzmGmFEgKXUfy0vXiNg0fx4R5XLQzmJBLM9Wg0guEq2/q8A==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@smithy/core": "^3.24.7",
- "@smithy/types": "^4.14.4",
+ "@smithy/core": "^3.25.0",
+ "@smithy/types": "^4.15.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -4409,14 +4409,14 @@
}
},
"node_modules/@smithy/fetch-http-handler": {
- "version": "5.4.7",
- "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.4.7.tgz",
- "integrity": "sha512-NslaM2ir0N2hisDmzXLstPaVINZheh8SokyOC++kzFPloZucL2R7Y7bS57mSzx/1Fc/fqmn7twjkeezTTrV0EA==",
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.5.0.tgz",
+ "integrity": "sha512-OG8kBYAgX7lf32+xLzgirvuLffn1KNoszaSiButt45i2cRa5irk8LQXLYQ5Smij1SBTN4KMNcBsRwRrLPfIGyA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@smithy/core": "^3.24.7",
- "@smithy/types": "^4.14.4",
+ "@smithy/core": "^3.25.0",
+ "@smithy/types": "^4.15.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -4437,14 +4437,14 @@
}
},
"node_modules/@smithy/node-http-handler": {
- "version": "4.7.8",
- "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.7.8.tgz",
- "integrity": "sha512-f+DbsWUwSbtMu1a/j8Y93KiU1SRg9nyzfjereqn1BJ33QOTUXxdlYvVXMhAYl1vuR1Kmna5aIJe09KSIfyFNYw==",
+ "version": "4.8.0",
+ "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.8.0.tgz",
+ "integrity": "sha512-Mq7TNt/VhlEWiYRLQGpzUWeUxh899UGpjKh7Ru0WVIDIjnE+cTRAn0NYlFQ6bWfsQnKnpCbWJj86HzmcG0qEdg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@smithy/core": "^3.24.7",
- "@smithy/types": "^4.14.4",
+ "@smithy/core": "^3.25.0",
+ "@smithy/types": "^4.15.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -4452,14 +4452,14 @@
}
},
"node_modules/@smithy/signature-v4": {
- "version": "5.4.7",
- "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.4.7.tgz",
- "integrity": "sha512-LwQZazFayImv+IOm0S0enoLeUJwmAlhGC5O6YCcLWezyu08dF46GOxPOq35OpBIHkgd7OvNvBStIFwVNyrvoBw==",
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.5.0.tgz",
+ "integrity": "sha512-vW6UdK7e7gV2wU/tXRsPq4pMQMusb8VymdVOyIFNA1FtyRmEClRFkYDtYI8UcO/HM0wK3qqjvvQs3HOlbgMbdg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@smithy/core": "^3.24.7",
- "@smithy/types": "^4.14.4",
+ "@smithy/core": "^3.25.0",
+ "@smithy/types": "^4.15.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -4467,9 +4467,9 @@
}
},
"node_modules/@smithy/types": {
- "version": "4.14.4",
- "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.14.4.tgz",
- "integrity": "sha512-B2S9+UGm1+/pHkcx3ZoLVX1a+pmSk8rqxRR+ZsNqZaJ5q9FWX9AFGQVM4qG5+OBeQUZVy99HY8HqW8gK/wgXzQ==",
+ "version": "4.15.0",
+ "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.15.0.tgz",
+ "integrity": "sha512-Z5TAOxygoFvybJV3igo5SloFflSokHx2hu1eFA+DxDTcn+FtKxUSui+rbTRG1pAafMA888Z3MVvCWUuvCrTXjg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -5737,9 +5737,9 @@
}
},
"node_modules/cheerio/node_modules/undici": {
- "version": "7.27.2",
- "resolved": "https://registry.npmjs.org/undici/-/undici-7.27.2.tgz",
- "integrity": "sha512-uZsKNuzQxDMUY6M3pIMvy5tvlGmtq8XJ2oLAkfRKGNu+1VQAIvLy2xIVG5ATZl5wDXl/tddByAWCizRbOme+TA==",
+ "version": "7.28.0",
+ "resolved": "https://registry.npmjs.org/undici/-/undici-7.28.0.tgz",
+ "integrity": "sha512-cRZYrTDwWznlnRiPjggAGxZXanty6M8RV1ff8Wm4LWXBp7/IG8v5DnOm74DtUBp9OONpK75YlPnIjQqX0dBDtA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -10344,9 +10344,9 @@
"license": "MIT"
},
"node_modules/undici": {
- "version": "8.4.1",
- "resolved": "https://registry.npmjs.org/undici/-/undici-8.4.1.tgz",
- "integrity": "sha512-RNHlB4fxZK0IrkhBsxhlbx7s8kFWwr7rzzOqj5nvZugw3ig3RsB7KW3zVlV0eu8POl+rx5d1hmL7rRg0z1owow==",
+ "version": "8.5.0",
+ "resolved": "https://registry.npmjs.org/undici/-/undici-8.5.0.tgz",
+ "integrity": "sha512-xamtWoB1EshgjpmlXd7GGm2VfdDtw1+rD8uhry8pSNW3If6S8E0m2T2+orSKeZXEn/aPJMviCpDBA65WJt8zhg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -11491,9 +11491,9 @@
"license": "ISC"
},
"node_modules/ws": {
- "version": "8.20.1",
- "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.1.tgz",
- "integrity": "sha512-It4dO0K5v//JtTXuPkfEOaI3uUN87iYPnqo/ZzqCoG3g8uhA66QUMs/SrM0YK7/NAu+r4LMh/9dq2A7k+rHs+w==",
+ "version": "8.21.0",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz",
+ "integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==",
"dev": true,
"license": "MIT",
"engines": {
@@ -11817,7 +11817,7 @@
"devDependencies": {
"@datastream/arrow": "0.6.0",
"@duckdb/duckdb-wasm": "1.33.1-dev45.0",
- "@duckdb/node-api": "1.5.3-r.1",
+ "@duckdb/node-api": "1.5.3-r.3",
"apache-arrow": "21.1.0"
},
"engines": {
diff --git a/package.json b/package.json
index 1352db4..d6b8610 100644
--- a/package.json
+++ b/package.json
@@ -93,6 +93,9 @@
},
"license-check-and-add": {
"minimatch": "^10.2.5"
+ },
+ "miniflare": {
+ "ws": "^8.21.0"
}
},
"workspaces": [
diff --git a/packages/duckdb/package.json b/packages/duckdb/package.json
index ad768e9..70992d9 100644
--- a/packages/duckdb/package.json
+++ b/packages/duckdb/package.json
@@ -85,7 +85,7 @@
"devDependencies": {
"@datastream/arrow": "0.6.0",
"@duckdb/duckdb-wasm": "1.33.1-dev45.0",
- "@duckdb/node-api": "1.5.3-r.1",
+ "@duckdb/node-api": "1.5.3-r.3",
"apache-arrow": "21.1.0"
}
}
From 973c402f2427255fa529d45324f704660b41ab72 Mon Sep 17 00:00:00 2001
From: will Farrell
Date: Mon, 15 Jun 2026 15:52:43 -0600
Subject: [PATCH 21/27] chore: dep update
Signed-off-by: will Farrell
---
package-lock.json | 535 +---------------------------------------------
package.json | 11 +-
2 files changed, 13 insertions(+), 533 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index d8d59cf..b989f9a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -4976,30 +4976,6 @@
"node": ">=18.12.0"
}
},
- "node_modules/@yarnpkg/parsers/node_modules/argparse": {
- "version": "1.0.10",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
- "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "sprintf-js": "~1.0.2"
- }
- },
- "node_modules/@yarnpkg/parsers/node_modules/js-yaml": {
- "version": "3.14.2",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz",
- "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "argparse": "^1.0.7",
- "esprima": "^4.0.0"
- },
- "bin": {
- "js-yaml": "bin/js-yaml.js"
- }
- },
"node_modules/abbrev": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz",
@@ -6558,20 +6534,6 @@
"integrity": "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==",
"license": "MIT"
},
- "node_modules/esprima": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
- "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
- "dev": true,
- "license": "BSD-2-Clause",
- "bin": {
- "esparse": "bin/esparse.js",
- "esvalidate": "bin/esvalidate.js"
- },
- "engines": {
- "node": ">=4"
- }
- },
"node_modules/esrap": {
"version": "2.2.11",
"resolved": "https://registry.npmjs.org/esrap/-/esrap-2.2.11.tgz",
@@ -9308,9 +9270,9 @@
"license": "MIT"
},
"node_modules/qs": {
- "version": "6.15.2",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.2.tgz",
- "integrity": "sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw==",
+ "version": "6.15.1",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.1.tgz",
+ "integrity": "sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
@@ -9862,13 +9824,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/sprintf-js": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
- "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
- "dev": true,
- "license": "BSD-3-Clause"
- },
"node_modules/stream-browserify": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz",
@@ -10882,490 +10837,6 @@
}
}
},
- "node_modules/wrangler/node_modules/@esbuild/aix-ppc64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz",
- "integrity": "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==",
- "cpu": [
- "ppc64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "aix"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/wrangler/node_modules/@esbuild/android-arm": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.3.tgz",
- "integrity": "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/wrangler/node_modules/@esbuild/android-arm64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz",
- "integrity": "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/wrangler/node_modules/@esbuild/android-x64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.3.tgz",
- "integrity": "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/wrangler/node_modules/@esbuild/darwin-arm64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz",
- "integrity": "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/wrangler/node_modules/@esbuild/darwin-x64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz",
- "integrity": "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/wrangler/node_modules/@esbuild/freebsd-arm64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz",
- "integrity": "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/wrangler/node_modules/@esbuild/freebsd-x64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz",
- "integrity": "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/wrangler/node_modules/@esbuild/linux-arm": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz",
- "integrity": "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/wrangler/node_modules/@esbuild/linux-arm64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.3.tgz",
- "integrity": "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/wrangler/node_modules/@esbuild/linux-ia32": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz",
- "integrity": "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/wrangler/node_modules/@esbuild/linux-loong64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz",
- "integrity": "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==",
- "cpu": [
- "loong64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/wrangler/node_modules/@esbuild/linux-mips64el": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz",
- "integrity": "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==",
- "cpu": [
- "mips64el"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/wrangler/node_modules/@esbuild/linux-ppc64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz",
- "integrity": "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==",
- "cpu": [
- "ppc64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/wrangler/node_modules/@esbuild/linux-riscv64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz",
- "integrity": "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==",
- "cpu": [
- "riscv64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/wrangler/node_modules/@esbuild/linux-s390x": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz",
- "integrity": "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==",
- "cpu": [
- "s390x"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/wrangler/node_modules/@esbuild/linux-x64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz",
- "integrity": "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/wrangler/node_modules/@esbuild/netbsd-arm64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz",
- "integrity": "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "netbsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/wrangler/node_modules/@esbuild/netbsd-x64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz",
- "integrity": "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "netbsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/wrangler/node_modules/@esbuild/openbsd-arm64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz",
- "integrity": "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "openbsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/wrangler/node_modules/@esbuild/openbsd-x64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz",
- "integrity": "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "openbsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/wrangler/node_modules/@esbuild/openharmony-arm64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz",
- "integrity": "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "openharmony"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/wrangler/node_modules/@esbuild/sunos-x64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz",
- "integrity": "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "sunos"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/wrangler/node_modules/@esbuild/win32-arm64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz",
- "integrity": "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/wrangler/node_modules/@esbuild/win32-ia32": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz",
- "integrity": "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/wrangler/node_modules/@esbuild/win32-x64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz",
- "integrity": "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/wrangler/node_modules/esbuild": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz",
- "integrity": "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==",
- "dev": true,
- "hasInstallScript": true,
- "license": "MIT",
- "bin": {
- "esbuild": "bin/esbuild"
- },
- "engines": {
- "node": ">=18"
- },
- "optionalDependencies": {
- "@esbuild/aix-ppc64": "0.27.3",
- "@esbuild/android-arm": "0.27.3",
- "@esbuild/android-arm64": "0.27.3",
- "@esbuild/android-x64": "0.27.3",
- "@esbuild/darwin-arm64": "0.27.3",
- "@esbuild/darwin-x64": "0.27.3",
- "@esbuild/freebsd-arm64": "0.27.3",
- "@esbuild/freebsd-x64": "0.27.3",
- "@esbuild/linux-arm": "0.27.3",
- "@esbuild/linux-arm64": "0.27.3",
- "@esbuild/linux-ia32": "0.27.3",
- "@esbuild/linux-loong64": "0.27.3",
- "@esbuild/linux-mips64el": "0.27.3",
- "@esbuild/linux-ppc64": "0.27.3",
- "@esbuild/linux-riscv64": "0.27.3",
- "@esbuild/linux-s390x": "0.27.3",
- "@esbuild/linux-x64": "0.27.3",
- "@esbuild/netbsd-arm64": "0.27.3",
- "@esbuild/netbsd-x64": "0.27.3",
- "@esbuild/openbsd-arm64": "0.27.3",
- "@esbuild/openbsd-x64": "0.27.3",
- "@esbuild/openharmony-arm64": "0.27.3",
- "@esbuild/sunos-x64": "0.27.3",
- "@esbuild/win32-arm64": "0.27.3",
- "@esbuild/win32-ia32": "0.27.3",
- "@esbuild/win32-x64": "0.27.3"
- }
- },
"node_modules/wrangler/node_modules/path-to-regexp": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz",
diff --git a/package.json b/package.json
index d6b8610..3eab432 100644
--- a/package.json
+++ b/package.json
@@ -84,7 +84,6 @@
"tstyche": "^7.2.0"
},
"overrides": {
- "qs": "^6.15.2",
"@sveltejs/kit": {
"cookie": "^0.7.2"
},
@@ -94,8 +93,18 @@
"license-check-and-add": {
"minimatch": "^10.2.5"
},
+ "lockfile-lint": {
+ "lockfile-lint-api": {
+ "@yarnpkg/parsers": {
+ "js-yaml": ">=4.2.0"
+ }
+ }
+ },
"miniflare": {
"ws": "^8.21.0"
+ },
+ "wrangler": {
+ "esbuild": ">=0.28.1"
}
},
"workspaces": [
From 69b3e3453ce4bbee5bd8d51933ac13fe3be756af Mon Sep 17 00:00:00 2001
From: will Farrell
Date: Mon, 15 Jun 2026 17:59:29 -0600
Subject: [PATCH 22/27] chore: dep update
Signed-off-by: will Farrell
---
package-lock.json | 6 +++---
package.json | 1 +
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index b989f9a..5849c0b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9270,9 +9270,9 @@
"license": "MIT"
},
"node_modules/qs": {
- "version": "6.15.1",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.1.tgz",
- "integrity": "sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==",
+ "version": "6.15.2",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.2.tgz",
+ "integrity": "sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
diff --git a/package.json b/package.json
index 3eab432..d1e58b6 100644
--- a/package.json
+++ b/package.json
@@ -84,6 +84,7 @@
"tstyche": "^7.2.0"
},
"overrides": {
+ "qs": "^6.15.2",
"@sveltejs/kit": {
"cookie": "^0.7.2"
},
From 98562c7761db048f933b185fa297f859f3d7861f Mon Sep 17 00:00:00 2001
From: will Farrell
Date: Sat, 11 Jul 2026 09:04:10 -0600
Subject: [PATCH 23/27] feat: update tardisec config
Signed-off-by: will Farrell
---
package-lock.json | 2475 +++++++++--------
websites/datastream.js.org/.tardisec.json | 35 +
.../.tardisec.sveltekit.json | 37 +
.../src/hooks/tardisecMiddleware.js | 11 +-
.../datastream.js.org/src/styles/below.css | 2 +-
websites/datastream.js.org/svelte.config.js | 22 +-
6 files changed, 1395 insertions(+), 1187 deletions(-)
create mode 100644 websites/datastream.js.org/.tardisec.json
create mode 100644 websites/datastream.js.org/.tardisec.sveltekit.json
diff --git a/package-lock.json b/package-lock.json
index 5849c0b..05f4387 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -55,115 +55,55 @@
"@types/json-schema": "^7.0.15"
}
},
- "node_modules/@aws-crypto/crc32": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-5.2.0.tgz",
- "integrity": "sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@aws-crypto/util": "^5.2.0",
- "@aws-sdk/types": "^3.222.0",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@aws-crypto/crc32c": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/@aws-crypto/crc32c/-/crc32c-5.2.0.tgz",
- "integrity": "sha512-+iWb8qaHLYKrNvGRbiYRHSdKRWhto5XlZUEBwDjYNf+ly5SVYG6zEoYIdxvf5R3zyeP16w4PLBn3rH1xc74Rag==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@aws-crypto/util": "^5.2.0",
- "@aws-sdk/types": "^3.222.0",
- "tslib": "^2.6.2"
- }
- },
- "node_modules/@aws-crypto/sha1-browser": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/@aws-crypto/sha1-browser/-/sha1-browser-5.2.0.tgz",
- "integrity": "sha512-OH6lveCFfcDjX4dbAvCFSYUjJZjDr/3XJ3xHtjn3Oj5b9RjojQo8npoLeA/bNwkOkrSQ0wgrHzXk4tDRxGKJeg==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@aws-crypto/supports-web-crypto": "^5.2.0",
- "@aws-crypto/util": "^5.2.0",
- "@aws-sdk/types": "^3.222.0",
- "@aws-sdk/util-locate-window": "^3.0.0",
- "@smithy/util-utf8": "^2.0.0",
- "tslib": "^2.6.2"
- }
- },
- "node_modules/@aws-crypto/sha256-browser": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz",
- "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@aws-crypto/sha256-js": "^5.2.0",
- "@aws-crypto/supports-web-crypto": "^5.2.0",
- "@aws-crypto/util": "^5.2.0",
- "@aws-sdk/types": "^3.222.0",
- "@aws-sdk/util-locate-window": "^3.0.0",
- "@smithy/util-utf8": "^2.0.0",
- "tslib": "^2.6.2"
- }
- },
"node_modules/@aws-crypto/sha256-js": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz",
- "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-4.0.0.tgz",
+ "integrity": "sha512-MHGJyjE7TX9aaqXj7zk2ppnFUOhaDs5sP+HtNS0evOxn72c+5njUmyJmpGd7TfyoDznZlHMmdo/xGUdu2NIjNQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-crypto/util": "^5.2.0",
+ "@aws-crypto/util": "^4.0.0",
"@aws-sdk/types": "^3.222.0",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
+ "tslib": "^1.11.1"
}
},
- "node_modules/@aws-crypto/supports-web-crypto": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-5.2.0.tgz",
- "integrity": "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==",
+ "node_modules/@aws-crypto/sha256-js/node_modules/tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
"dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "tslib": "^2.6.2"
- }
+ "license": "0BSD"
},
"node_modules/@aws-crypto/util": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz",
- "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-4.0.0.tgz",
+ "integrity": "sha512-2EnmPy2gsFZ6m8bwUQN4jq+IyXV3quHAcwPOS6ZA3k+geujiqI8aRokO2kFJe+idJ/P3v4qWI186rVMo0+zLDQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-sdk/types": "^3.222.0",
- "@smithy/util-utf8": "^2.0.0",
- "tslib": "^2.6.2"
+ "@aws-sdk/util-utf8-browser": "^3.0.0",
+ "tslib": "^1.11.1"
}
},
+ "node_modules/@aws-crypto/util/node_modules/tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
+ "dev": true,
+ "license": "0BSD"
+ },
"node_modules/@aws-sdk/checksums": {
- "version": "3.1000.6",
- "resolved": "https://registry.npmjs.org/@aws-sdk/checksums/-/checksums-3.1000.6.tgz",
- "integrity": "sha512-RMCrCteiUwYTEv2G9zfP/BEuKHv57665vVieJyp9cf8VgilWxP/KrWVtMdfdDlIH8nFhvu3rIMc29z3ebGEZ1w==",
+ "version": "3.1000.16",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/checksums/-/checksums-3.1000.16.tgz",
+ "integrity": "sha512-EKnvkXSmz3IpA99tCNuI+dLFXyZyClSm8zns9sB/elvkU+MTuomAs6toJMPMBf98/fICG/urXDkzGz0/c3yyAQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-crypto/crc32": "5.2.0",
- "@aws-crypto/crc32c": "5.2.0",
- "@aws-crypto/util": "5.2.0",
- "@aws-sdk/core": "^3.974.21",
- "@aws-sdk/types": "^3.973.13",
- "@smithy/core": "^3.24.6",
- "@smithy/types": "^4.14.3",
+ "@aws-sdk/core": "^3.975.1",
+ "@aws-sdk/types": "^3.974.0",
+ "@smithy/core": "^3.29.2",
+ "@smithy/types": "^4.16.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -171,21 +111,19 @@
}
},
"node_modules/@aws-sdk/client-cloudwatch-logs": {
- "version": "3.1069.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudwatch-logs/-/client-cloudwatch-logs-3.1069.0.tgz",
- "integrity": "sha512-cfATk797z1U+oQ4ti486xjBbz7pFOMfMfGw87Zi4TIavaos3cOIHR9V4POD33JM49H1BeiaP1WYRahZJqFVvQg==",
+ "version": "3.1085.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudwatch-logs/-/client-cloudwatch-logs-3.1085.0.tgz",
+ "integrity": "sha512-jNMt5zMsnJ6X0fZJKKNU5/qTQ98OIsUSFLqDh+FTXQTiEI3NTq95gAdsaAwXVWO9hTaT5gY7fbwF5Ally69bwg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-crypto/sha256-browser": "5.2.0",
- "@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.974.21",
- "@aws-sdk/credential-provider-node": "^3.972.56",
- "@aws-sdk/types": "^3.973.13",
- "@smithy/core": "^3.24.6",
- "@smithy/fetch-http-handler": "^5.4.6",
- "@smithy/node-http-handler": "^4.7.6",
- "@smithy/types": "^4.14.3",
+ "@aws-sdk/core": "^3.975.1",
+ "@aws-sdk/credential-provider-node": "^3.972.66",
+ "@aws-sdk/types": "^3.974.0",
+ "@smithy/core": "^3.29.2",
+ "@smithy/fetch-http-handler": "^5.6.4",
+ "@smithy/node-http-handler": "^4.9.4",
+ "@smithy/types": "^4.16.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -193,21 +131,19 @@
}
},
"node_modules/@aws-sdk/client-cognito-identity": {
- "version": "3.1069.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.1069.0.tgz",
- "integrity": "sha512-2otjCOXhvw3ZbV8JGHn+4ztdn8J5DJ/nvP3ZIIBANPD69BU+5RhJnSbA+tPk3S7LJpEep6DJHWQ8ZJn40tCixg==",
+ "version": "3.1081.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.1081.0.tgz",
+ "integrity": "sha512-ipDgvZ3Hy8kaFrkwj62yuoghKkZi5WrWTiJnaqGc/ntbuAuijIkRWhzSb8d1MGEE+qb+vFFTrWVFwGSqt76TCA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-crypto/sha256-browser": "5.2.0",
- "@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.974.21",
- "@aws-sdk/credential-provider-node": "^3.972.56",
- "@aws-sdk/types": "^3.973.13",
- "@smithy/core": "^3.24.6",
- "@smithy/fetch-http-handler": "^5.4.6",
- "@smithy/node-http-handler": "^4.7.6",
- "@smithy/types": "^4.14.3",
+ "@aws-sdk/core": "^3.974.29",
+ "@aws-sdk/credential-provider-node": "^3.972.64",
+ "@aws-sdk/types": "^3.973.15",
+ "@smithy/core": "^3.29.0",
+ "@smithy/fetch-http-handler": "^5.6.2",
+ "@smithy/node-http-handler": "^4.9.2",
+ "@smithy/types": "^4.15.1",
"tslib": "^2.6.2"
},
"engines": {
@@ -215,23 +151,21 @@
}
},
"node_modules/@aws-sdk/client-dynamodb": {
- "version": "3.1069.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-dynamodb/-/client-dynamodb-3.1069.0.tgz",
- "integrity": "sha512-cVnKUba/cdaFfslzw2+IAZGwna8mG0A5yFBELUQ6j7L/vqzEcW7l17ogkCmXhIcsoYAO8WA25c82Tgjet0Fpdw==",
+ "version": "3.1085.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-dynamodb/-/client-dynamodb-3.1085.0.tgz",
+ "integrity": "sha512-EpEFvJm+YjrCeDeXTQcbvk2zviLhKxM7exEiuAXXs4QT6h8HemeMY3gxF0S4gScjzhu3VdDXjLLnlJczIj/49w==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-crypto/sha256-browser": "5.2.0",
- "@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.974.21",
- "@aws-sdk/credential-provider-node": "^3.972.56",
- "@aws-sdk/dynamodb-codec": "^3.973.21",
- "@aws-sdk/middleware-endpoint-discovery": "^3.972.19",
- "@aws-sdk/types": "^3.973.13",
- "@smithy/core": "^3.24.6",
- "@smithy/fetch-http-handler": "^5.4.6",
- "@smithy/node-http-handler": "^4.7.6",
- "@smithy/types": "^4.14.3",
+ "@aws-sdk/core": "^3.975.1",
+ "@aws-sdk/credential-provider-node": "^3.972.66",
+ "@aws-sdk/dynamodb-codec": "^3.973.31",
+ "@aws-sdk/middleware-endpoint-discovery": "^3.972.23",
+ "@aws-sdk/types": "^3.974.0",
+ "@smithy/core": "^3.29.2",
+ "@smithy/fetch-http-handler": "^5.6.4",
+ "@smithy/node-http-handler": "^4.9.4",
+ "@smithy/types": "^4.16.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -239,21 +173,19 @@
}
},
"node_modules/@aws-sdk/client-dynamodb-streams": {
- "version": "3.1069.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-dynamodb-streams/-/client-dynamodb-streams-3.1069.0.tgz",
- "integrity": "sha512-w3fPJsb8ejGO34xrdET0MznR54EY0MBroRvxtBnt6fUSnMESr7/vLnuTyvZeAArfxlRcOBgqWy1Etirf6Na6VA==",
+ "version": "3.1085.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-dynamodb-streams/-/client-dynamodb-streams-3.1085.0.tgz",
+ "integrity": "sha512-sZ3SeswHhzwZzg+EN9fd3P4sAcm3O5lgrVYm8zWu+pGQXZnPpHf6uxjLNgK18l9fUQMPP1FtR50ZBGEfi2yvGw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-crypto/sha256-browser": "5.2.0",
- "@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.974.21",
- "@aws-sdk/credential-provider-node": "^3.972.56",
- "@aws-sdk/types": "^3.973.13",
- "@smithy/core": "^3.24.6",
- "@smithy/fetch-http-handler": "^5.4.6",
- "@smithy/node-http-handler": "^4.7.6",
- "@smithy/types": "^4.14.3",
+ "@aws-sdk/core": "^3.975.1",
+ "@aws-sdk/credential-provider-node": "^3.972.66",
+ "@aws-sdk/types": "^3.974.0",
+ "@smithy/core": "^3.29.2",
+ "@smithy/fetch-http-handler": "^5.6.4",
+ "@smithy/node-http-handler": "^4.9.4",
+ "@smithy/types": "^4.16.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -261,21 +193,19 @@
}
},
"node_modules/@aws-sdk/client-glue": {
- "version": "3.1069.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-glue/-/client-glue-3.1069.0.tgz",
- "integrity": "sha512-OY6jQlYGmDalvl7ljluyEtf3xlsvKbO9zi7oDQTb/UOPSDPVWXmHNQ2O0nr+9amuWqkoig/A3B1OqHaaB4knIw==",
+ "version": "3.1085.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-glue/-/client-glue-3.1085.0.tgz",
+ "integrity": "sha512-D/PpbHZbEpaR6wH7Ss/BbqQwXMH5nPEfnb1wB+bgqWdYMHP7aLhwJNI81Lq/CwbiypZKTu+iX/ZdrHgK+kb7jA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-crypto/sha256-browser": "5.2.0",
- "@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.974.21",
- "@aws-sdk/credential-provider-node": "^3.972.56",
- "@aws-sdk/types": "^3.973.13",
- "@smithy/core": "^3.24.6",
- "@smithy/fetch-http-handler": "^5.4.6",
- "@smithy/node-http-handler": "^4.7.6",
- "@smithy/types": "^4.14.3",
+ "@aws-sdk/core": "^3.975.1",
+ "@aws-sdk/credential-provider-node": "^3.972.66",
+ "@aws-sdk/types": "^3.974.0",
+ "@smithy/core": "^3.29.2",
+ "@smithy/fetch-http-handler": "^5.6.4",
+ "@smithy/node-http-handler": "^4.9.4",
+ "@smithy/types": "^4.16.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -283,21 +213,19 @@
}
},
"node_modules/@aws-sdk/client-kinesis": {
- "version": "3.1069.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-kinesis/-/client-kinesis-3.1069.0.tgz",
- "integrity": "sha512-0p58wlFSVZRgm3J/aoBLoe0It6C+wqGxJkGnZaODY3TQBR7dBkZ12ULaIy6+zH6xXceqH6tuP5Cn2PuSR2avFw==",
+ "version": "3.1085.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-kinesis/-/client-kinesis-3.1085.0.tgz",
+ "integrity": "sha512-Q+JQhmBMlndSST/ZBkgbBqwPX4WuaWWWvBbOZt5L9K0wvsh8y6jAI75qx5gxVz155zEyNIzbfgZSYmHf9Bzb8w==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-crypto/sha256-browser": "5.2.0",
- "@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.974.21",
- "@aws-sdk/credential-provider-node": "^3.972.56",
- "@aws-sdk/types": "^3.973.13",
- "@smithy/core": "^3.24.6",
- "@smithy/fetch-http-handler": "^5.4.6",
- "@smithy/node-http-handler": "^4.7.6",
- "@smithy/types": "^4.14.3",
+ "@aws-sdk/core": "^3.975.1",
+ "@aws-sdk/credential-provider-node": "^3.972.66",
+ "@aws-sdk/types": "^3.974.0",
+ "@smithy/core": "^3.29.2",
+ "@smithy/fetch-http-handler": "^5.6.4",
+ "@smithy/node-http-handler": "^4.9.4",
+ "@smithy/types": "^4.16.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -305,21 +233,19 @@
}
},
"node_modules/@aws-sdk/client-lambda": {
- "version": "3.1069.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-lambda/-/client-lambda-3.1069.0.tgz",
- "integrity": "sha512-35QhvxgI6H1cxpq9vspmefqDxWI16Jhwpo2wp8TzMRodphzWrHaoCxRXYwGlobhbycplhto3k61XXV8gvlzZJg==",
+ "version": "3.1085.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-lambda/-/client-lambda-3.1085.0.tgz",
+ "integrity": "sha512-Ms41fQmgYK/iF89KLoLVxSwPGtCwIYGyH+1Ovm6l7jiubxDmUfzU7keLzZHOymfxfDz5bBcqfwID65fuMKEnYQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-crypto/sha256-browser": "5.2.0",
- "@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.974.21",
- "@aws-sdk/credential-provider-node": "^3.972.56",
- "@aws-sdk/types": "^3.973.13",
- "@smithy/core": "^3.24.6",
- "@smithy/fetch-http-handler": "^5.4.6",
- "@smithy/node-http-handler": "^4.7.6",
- "@smithy/types": "^4.14.3",
+ "@aws-sdk/core": "^3.975.1",
+ "@aws-sdk/credential-provider-node": "^3.972.66",
+ "@aws-sdk/types": "^3.974.0",
+ "@smithy/core": "^3.29.2",
+ "@smithy/fetch-http-handler": "^5.6.4",
+ "@smithy/node-http-handler": "^4.9.4",
+ "@smithy/types": "^4.16.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -327,25 +253,22 @@
}
},
"node_modules/@aws-sdk/client-s3": {
- "version": "3.1069.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.1069.0.tgz",
- "integrity": "sha512-zkwCW4D88foQ0YHyjVyFhDOIWG+IWiTGXYg8+kUgH6M19son3OsZLvioZGyZdNtlRgLNYfQGBjfArSJOYYt2QQ==",
+ "version": "3.1085.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.1085.0.tgz",
+ "integrity": "sha512-O0xe8sR50AYkwxlvRRsV0qytEO2dtXQTQ1CF3YBBdE5xtVkbu27H0vGa1mjQi1/+fbYM80AWEIPai5jZmXyubw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-crypto/sha1-browser": "5.2.0",
- "@aws-crypto/sha256-browser": "5.2.0",
- "@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.974.21",
- "@aws-sdk/credential-provider-node": "^3.972.56",
- "@aws-sdk/middleware-flexible-checksums": "^3.974.31",
- "@aws-sdk/middleware-sdk-s3": "^3.972.52",
- "@aws-sdk/signature-v4-multi-region": "^3.996.35",
- "@aws-sdk/types": "^3.973.13",
- "@smithy/core": "^3.24.6",
- "@smithy/fetch-http-handler": "^5.4.6",
- "@smithy/node-http-handler": "^4.7.6",
- "@smithy/types": "^4.14.3",
+ "@aws-sdk/checksums": "^3.1000.16",
+ "@aws-sdk/core": "^3.975.1",
+ "@aws-sdk/credential-provider-node": "^3.972.66",
+ "@aws-sdk/middleware-sdk-s3": "^3.972.62",
+ "@aws-sdk/signature-v4-multi-region": "^3.996.39",
+ "@aws-sdk/types": "^3.974.0",
+ "@smithy/core": "^3.29.2",
+ "@smithy/fetch-http-handler": "^5.6.4",
+ "@smithy/node-http-handler": "^4.9.4",
+ "@smithy/types": "^4.16.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -353,21 +276,19 @@
}
},
"node_modules/@aws-sdk/client-sns": {
- "version": "3.1069.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-sns/-/client-sns-3.1069.0.tgz",
- "integrity": "sha512-qiBqtJQWsWsjX6T0fRuxAs6yNx61003j/YskIq7XAiQ11yZ0PPByn4nqVqu3zJDMWiwbQyf3QBBLYLp5NPbaoA==",
+ "version": "3.1085.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-sns/-/client-sns-3.1085.0.tgz",
+ "integrity": "sha512-F9AOKvav/zv8uukLXSgqG/EQErB/UMEahadT47iWqAWa0FahvxcchnzthN8kECoBCTsUn16N/1+wSvGTgJ9hWQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-crypto/sha256-browser": "5.2.0",
- "@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.974.21",
- "@aws-sdk/credential-provider-node": "^3.972.56",
- "@aws-sdk/types": "^3.973.13",
- "@smithy/core": "^3.24.6",
- "@smithy/fetch-http-handler": "^5.4.6",
- "@smithy/node-http-handler": "^4.7.6",
- "@smithy/types": "^4.14.3",
+ "@aws-sdk/core": "^3.975.1",
+ "@aws-sdk/credential-provider-node": "^3.972.66",
+ "@aws-sdk/types": "^3.974.0",
+ "@smithy/core": "^3.29.2",
+ "@smithy/fetch-http-handler": "^5.6.4",
+ "@smithy/node-http-handler": "^4.9.4",
+ "@smithy/types": "^4.16.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -375,22 +296,20 @@
}
},
"node_modules/@aws-sdk/client-sqs": {
- "version": "3.1069.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-sqs/-/client-sqs-3.1069.0.tgz",
- "integrity": "sha512-WVTfzUgaivDgee2802UInuZZFdNspYO2ba8yb56q+qgbDdDCAmk0k35MAmFnTn0hMoiJcDg+6/sk3iCc+aUqwg==",
+ "version": "3.1085.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-sqs/-/client-sqs-3.1085.0.tgz",
+ "integrity": "sha512-ND4HTISx/vwGhNmqgwaI/oQRVrTwqGerPJL0a6z0bRRme73fQ8RcciuVEDZT/klD5/J/uvw8g7cWlo+XjIMF/Q==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-crypto/sha256-browser": "5.2.0",
- "@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.974.21",
- "@aws-sdk/credential-provider-node": "^3.972.56",
- "@aws-sdk/middleware-sdk-sqs": "^3.972.31",
- "@aws-sdk/types": "^3.973.13",
- "@smithy/core": "^3.24.6",
- "@smithy/fetch-http-handler": "^5.4.6",
- "@smithy/node-http-handler": "^4.7.6",
- "@smithy/types": "^4.14.3",
+ "@aws-sdk/core": "^3.975.1",
+ "@aws-sdk/credential-provider-node": "^3.972.66",
+ "@aws-sdk/middleware-sdk-sqs": "^3.972.35",
+ "@aws-sdk/types": "^3.974.0",
+ "@smithy/core": "^3.29.2",
+ "@smithy/fetch-http-handler": "^5.6.4",
+ "@smithy/node-http-handler": "^4.9.4",
+ "@smithy/types": "^4.16.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -398,22 +317,20 @@
}
},
"node_modules/@aws-sdk/client-sts": {
- "version": "3.1069.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.1069.0.tgz",
- "integrity": "sha512-AJZ9Ujy0NL5KWb4NjP80FeHEgFDb5MvFnNDls3motxOedpyp4vXC5PtOLOlX4eh5k2PysLOQzamfBWee09dXqw==",
+ "version": "3.1085.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.1085.0.tgz",
+ "integrity": "sha512-ej/Fhb74+ZzmU5vUBQ+zZvrZ223dq5QxrmU6ufCKALvFz5u66z3+dR3jwtUUIOjxLeLXy4Y6YHy6+Z76JkhJAA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-crypto/sha256-browser": "5.2.0",
- "@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.974.21",
- "@aws-sdk/credential-provider-node": "^3.972.56",
- "@aws-sdk/signature-v4-multi-region": "^3.996.35",
- "@aws-sdk/types": "^3.973.13",
- "@smithy/core": "^3.24.6",
- "@smithy/fetch-http-handler": "^5.4.6",
- "@smithy/node-http-handler": "^4.7.6",
- "@smithy/types": "^4.14.3",
+ "@aws-sdk/core": "^3.975.1",
+ "@aws-sdk/credential-provider-node": "^3.972.66",
+ "@aws-sdk/signature-v4-multi-region": "^3.996.39",
+ "@aws-sdk/types": "^3.974.0",
+ "@smithy/core": "^3.29.2",
+ "@smithy/fetch-http-handler": "^5.6.4",
+ "@smithy/node-http-handler": "^4.9.4",
+ "@smithy/types": "^4.16.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -421,18 +338,18 @@
}
},
"node_modules/@aws-sdk/core": {
- "version": "3.974.21",
- "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.974.21.tgz",
- "integrity": "sha512-P5JAHvn4dTi96UsAGS67LVOqqpUNNRhnfFXqzCYtdBIGZtqBue4CXvRr9YenOO7PALj/Pn8uuyw53FBCiCYw8w==",
+ "version": "3.975.1",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.975.1.tgz",
+ "integrity": "sha512-8qh/6EYb7hl/ZwVfQufhbMEZs1gQIc7GbdrIf4eprQJ7cv042+74nE6l3YDfyWNzb9iPXb8fRyYSHkNIk5eE6Q==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/types": "^3.973.13",
- "@aws-sdk/xml-builder": "^3.972.30",
- "@aws/lambda-invoke-store": "^0.2.2",
- "@smithy/core": "^3.24.6",
- "@smithy/signature-v4": "^5.4.6",
- "@smithy/types": "^4.14.3",
+ "@aws-sdk/types": "^3.974.0",
+ "@aws-sdk/xml-builder": "^3.972.34",
+ "@aws/lambda-invoke-store": "^0.3.0",
+ "@smithy/core": "^3.29.2",
+ "@smithy/signature-v4": "^5.6.3",
+ "@smithy/types": "^4.16.0",
"bowser": "^2.11.0",
"tslib": "^2.6.2"
},
@@ -441,16 +358,16 @@
}
},
"node_modules/@aws-sdk/credential-provider-cognito-identity": {
- "version": "3.972.46",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.972.46.tgz",
- "integrity": "sha512-xQ+zJxuP4MZGsr6TIVVgsLRsxaBu1YqOFNbZMaNskqbTF2d9F8ibBLOMFV1BkUBOvI6ShwhlNViOQcK1Od/RPg==",
+ "version": "3.972.56",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.972.56.tgz",
+ "integrity": "sha512-nedaZz6Wz2FGUBMsWhlvBPGIkTMfRuMJ99YDHJI4CaC31JS8WPyTavEAio74cfd5nGhi0A8XASB4fZA5VqTdOQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/nested-clients": "^3.997.21",
- "@aws-sdk/types": "^3.973.13",
- "@smithy/core": "^3.24.6",
- "@smithy/types": "^4.14.3",
+ "@aws-sdk/nested-clients": "^3.997.31",
+ "@aws-sdk/types": "^3.974.0",
+ "@smithy/core": "^3.29.2",
+ "@smithy/types": "^4.16.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -458,16 +375,16 @@
}
},
"node_modules/@aws-sdk/credential-provider-env": {
- "version": "3.972.47",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.47.tgz",
- "integrity": "sha512-3YoPwJczcc+MtX2xxXaYaOOWO6xKUJr1ZIIDIFuninr51BYONVVcF/CP8K2xfVRC/PztJjqKWxNGFH7BWQAw1Q==",
+ "version": "3.972.57",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.57.tgz",
+ "integrity": "sha512-1RfJaF7SW1TOnvNGU7kaYjwUf5H3sfm+synGH1bHhRlqcnxCt3szebH3dmKEyY4tuGcbQ6ffzUT89cRitBV8OQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.974.21",
- "@aws-sdk/types": "^3.973.13",
- "@smithy/core": "^3.24.6",
- "@smithy/types": "^4.14.3",
+ "@aws-sdk/core": "^3.975.1",
+ "@aws-sdk/types": "^3.974.0",
+ "@smithy/core": "^3.29.2",
+ "@smithy/types": "^4.16.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -475,18 +392,18 @@
}
},
"node_modules/@aws-sdk/credential-provider-http": {
- "version": "3.972.49",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.49.tgz",
- "integrity": "sha512-2UtGUPy+x3lqyceHrtC1uEuVxBZbDalPF6KAFqBwYgm4edWdBrZKNnCqzDs7KynWUvEC6mrR+ojRk+ZgQz9C2w==",
+ "version": "3.972.59",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.59.tgz",
+ "integrity": "sha512-sRCkpTiFnCdQvuaRVjQ6SVoHu6i7RUpurVo1c4F81HWhPvUJ7Wdp5MNtSdX1O29CNXc8em3O5m52hCjVtAD9SA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.974.21",
- "@aws-sdk/types": "^3.973.13",
- "@smithy/core": "^3.24.6",
- "@smithy/fetch-http-handler": "^5.4.6",
- "@smithy/node-http-handler": "^4.7.6",
- "@smithy/types": "^4.14.3",
+ "@aws-sdk/core": "^3.975.1",
+ "@aws-sdk/types": "^3.974.0",
+ "@smithy/core": "^3.29.2",
+ "@smithy/fetch-http-handler": "^5.6.4",
+ "@smithy/node-http-handler": "^4.9.4",
+ "@smithy/types": "^4.16.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -494,24 +411,24 @@
}
},
"node_modules/@aws-sdk/credential-provider-ini": {
- "version": "3.972.54",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.972.54.tgz",
- "integrity": "sha512-Hx4gO4YRjFwitf3MVl3cDwYe1aryJthC4txVl9b+JAURovA50M2ywf9r8j1E/Q6SCTPT4qQpjOAbKYIC9CG+Vw==",
+ "version": "3.973.1",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.973.1.tgz",
+ "integrity": "sha512-6d8H6ZAh3ZPKZ6fe1nG2OWeZEZPtt9ravoD1dezPdPtsSkJRoxGAnFSHwKT3E/Te6fHE30zRzjV6TD12rvF6yQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.974.21",
- "@aws-sdk/credential-provider-env": "^3.972.47",
- "@aws-sdk/credential-provider-http": "^3.972.49",
- "@aws-sdk/credential-provider-login": "^3.972.53",
- "@aws-sdk/credential-provider-process": "^3.972.47",
- "@aws-sdk/credential-provider-sso": "^3.972.53",
- "@aws-sdk/credential-provider-web-identity": "^3.972.53",
- "@aws-sdk/nested-clients": "^3.997.21",
- "@aws-sdk/types": "^3.973.13",
- "@smithy/core": "^3.24.6",
- "@smithy/credential-provider-imds": "^4.3.7",
- "@smithy/types": "^4.14.3",
+ "@aws-sdk/core": "^3.975.1",
+ "@aws-sdk/credential-provider-env": "^3.972.57",
+ "@aws-sdk/credential-provider-http": "^3.972.59",
+ "@aws-sdk/credential-provider-login": "^3.972.63",
+ "@aws-sdk/credential-provider-process": "^3.972.57",
+ "@aws-sdk/credential-provider-sso": "^3.973.1",
+ "@aws-sdk/credential-provider-web-identity": "^3.972.63",
+ "@aws-sdk/nested-clients": "^3.997.31",
+ "@aws-sdk/types": "^3.974.0",
+ "@smithy/core": "^3.29.2",
+ "@smithy/credential-provider-imds": "^4.4.7",
+ "@smithy/types": "^4.16.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -519,17 +436,17 @@
}
},
"node_modules/@aws-sdk/credential-provider-login": {
- "version": "3.972.53",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.53.tgz",
- "integrity": "sha512-+71sluhkgPqdhbbD3UDwUpj24GCkng9HQx6z7qoBFb8dwkF4ktpOcVKDeHpgg8PvBgLYwAnUYLTEGRC/PniCiQ==",
+ "version": "3.972.63",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.63.tgz",
+ "integrity": "sha512-GREWRrMj0XnNKMaVa/Mauoaui26qBEHu71WWqXbwZOu/jFQOnPZjTf7u0KtGKC8VGa6VUs9kDWGgocrKNLS9vw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.974.21",
- "@aws-sdk/nested-clients": "^3.997.21",
- "@aws-sdk/types": "^3.973.13",
- "@smithy/core": "^3.24.6",
- "@smithy/types": "^4.14.3",
+ "@aws-sdk/core": "^3.975.1",
+ "@aws-sdk/nested-clients": "^3.997.31",
+ "@aws-sdk/types": "^3.974.0",
+ "@smithy/core": "^3.29.2",
+ "@smithy/types": "^4.16.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -537,22 +454,22 @@
}
},
"node_modules/@aws-sdk/credential-provider-node": {
- "version": "3.972.56",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.56.tgz",
- "integrity": "sha512-iI+4o0dvQQ4NHel4FMDiFy5q2gaU/ryLK3niOsoPccAt9WLFRkV4XTYPWRr9XvmBUqEzXG73S4p/8gm0Lu/W3A==",
+ "version": "3.972.66",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.66.tgz",
+ "integrity": "sha512-f+qjRXZpz7sgzbc4QB+6nLKfyKFgRRXzWdXbsKPv/VhVRyHsDyq4yBWC/B75BAJpFIcUeI2XR/3gdWJ677zB4A==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/credential-provider-env": "^3.972.47",
- "@aws-sdk/credential-provider-http": "^3.972.49",
- "@aws-sdk/credential-provider-ini": "^3.972.54",
- "@aws-sdk/credential-provider-process": "^3.972.47",
- "@aws-sdk/credential-provider-sso": "^3.972.53",
- "@aws-sdk/credential-provider-web-identity": "^3.972.53",
- "@aws-sdk/types": "^3.973.13",
- "@smithy/core": "^3.24.6",
- "@smithy/credential-provider-imds": "^4.3.7",
- "@smithy/types": "^4.14.3",
+ "@aws-sdk/credential-provider-env": "^3.972.57",
+ "@aws-sdk/credential-provider-http": "^3.972.59",
+ "@aws-sdk/credential-provider-ini": "^3.973.1",
+ "@aws-sdk/credential-provider-process": "^3.972.57",
+ "@aws-sdk/credential-provider-sso": "^3.973.1",
+ "@aws-sdk/credential-provider-web-identity": "^3.972.63",
+ "@aws-sdk/types": "^3.974.0",
+ "@smithy/core": "^3.29.2",
+ "@smithy/credential-provider-imds": "^4.4.7",
+ "@smithy/types": "^4.16.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -560,16 +477,16 @@
}
},
"node_modules/@aws-sdk/credential-provider-process": {
- "version": "3.972.47",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.47.tgz",
- "integrity": "sha512-tAizPm9IFo/PHn06c+LQJlzfY2AGOlyF0CUljFejrU6LcZBjnk8pmbZK3/xoIDdnIzjEdbClfvY3mXfr818ZEg==",
+ "version": "3.972.57",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.57.tgz",
+ "integrity": "sha512-TiVQhuU0pbhIZAUZacbPHMyzrIdiH+lnx+PMY/Pu/b93dJrq3wdZwzUJ0TPpvNxaqbHsxJvQZW3/h/beLiKq7Q==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.974.21",
- "@aws-sdk/types": "^3.973.13",
- "@smithy/core": "^3.24.6",
- "@smithy/types": "^4.14.3",
+ "@aws-sdk/core": "^3.975.1",
+ "@aws-sdk/types": "^3.974.0",
+ "@smithy/core": "^3.29.2",
+ "@smithy/types": "^4.16.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -577,18 +494,18 @@
}
},
"node_modules/@aws-sdk/credential-provider-sso": {
- "version": "3.972.53",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.972.53.tgz",
- "integrity": "sha512-pUXE3fu4tfEDV8BksIgf4dXvuIH10FhwHMl/wu8rBD5T1sMpryQWFVitH3kdPS90wlgrGYJQ/meQTSPacyZfeg==",
+ "version": "3.973.1",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.973.1.tgz",
+ "integrity": "sha512-3foTZUJ4821Ij60X7K3NJroygiZLnbBmarN+T//O2cjkISan90zElN3NBmgSlDrTQ7Gs6z/yO8V7h60QNcDZHQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.974.21",
- "@aws-sdk/nested-clients": "^3.997.21",
- "@aws-sdk/token-providers": "3.1069.0",
- "@aws-sdk/types": "^3.973.13",
- "@smithy/core": "^3.24.6",
- "@smithy/types": "^4.14.3",
+ "@aws-sdk/core": "^3.975.1",
+ "@aws-sdk/nested-clients": "^3.997.31",
+ "@aws-sdk/token-providers": "3.1083.0",
+ "@aws-sdk/types": "^3.974.0",
+ "@smithy/core": "^3.29.2",
+ "@smithy/types": "^4.16.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -596,17 +513,17 @@
}
},
"node_modules/@aws-sdk/credential-provider-web-identity": {
- "version": "3.972.53",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.53.tgz",
- "integrity": "sha512-JmMGlhVvSj8uSG9CpeDkJAXT35H89tc6v84iMgEIE75q4yp1MKVVKvopv6Gg28HJIR7hMNkojRF8H2m5W44wyg==",
+ "version": "3.972.63",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.63.tgz",
+ "integrity": "sha512-8qZLFhM69eKcS37m459ctPR05Qimycm/74OPVioe6wNZabMT54GYhwBju0+J656RkMasNSawWQu+c8CmBe3TUQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.974.21",
- "@aws-sdk/nested-clients": "^3.997.21",
- "@aws-sdk/types": "^3.973.13",
- "@smithy/core": "^3.24.6",
- "@smithy/types": "^4.14.3",
+ "@aws-sdk/core": "^3.975.1",
+ "@aws-sdk/nested-clients": "^3.997.31",
+ "@aws-sdk/types": "^3.974.0",
+ "@smithy/core": "^3.29.2",
+ "@smithy/types": "^4.16.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -614,28 +531,28 @@
}
},
"node_modules/@aws-sdk/credential-providers": {
- "version": "3.1069.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.1069.0.tgz",
- "integrity": "sha512-9emJtp/7OMOhfK2aIk0MdAfCF5v/2ERU3ZriVxAmZXIsoXtq5zmkZumN45/guHk15ZJ9XleKvgI0Ug+sXPZ9GA==",
+ "version": "3.1081.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.1081.0.tgz",
+ "integrity": "sha512-UHWvxd1F5nfBXBRXtQaXWoNT8CYKXZovLQOyz6XZlgFTGc2mWzzPGspOfnh49jwvB2qzsdH046i9jnnmND+64w==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/client-cognito-identity": "3.1069.0",
- "@aws-sdk/core": "^3.974.21",
- "@aws-sdk/credential-provider-cognito-identity": "^3.972.46",
- "@aws-sdk/credential-provider-env": "^3.972.47",
- "@aws-sdk/credential-provider-http": "^3.972.49",
- "@aws-sdk/credential-provider-ini": "^3.972.54",
- "@aws-sdk/credential-provider-login": "^3.972.53",
- "@aws-sdk/credential-provider-node": "^3.972.56",
- "@aws-sdk/credential-provider-process": "^3.972.47",
- "@aws-sdk/credential-provider-sso": "^3.972.53",
- "@aws-sdk/credential-provider-web-identity": "^3.972.53",
- "@aws-sdk/nested-clients": "^3.997.21",
- "@aws-sdk/types": "^3.973.13",
- "@smithy/core": "^3.24.6",
- "@smithy/credential-provider-imds": "^4.3.7",
- "@smithy/types": "^4.14.3",
+ "@aws-sdk/client-cognito-identity": "3.1081.0",
+ "@aws-sdk/core": "^3.974.29",
+ "@aws-sdk/credential-provider-cognito-identity": "^3.972.54",
+ "@aws-sdk/credential-provider-env": "^3.972.55",
+ "@aws-sdk/credential-provider-http": "^3.972.57",
+ "@aws-sdk/credential-provider-ini": "^3.972.62",
+ "@aws-sdk/credential-provider-login": "^3.972.61",
+ "@aws-sdk/credential-provider-node": "^3.972.64",
+ "@aws-sdk/credential-provider-process": "^3.972.55",
+ "@aws-sdk/credential-provider-sso": "^3.972.61",
+ "@aws-sdk/credential-provider-web-identity": "^3.972.61",
+ "@aws-sdk/nested-clients": "^3.997.29",
+ "@aws-sdk/types": "^3.973.15",
+ "@smithy/core": "^3.29.0",
+ "@smithy/credential-provider-imds": "^4.4.5",
+ "@smithy/types": "^4.15.1",
"tslib": "^2.6.2"
},
"engines": {
@@ -643,15 +560,15 @@
}
},
"node_modules/@aws-sdk/dynamodb-codec": {
- "version": "3.973.21",
- "resolved": "https://registry.npmjs.org/@aws-sdk/dynamodb-codec/-/dynamodb-codec-3.973.21.tgz",
- "integrity": "sha512-wfAWZ6oIrsDOFyYm9bDQNva/WCmvIrVqP3dSCePN5YYWCGWWXkikn5YC0wPSxF92M8kQFPfdVpMaTTV1mRk4Lw==",
+ "version": "3.973.31",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/dynamodb-codec/-/dynamodb-codec-3.973.31.tgz",
+ "integrity": "sha512-R8hSxTSdx49/Vz4qVvIQXtx10ka9mVxkXHvT43AYTYF7bb/TyzD/7BXcGTrsGYeJ6PV0y8RlNLGn2HumjHbsxw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.974.21",
- "@smithy/core": "^3.24.6",
- "@smithy/types": "^4.14.3",
+ "@aws-sdk/core": "^3.975.1",
+ "@smithy/core": "^3.29.2",
+ "@smithy/types": "^4.16.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -659,9 +576,9 @@
}
},
"node_modules/@aws-sdk/endpoint-cache": {
- "version": "3.972.8",
- "resolved": "https://registry.npmjs.org/@aws-sdk/endpoint-cache/-/endpoint-cache-3.972.8.tgz",
- "integrity": "sha512-bBmkG0Dnhfq0/T4Z0PpUr7HkncBVaWvvCbvafeaUM+yC9wa8GGjLJmonq0QL17REB9WivgGeYgWQ5A80Uw5UnQ==",
+ "version": "3.972.9",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/endpoint-cache/-/endpoint-cache-3.972.9.tgz",
+ "integrity": "sha512-LFvdgq8SriaskUcjpBMDE7J2c9RmuT5v3gU36/znV71EU5DKUis4FmGFjCMelKCCViFeVrQADBAlIiOYRhEx6Q==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -673,14 +590,14 @@
}
},
"node_modules/@aws-sdk/lib-storage": {
- "version": "3.1069.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/lib-storage/-/lib-storage-3.1069.0.tgz",
- "integrity": "sha512-i5XY2ZNaBOVXCHrmSe/4YG8Bl1X/qa/WjMbSF7DYXaN1F1x0Q4kQwce+HIYWym0S2/1ljm2aorul5bdU/k7fSA==",
+ "version": "3.1085.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/lib-storage/-/lib-storage-3.1085.0.tgz",
+ "integrity": "sha512-S+yCGIMxQ5Zs2A5ZDdYfXwOxu5kKjBaCQVOxp6+mnwCQYXUNkBD/aKCnW1eniMTavzz3YidhD5eTFpDlcUv2gQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@smithy/core": "^3.24.6",
- "@smithy/types": "^4.14.3",
+ "@smithy/core": "^3.29.2",
+ "@smithy/types": "^4.16.0",
"buffer": "5.6.0",
"events": "3.3.0",
"stream-browserify": "3.0.0",
@@ -690,34 +607,20 @@
"node": ">=20.0.0"
},
"peerDependencies": {
- "@aws-sdk/client-s3": "^3.1069.0"
+ "@aws-sdk/client-s3": "^3.1085.0"
}
},
"node_modules/@aws-sdk/middleware-endpoint-discovery": {
- "version": "3.972.19",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-endpoint-discovery/-/middleware-endpoint-discovery-3.972.19.tgz",
- "integrity": "sha512-FMgyzUq3Jh+ONRYxryBRNdBd+FUX8PwRl07ccQknNdoms6KCeAEusCkl6whqpDrPQ6OH0ddeSifKyqYSs2DLIw==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@aws-sdk/endpoint-cache": "^3.972.8",
- "@aws-sdk/types": "^3.973.13",
- "@smithy/core": "^3.24.6",
- "@smithy/types": "^4.14.3",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=20.0.0"
- }
- },
- "node_modules/@aws-sdk/middleware-flexible-checksums": {
- "version": "3.974.31",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.974.31.tgz",
- "integrity": "sha512-Yzj6NRYVZdBaCp7o1BwHGyeDBfixdeToLIAMprshIITEdl9wKVSiidVOfeaiH8FyeC1hBmBfDZFvs/aH1Y3xpw==",
+ "version": "3.972.23",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-endpoint-discovery/-/middleware-endpoint-discovery-3.972.23.tgz",
+ "integrity": "sha512-FoEkpD2A8haYWNT4wp8zW1x0Hc+NyxcnKJ2Hf4jX8EI5R4ybo1LRI3ql7iuFX1MTyklZx9hum9dPkq6R46pQMw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/checksums": "^3.1000.6",
+ "@aws-sdk/endpoint-cache": "^3.972.9",
+ "@aws-sdk/types": "^3.974.0",
+ "@smithy/core": "^3.29.2",
+ "@smithy/types": "^4.16.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -725,17 +628,17 @@
}
},
"node_modules/@aws-sdk/middleware-sdk-s3": {
- "version": "3.972.52",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.972.52.tgz",
- "integrity": "sha512-rerjP08onRqkBh0AcCqip6GkKvESapmLoTgi1xysZ4C6a1xMrIMtTBcEbUb6EY71oeajnigeUD4KwZjtIO+aWQ==",
+ "version": "3.972.62",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.972.62.tgz",
+ "integrity": "sha512-k8JJwYXVYlOOjWnPZDThQS1xDFJgi5Dokt73qFlDtrZAbdcint5aIdjB9XgJAAQVP5OoqcefQmh1FYXiPpvsvw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.974.21",
- "@aws-sdk/signature-v4-multi-region": "^3.996.35",
- "@aws-sdk/types": "^3.973.13",
- "@smithy/core": "^3.24.6",
- "@smithy/types": "^4.14.3",
+ "@aws-sdk/core": "^3.975.1",
+ "@aws-sdk/signature-v4-multi-region": "^3.996.39",
+ "@aws-sdk/types": "^3.974.0",
+ "@smithy/core": "^3.29.2",
+ "@smithy/types": "^4.16.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -743,15 +646,15 @@
}
},
"node_modules/@aws-sdk/middleware-sdk-sqs": {
- "version": "3.972.31",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sqs/-/middleware-sdk-sqs-3.972.31.tgz",
- "integrity": "sha512-56ifsBmK9bLn5EE/t6c0nmjOB1BO8cJDLkA1VOlsN1GR85ROqnaCwVDspqcwsLaBDgPlwyYNedoDIoT3t6Ho1A==",
+ "version": "3.972.35",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sqs/-/middleware-sdk-sqs-3.972.35.tgz",
+ "integrity": "sha512-J1u7OABwjjBB7sUJiET05dPVAfjFeR6vfM5//DInKuPzc7PhPVNEviC7RqbsIsBdZi8xICVnHemFrTuvGmhySA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/types": "^3.973.13",
- "@smithy/core": "^3.24.6",
- "@smithy/types": "^4.14.3",
+ "@aws-sdk/types": "^3.974.0",
+ "@smithy/core": "^3.29.2",
+ "@smithy/types": "^4.16.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -759,21 +662,19 @@
}
},
"node_modules/@aws-sdk/nested-clients": {
- "version": "3.997.21",
- "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.997.21.tgz",
- "integrity": "sha512-eC7Vl7Qom/BGhZjG9GEqPwdQ/fk45hg1t5LP4EUxG5d1fdshLbaxCiwh/tszUzDX/4mW40mu2QsbeJJRPBbqUw==",
+ "version": "3.997.31",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.997.31.tgz",
+ "integrity": "sha512-BDHTpwcsZHEBNEJzOg/B1BkFYJxAXY50dau/NyVWs3d51F0WgIUGSWZot/Os+N3KpDhXeaXnz37mWffAvduREw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-crypto/sha256-browser": "5.2.0",
- "@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.974.21",
- "@aws-sdk/signature-v4-multi-region": "^3.996.35",
- "@aws-sdk/types": "^3.973.13",
- "@smithy/core": "^3.24.6",
- "@smithy/fetch-http-handler": "^5.4.6",
- "@smithy/node-http-handler": "^4.7.6",
- "@smithy/types": "^4.14.3",
+ "@aws-sdk/core": "^3.975.1",
+ "@aws-sdk/signature-v4-multi-region": "^3.996.39",
+ "@aws-sdk/types": "^3.974.0",
+ "@smithy/core": "^3.29.2",
+ "@smithy/fetch-http-handler": "^5.6.4",
+ "@smithy/node-http-handler": "^4.9.4",
+ "@smithy/types": "^4.16.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -781,15 +682,15 @@
}
},
"node_modules/@aws-sdk/signature-v4-multi-region": {
- "version": "3.996.35",
- "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.996.35.tgz",
- "integrity": "sha512-6L/VWs+Wch2stHemCGTmUNqKLMzURxQDK5boNG3Jn3kAOp71meDUuS5sbObpEvFxHDq0uWeSLFDNSYsjNt+Dlg==",
+ "version": "3.996.39",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.996.39.tgz",
+ "integrity": "sha512-8+srXqYIF8KYMLC4FxMLEM5Ek7kUNibJu1R4m8/fUhhNYIZZz26oGtKkCr8I/HiG2fFQxBvaGgQZT4/mqRCSnA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/types": "^3.973.13",
- "@smithy/signature-v4": "^5.4.6",
- "@smithy/types": "^4.14.3",
+ "@aws-sdk/types": "^3.974.0",
+ "@smithy/signature-v4": "^5.6.3",
+ "@smithy/types": "^4.16.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -797,17 +698,17 @@
}
},
"node_modules/@aws-sdk/token-providers": {
- "version": "3.1069.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.1069.0.tgz",
- "integrity": "sha512-ks4X+kngC3PA5howV7Qu1TgG4bfC4jPykKdvw3nmBSXR9yZxRJouBholFSNQ5kY3L+Fgwyw+LCjzQmNi+KR91g==",
+ "version": "3.1083.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.1083.0.tgz",
+ "integrity": "sha512-s0woKnxuHrExLc5L2ArIH5BMkbonHPtt+5hSBM8oknp9M6QTuUmmAmJ2E0EdzCGONrO+8+ADPqvv6UX0nNcc7A==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.974.21",
- "@aws-sdk/nested-clients": "^3.997.21",
- "@aws-sdk/types": "^3.973.13",
- "@smithy/core": "^3.24.6",
- "@smithy/types": "^4.14.3",
+ "@aws-sdk/core": "^3.975.1",
+ "@aws-sdk/nested-clients": "^3.997.31",
+ "@aws-sdk/types": "^3.974.0",
+ "@smithy/core": "^3.29.2",
+ "@smithy/types": "^4.16.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -815,13 +716,13 @@
}
},
"node_modules/@aws-sdk/types": {
- "version": "3.973.13",
- "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.973.13.tgz",
- "integrity": "sha512-pEHZqRkAlHfnfAU9tK+WpKv/gBNjGJrHMgA3A0iYRGyswBS2t0pfez+lWlwktb3Bqa0ovh7w/QJTFwp3fDxLNg==",
+ "version": "3.974.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.974.0.tgz",
+ "integrity": "sha512-QIBrw90CDm4O0UaIIzkU6DrFdeJzEb2Va5EPEVpyldj6sHJxB6cshhStJuhZxk3wR3PmjJlYsjPmY1kNb+KGBg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@smithy/types": "^4.14.3",
+ "@smithy/types": "^4.16.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -829,26 +730,13 @@
}
},
"node_modules/@aws-sdk/util-format-url": {
- "version": "3.972.23",
- "resolved": "https://registry.npmjs.org/@aws-sdk/util-format-url/-/util-format-url-3.972.23.tgz",
- "integrity": "sha512-+KAkQBGX3CSFd7/xs+pz+j+D7rWXj4fviHn+Ykb4T4cfrOJFI3yfy+y+wvZ0vUIhVNy2wEKwFkhk4+tAoMFppw==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@aws-sdk/core": "^3.974.21",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=20.0.0"
- }
- },
- "node_modules/@aws-sdk/util-locate-window": {
- "version": "3.965.8",
- "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.965.8.tgz",
- "integrity": "sha512-uUbMs1cBZPafD0ohUj6EwNf0fPZ534NvBxHox4hjX+0Rxq5paSYUem7+hi833pYrzrcnBATKIYpR02MDXT5M9g==",
+ "version": "3.972.33",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/util-format-url/-/util-format-url-3.972.33.tgz",
+ "integrity": "sha512-yKdN0GW+dVRANmFf+kJH6EnZlvl4ynaYRaUKC8SVRWrAgNe/KjA0FIrH9zyjy38kI5q3GZx6JJ7cwsJTFvRDHw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
+ "@aws-sdk/core": "^3.975.1",
"tslib": "^2.6.2"
},
"engines": {
@@ -866,14 +754,13 @@
}
},
"node_modules/@aws-sdk/xml-builder": {
- "version": "3.972.30",
- "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.30.tgz",
- "integrity": "sha512-StElZPEoBquWwNqw1AcfpzEyZqJvFxouG+mpDNYlcH6ZOrqd2CuIryv+8LV8gNHZUOyKyJF3Dq9vxaXEmDR9TQ==",
+ "version": "3.972.34",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.34.tgz",
+ "integrity": "sha512-wHhWL1y7sN3enBA8POrPpQM5jCcmu2ozyhbRei4c8OjVcEaEs6yLucLa/pla457ggS/ysuy7bosagz3HaJkZXA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@smithy/types": "^4.14.3",
- "fast-xml-parser": "5.7.3",
+ "@smithy/types": "^4.16.0",
"tslib": "^2.6.2"
},
"engines": {
@@ -881,9 +768,9 @@
}
},
"node_modules/@aws/lambda-invoke-store": {
- "version": "0.2.4",
- "resolved": "https://registry.npmjs.org/@aws/lambda-invoke-store/-/lambda-invoke-store-0.2.4.tgz",
- "integrity": "sha512-iY8yvjE0y651BixKNPgmv1WrQc+GZ142sb0z4gYnChDDY2YqI4P/jsSopBWrKfAt7LOJAkOXt7rC/hms+WclQQ==",
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/@aws/lambda-invoke-store/-/lambda-invoke-store-0.3.0.tgz",
+ "integrity": "sha512-sl4Bm6yiMNYrZKkqqDFWN0UfnWhlS8ivKxrYl+6t0gCLrqr8y3B2IqZZbFRkfaVVp7C/baApyh71P+LeE1A2sQ==",
"dev": true,
"license": "Apache-2.0",
"engines": {
@@ -1432,9 +1319,9 @@
}
},
"node_modules/@biomejs/biome": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.5.0.tgz",
- "integrity": "sha512-4kURkd9hAPrdDM3C9n82ycYgx8hvQcW6MjKTEejruj8rK0N8P3OPpdy8BvI8kt3KWY4ycF5XtDOrktetEfhfuw==",
+ "version": "2.5.3",
+ "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.5.3.tgz",
+ "integrity": "sha512-MrJswFdei9EfDwwUy2tQrPDpK0AO+RmMFvBoaaJ6ayBc3sUbHdCE+XG5N8vp+5So41ZupZJQm0roHFFhMGVD7A==",
"dev": true,
"license": "MIT OR Apache-2.0",
"bin": {
@@ -1448,20 +1335,20 @@
"url": "https://opencollective.com/biome"
},
"optionalDependencies": {
- "@biomejs/cli-darwin-arm64": "2.5.0",
- "@biomejs/cli-darwin-x64": "2.5.0",
- "@biomejs/cli-linux-arm64": "2.5.0",
- "@biomejs/cli-linux-arm64-musl": "2.5.0",
- "@biomejs/cli-linux-x64": "2.5.0",
- "@biomejs/cli-linux-x64-musl": "2.5.0",
- "@biomejs/cli-win32-arm64": "2.5.0",
- "@biomejs/cli-win32-x64": "2.5.0"
+ "@biomejs/cli-darwin-arm64": "2.5.3",
+ "@biomejs/cli-darwin-x64": "2.5.3",
+ "@biomejs/cli-linux-arm64": "2.5.3",
+ "@biomejs/cli-linux-arm64-musl": "2.5.3",
+ "@biomejs/cli-linux-x64": "2.5.3",
+ "@biomejs/cli-linux-x64-musl": "2.5.3",
+ "@biomejs/cli-win32-arm64": "2.5.3",
+ "@biomejs/cli-win32-x64": "2.5.3"
}
},
"node_modules/@biomejs/cli-darwin-arm64": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.5.0.tgz",
- "integrity": "sha512-Mn3Fwi3SA5fgmfCPqmzpWF2DLZnms3BVAhM088nTnGrTZmHS3wwIjcoZPqpXeNgd3DrrLH6xp8vTLIBuJoZiXw==",
+ "version": "2.5.3",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.5.3.tgz",
+ "integrity": "sha512-QhYP9muVQ0nUO5zztFuPbEwi4+94sJWVjaZds9aMi1l/KNZBiUjdiSUrGHsTaMGDXrYl+r4AS2sUKfgH3w+V3g==",
"cpu": [
"arm64"
],
@@ -1476,9 +1363,9 @@
}
},
"node_modules/@biomejs/cli-darwin-x64": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.5.0.tgz",
- "integrity": "sha512-rg3VPL5P8mYro6pqlXYXuJWph21slVp3SZtAqWSrkZs40d2gTzYmHF8E/X1iTID25btmNKltNDJ926sqVBp7DQ==",
+ "version": "2.5.3",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.5.3.tgz",
+ "integrity": "sha512-NC1Ss13UaW7QZX+y8j44bF7AP0jSJdBl6iRhe0MAkvaSqZy+mWg3GaXsrb+eSoHoGDBtaXWEbMVV0iVN2cZ7cQ==",
"cpu": [
"x64"
],
@@ -1493,9 +1380,9 @@
}
},
"node_modules/@biomejs/cli-linux-arm64": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.5.0.tgz",
- "integrity": "sha512-tl+LW8fdD96/xdeWtWwc82LIOc5CoY7N2AsogLTp5R4ECErYt+8Jl/N68ezN9vzSiqPTxw6vjcihoLPYKZHrlw==",
+ "version": "2.5.3",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.5.3.tgz",
+ "integrity": "sha512-ksx1KWeyYW18ILL04msF/J4ZBtBDN33znYK8Z/aNv/vlBVxL9/g3mGP+omgHJKy4+KWbK87vcmmpmurfNjSgiA==",
"cpu": [
"arm64"
],
@@ -1513,9 +1400,9 @@
}
},
"node_modules/@biomejs/cli-linux-arm64-musl": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.5.0.tgz",
- "integrity": "sha512-vQdM4oSGaf7ZNeGO9w5+Y8SBtyser9M6znxYbm7Ec8wInxJu1WiKxFYZW5Auj2d80bcVvefuGGRxoFOE0eee8g==",
+ "version": "2.5.3",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.5.3.tgz",
+ "integrity": "sha512-fccix0w6xp6csCXgxeC0dU/3ecgRQal0y+cv2SP9ajNlhe7Yrk2Ug7UDe2j9AT9ZDYitkXpvUKgZjjuoYeP4Vg==",
"cpu": [
"arm64"
],
@@ -1533,9 +1420,9 @@
}
},
"node_modules/@biomejs/cli-linux-x64": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.5.0.tgz",
- "integrity": "sha512-zpEGf4RQbFEh8Vt7OmavLyyOzRbtcE9osCqrS1kfvt8jDvxwhKXLSf7n0ebr/ov0RJ9ssP+lhs6C8a9WwFvrQA==",
+ "version": "2.5.3",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.5.3.tgz",
+ "integrity": "sha512-yMkJtilsgvILDcVkh187aVLTb64xYsrxYajx5kym+r1ULkO5HUOfu9AYKLGQbOVLwJtT2utNw7hhFNg+17mUYA==",
"cpu": [
"x64"
],
@@ -1553,9 +1440,9 @@
}
},
"node_modules/@biomejs/cli-linux-x64-musl": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.5.0.tgz",
- "integrity": "sha512-+9hIcMngJ+yGUahXqZuZ8CoWKJE9SAZsFsM3QDvXpNsLbXZ9lqVzgBhOk/jTSYkOA0GLP9eu3teukqpLUojHMg==",
+ "version": "2.5.3",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.5.3.tgz",
+ "integrity": "sha512-O/yU9YKRUiHhmcjF2f38PSjseVk3G4VLWYc0G2HWpzdBVREV6G8IGWIVEFf7MFPfWIzNUIvPsEjeAZQIOgnLcQ==",
"cpu": [
"x64"
],
@@ -1573,9 +1460,9 @@
}
},
"node_modules/@biomejs/cli-win32-arm64": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.5.0.tgz",
- "integrity": "sha512-jB0wAvTLI4itx5VidqVUejPQFhRUxiZ9l9FvZ26D5fl6t3qme+ZB4PD3bTSeL1vZ8NI2Rx/zj6H9zcESuGHKGw==",
+ "version": "2.5.3",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.5.3.tgz",
+ "integrity": "sha512-cX5z+GYwRcqEok0AH3KSfQGgqYd0Nomfp6Fbe1uiTtELE38hdH2k842wQ9wLNaF/JJ7r4rjJQ4VR+ce+fRmQbw==",
"cpu": [
"arm64"
],
@@ -1590,9 +1477,9 @@
}
},
"node_modules/@biomejs/cli-win32-x64": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.5.0.tgz",
- "integrity": "sha512-VT/lF+GId+67j8aDfLkxdxNoVApsPSTbyAtB3jJq0IWTrY77WXfbPfpngxq0bA6JCEv/7k8C9qWjDRKRznDlyw==",
+ "version": "2.5.3",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.5.3.tgz",
+ "integrity": "sha512-ExSaJWi4/u6+GXCszlSKpWSjKNbDseAYqqkCznsCsZ/4uidZ/BEqsCc5/3ctlq6dfIubdIIRSVLC/PG9xPl70Q==",
"cpu": [
"x64"
],
@@ -1633,9 +1520,9 @@
}
},
"node_modules/@cloudflare/workerd-darwin-64": {
- "version": "1.20260611.1",
- "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20260611.1.tgz",
- "integrity": "sha512-iJICldmi4sBGgi7IrQles8cStOGXM/Tmv95C4OODVs6VIbMsJPqThUM5h3uYVQNULuJ8I/aVvnJ3Eh/wZCKwuA==",
+ "version": "1.20260708.1",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20260708.1.tgz",
+ "integrity": "sha512-HXFCvhS1wpg3uXO0CLUwmwC41i2loM5FSK69EUchOBpmYBAXxT1oHLm6EOA5lqhTk5Mu9kjRiQYxa1GwKPwfJg==",
"cpu": [
"x64"
],
@@ -1650,9 +1537,9 @@
}
},
"node_modules/@cloudflare/workerd-darwin-arm64": {
- "version": "1.20260611.1",
- "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20260611.1.tgz",
- "integrity": "sha512-yBbVXvbZyltR3I7NJdC4C4ItkItjZSiabcA/3HzEWOUQjLVKFqRh4so6ToHr70VCYh8VGeR8EDZL23igLhXqFQ==",
+ "version": "1.20260708.1",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20260708.1.tgz",
+ "integrity": "sha512-JVlJaKDoRTVKSroHIlf8g3UCPjKj4iDbMZE2CNYht5qQ+2rL0FAUiVlV82G3BqKnnw9kHYnnsMzC08b9zVtdzA==",
"cpu": [
"arm64"
],
@@ -1667,9 +1554,9 @@
}
},
"node_modules/@cloudflare/workerd-linux-64": {
- "version": "1.20260611.1",
- "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20260611.1.tgz",
- "integrity": "sha512-PfNjpxOlaIgZFYuhD7+neEEewCN2Ud993wEEN0fmbtSOax1AK53LGqmXUDvFhnbkHxJLFAxYCSNISW8QbzaAIg==",
+ "version": "1.20260708.1",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20260708.1.tgz",
+ "integrity": "sha512-3daE60YdD7YX0Jtuzc9DE/r/qMkmx8ZvHTkF8Mzmp3F5tbzlV0DAzmu5PFUPF2WuvtKbAhZKbvC2cHmWpQYxnA==",
"cpu": [
"x64"
],
@@ -1684,9 +1571,9 @@
}
},
"node_modules/@cloudflare/workerd-linux-arm64": {
- "version": "1.20260611.1",
- "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20260611.1.tgz",
- "integrity": "sha512-GEp4XbuIKjlF8pakqXcUDJfKiJosD/Q7S83J0d+r+z9XIlYGfF3ntm08e2aiF5TFTwp3fnG4yMoPUAKNhNJpvQ==",
+ "version": "1.20260708.1",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20260708.1.tgz",
+ "integrity": "sha512-VLdNYOx5Hj+9C6isy0ACWZsbMtSxex2DIJWEe7cZxUdlphZ58ZT8zxNXK8yunFiowd34hn3VwGMopdvdj8lvmA==",
"cpu": [
"arm64"
],
@@ -1701,9 +1588,9 @@
}
},
"node_modules/@cloudflare/workerd-windows-64": {
- "version": "1.20260611.1",
- "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20260611.1.tgz",
- "integrity": "sha512-S6JkS0kEbcCKs19RGqEPhjCRbP8GBkQwqYLp2fhBJtD/KTlwqLzOJ9E6PQ7gQKgWHtxy1NBG3oXarlNFRNU/dw==",
+ "version": "1.20260708.1",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20260708.1.tgz",
+ "integrity": "sha512-bC/aSAwLy16Vjo24i9XU3aWH+eRgz7NeR5xPKavGbembO18ZywYTQbXh14eXtY6fAqN3RzRG8psijTdhX4xydA==",
"cpu": [
"x64"
],
@@ -1718,24 +1605,25 @@
}
},
"node_modules/@cloudflare/workers-types": {
- "version": "4.20260615.1",
- "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20260615.1.tgz",
- "integrity": "sha512-fGOiTwoLj/8bU8mj3VAfa1EULx4ceZhDwnjvY+afDBlSXI9pvY7PE9t62rGEhJjbAOGd7i5WUDun0eZCWBDrzg==",
- "dev": true,
+ "version": "5.20260711.1",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-5.20260711.1.tgz",
+ "integrity": "sha512-yY6GXfyrHJa33EWaSzS5N56Lsll02kgHo4Qodz2l2DNl4L6L5yXBMZVMvcYArirdYA1xn+o8LKVRQGdRpmSMzA==",
+ "extraneous": true,
"license": "MIT OR Apache-2.0"
},
"node_modules/@commitlint/cli": {
- "version": "21.0.2",
- "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-21.0.2.tgz",
- "integrity": "sha512-YMmfLbqBg+ZRvvmPhc+cilSQFrh/AgzVgCT1U/OifmUZEwPbvCtA8rN//YNaF9d5eoZphxVMGYtmwA2QgQORgg==",
+ "version": "21.2.1",
+ "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-21.2.1.tgz",
+ "integrity": "sha512-blsZGe29hJ72VGEFVl72IVYX+1vsfINpjA9yWQA6i7OKD/McGEOXg08sKIRKjFk4JvzhV/9n0l3i6NooPLTNfg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@commitlint/format": "^21.0.1",
- "@commitlint/lint": "^21.0.2",
- "@commitlint/load": "^21.0.2",
- "@commitlint/read": "^21.0.2",
- "@commitlint/types": "^21.0.1",
+ "@commitlint/config-conventional": "^21.2.0",
+ "@commitlint/format": "^21.2.0",
+ "@commitlint/lint": "^21.2.0",
+ "@commitlint/load": "^21.2.0",
+ "@commitlint/read": "^21.2.1",
+ "@commitlint/types": "^21.2.0",
"tinyexec": "^1.0.0",
"yargs": "^18.0.0"
},
@@ -1747,27 +1635,27 @@
}
},
"node_modules/@commitlint/config-conventional": {
- "version": "21.0.2",
- "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-21.0.2.tgz",
- "integrity": "sha512-P/ZRhryQmkj0Z0dY9FOoRwe3xkwJyyAdtXwt01NT2kuZttcG2CNYp1q5Ci3u+nDT2jcbJRw2kt13Czl1qKNPfg==",
+ "version": "21.2.0",
+ "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-21.2.0.tgz",
+ "integrity": "sha512-Qf8WRDVcyVd14if6VTWenebxFbKnVnbzPUJjlzjkyJGeHK2xCGd63Dr1XZzj0plXKQb9P0BfOxoc1HVeCo2BWQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@commitlint/types": "^21.0.1",
- "conventional-changelog-conventionalcommits": "^9.2.0"
+ "@commitlint/types": "^21.2.0",
+ "conventional-changelog-conventionalcommits": "^10.0.0"
},
"engines": {
"node": ">=22.12.0"
}
},
"node_modules/@commitlint/config-validator": {
- "version": "21.0.1",
- "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-21.0.1.tgz",
- "integrity": "sha512-Zd2UFdndeMMaW2O96HK0tdfT4gOImUvidMpAd/pws2zZ4m1nrAZ/9b/v2JYuE8fs86GpXv9F7LNaIuCIWhY+pA==",
+ "version": "21.2.0",
+ "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-21.2.0.tgz",
+ "integrity": "sha512-t7AzNHAKeIdo/3NRGwzpufKHsKkPHmFs/56N2Fnsh0/r0rGtnQzTxk6vnFgjaGr4hdSQKNB50/KAhR9Yk4LJKA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@commitlint/types": "^21.0.1",
+ "@commitlint/types": "^21.2.0",
"ajv": "^8.11.0"
},
"engines": {
@@ -1775,13 +1663,13 @@
}
},
"node_modules/@commitlint/ensure": {
- "version": "21.0.1",
- "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-21.0.1.tgz",
- "integrity": "sha512-jJ1037967wU7YN/xkv+iRlOBlmaOXPhPO5KQSqya6GyXzBlwuLzELBFao16DVg9dZyqmNrhewzwZ3SAibetHBQ==",
+ "version": "21.2.0",
+ "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-21.2.0.tgz",
+ "integrity": "sha512-76IF9vDNS13lAzEEik9eKwzt8f9hYhWiwVXZ2AnyLCz5/f511FsEQ3pw1X3/zSQpdRLQU7i5qDMVKyXi1GWjSg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@commitlint/types": "^21.0.1",
+ "@commitlint/types": "^21.2.0",
"es-toolkit": "^1.46.0"
},
"engines": {
@@ -1799,13 +1687,13 @@
}
},
"node_modules/@commitlint/format": {
- "version": "21.0.1",
- "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-21.0.1.tgz",
- "integrity": "sha512-ksmG2+cHGtuDPQQbhBbC4unwm444+6TiPw0d1bKf67hntgZqZ8E0g1MuYKUuyT5IH4IMmXZhKq22/Z3jBvtQIw==",
+ "version": "21.2.0",
+ "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-21.2.0.tgz",
+ "integrity": "sha512-c4q64xaav2U83t7k7RyzJerBZurPer7FxUOY0RL5L/6CZijZ7K+s6HIBGIghj0ey1P2+seRX0J9XQYtDued6tg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@commitlint/types": "^21.0.1",
+ "@commitlint/types": "^21.2.0",
"picocolors": "^1.1.1"
},
"engines": {
@@ -1813,13 +1701,13 @@
}
},
"node_modules/@commitlint/is-ignored": {
- "version": "21.0.2",
- "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-21.0.2.tgz",
- "integrity": "sha512-H5z4t8PC9tUsmZ/o+EptM3Nq8sTFtskAShdcqxCoyzklW5eaVT5xbrDAET2uypzir9Vsj4ZZmBtyKjYe2XqgeQ==",
+ "version": "21.2.0",
+ "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-21.2.0.tgz",
+ "integrity": "sha512-4/eB0vBN7L88O/oC4ajAEqi7j2ZfNgxl/+11RfAV9YosejZgDXhY2C9VcHnHJhOzPLoSy5P3Mg/46kqeyJfXKw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@commitlint/types": "^21.0.1",
+ "@commitlint/types": "^21.2.0",
"semver": "^7.6.0"
},
"engines": {
@@ -1827,32 +1715,32 @@
}
},
"node_modules/@commitlint/lint": {
- "version": "21.0.2",
- "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-21.0.2.tgz",
- "integrity": "sha512-PnUmLYGeGLfW8oVatR9KpNxSHYAnJOEWlMZzfdeFOUq6WUrFx1fGQaWCWJqMoIll/xPM+GdfJV+tKHZVHhl0Fg==",
+ "version": "21.2.0",
+ "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-21.2.0.tgz",
+ "integrity": "sha512-ceO5dp9pLjEZ6y6qbq/uXWXDPykqqlTsyzoQ0NzecpisSJhK3kTy9qzQoPeJuWG/IMNdV1lO0RgmzqoAlSi1uw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@commitlint/is-ignored": "^21.0.2",
- "@commitlint/parse": "^21.0.2",
- "@commitlint/rules": "^21.0.2",
- "@commitlint/types": "^21.0.1"
+ "@commitlint/is-ignored": "^21.2.0",
+ "@commitlint/parse": "^21.2.0",
+ "@commitlint/rules": "^21.2.0",
+ "@commitlint/types": "^21.2.0"
},
"engines": {
"node": ">=22.12.0"
}
},
"node_modules/@commitlint/load": {
- "version": "21.0.2",
- "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-21.0.2.tgz",
- "integrity": "sha512-lwUE70hN0/qE/ZRROhbaX65ly/FF12DrqfReLCESo37M0OQCFAf2jRS+2tSCSORq+bm4Kdju7qNDj46uc1QzTA==",
+ "version": "21.2.0",
+ "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-21.2.0.tgz",
+ "integrity": "sha512-RjlzWQqruRwIenJEfZtq7kG97co97nKoHpflE5YnF61tDLXxHPrdWImgzw6VL6MlFyaOcVlk74eBV8ZQmc3oIA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@commitlint/config-validator": "^21.0.1",
+ "@commitlint/config-validator": "^21.2.0",
"@commitlint/execute-rule": "^21.0.1",
- "@commitlint/resolve-extends": "^21.0.1",
- "@commitlint/types": "^21.0.1",
+ "@commitlint/resolve-extends": "^21.2.0",
+ "@commitlint/types": "^21.2.0",
"cosmiconfig": "^9.0.1",
"cosmiconfig-typescript-loader": "^6.1.0",
"es-toolkit": "^1.46.0",
@@ -1864,9 +1752,9 @@
}
},
"node_modules/@commitlint/message": {
- "version": "21.0.2",
- "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-21.0.2.tgz",
- "integrity": "sha512-5n4aqHGD/FNnom/D5L8i7cYtV+xjuXcBL832C3w9VglEsZzIsoHpJsvxzJ7cgiOsOdc/2jU4t5+7qMHh7GBX3g==",
+ "version": "21.2.0",
+ "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-21.2.0.tgz",
+ "integrity": "sha512-YxGoiXD/HXNXLJPrQwE5poXa+XH0CBEm+mdvbHQP0g6MV/dmJyUFCzPNzZbxL93GvZ70TmtTK0Z0/IBpAqHv8g==",
"dev": true,
"license": "MIT",
"engines": {
@@ -1874,30 +1762,30 @@
}
},
"node_modules/@commitlint/parse": {
- "version": "21.0.2",
- "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-21.0.2.tgz",
- "integrity": "sha512-QVZJhGHTm+oiuWyEKOCTQ0ZM3mfJ0eGWFeHuj7WzSKEth+UukcCHac9GD8pgdFlg/qGkFWOtyaNd1T8REgagaw==",
+ "version": "21.2.0",
+ "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-21.2.0.tgz",
+ "integrity": "sha512-QHWxG4d0PLTF634/AdyZ0MQS+CLn5YOuJlCFhMMlSGKFxzYGUetkHBj18xgBD+6fVzUrA2lrCdi/vlS2f/oYXg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@commitlint/types": "^21.0.1",
- "conventional-changelog-angular": "^8.2.0",
- "conventional-commits-parser": "^6.3.0"
+ "@commitlint/types": "^21.2.0",
+ "conventional-changelog-angular": "^9.0.0",
+ "conventional-commits-parser": "^7.0.0"
},
"engines": {
"node": ">=22.12.0"
}
},
"node_modules/@commitlint/read": {
- "version": "21.0.2",
- "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-21.0.2.tgz",
- "integrity": "sha512-BtsrnLVycSSKf4Q0gMch4giCj5NNlmcbhc8ra5vONgGtP2IjRDo33bEFtr5Pm+2N+5fXGWb2MksWPrspPfdhdw==",
+ "version": "21.2.1",
+ "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-21.2.1.tgz",
+ "integrity": "sha512-hUW7EJQnNTL0vPOmVMNK4CrnrNBN0nN+JJHReFkdHO5y4iyHeEmTBwuC15OCqUTjxWo7idnH1LftfpWVIaPWIA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@commitlint/top-level": "^21.0.2",
- "@commitlint/types": "^21.0.1",
- "git-raw-commits": "^5.0.0",
+ "@commitlint/top-level": "^21.2.0",
+ "@commitlint/types": "^21.2.0",
+ "@conventional-changelog/git-client": "^3.0.0",
"tinyexec": "^1.0.0"
},
"engines": {
@@ -1905,14 +1793,14 @@
}
},
"node_modules/@commitlint/resolve-extends": {
- "version": "21.0.1",
- "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-21.0.1.tgz",
- "integrity": "sha512-0DhjYWL6uYrY16Efa032fYk3woGJDU4AGWiG1XXltT9AMUNYKyb5cIZU2ivbaMZ3+kKFqUjikD2cjh66Sbh/Sg==",
+ "version": "21.2.0",
+ "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-21.2.0.tgz",
+ "integrity": "sha512-4O/1j51+79Wth9s/MGxt/5gs0XYLDgNlYpltQfhAvLE0itusLKs9zruxbiNg1oOkmkb9L9L4USYGjEj7n87NxA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@commitlint/config-validator": "^21.0.1",
- "@commitlint/types": "^21.0.1",
+ "@commitlint/config-validator": "^21.2.0",
+ "@commitlint/types": "^21.2.0",
"es-toolkit": "^1.46.0",
"global-directory": "^5.0.0",
"resolve-from": "^5.0.0"
@@ -1922,16 +1810,16 @@
}
},
"node_modules/@commitlint/rules": {
- "version": "21.0.2",
- "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-21.0.2.tgz",
- "integrity": "sha512-k6tQ69Td7t2qUSIbik8D3TL1q3ZJpkEbV+yLogDzCRAdOxJm4ndhtBNREsLA1/puRfWvzS9eioF2w43WT+hHgQ==",
+ "version": "21.2.0",
+ "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-21.2.0.tgz",
+ "integrity": "sha512-C2yXMNpiB8ETZKfx5JD8+ExgF8vTU1VQMKPSUUYwqKpw9oJWQBrlXBpdU038mj2WPjof7o9UzFpmTyBeGMZwZg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@commitlint/ensure": "^21.0.1",
- "@commitlint/message": "^21.0.2",
+ "@commitlint/ensure": "^21.2.0",
+ "@commitlint/message": "^21.2.0",
"@commitlint/to-lines": "^21.0.1",
- "@commitlint/types": "^21.0.1"
+ "@commitlint/types": "^21.2.0"
},
"engines": {
"node": ">=22.12.0"
@@ -1948,9 +1836,9 @@
}
},
"node_modules/@commitlint/top-level": {
- "version": "21.0.2",
- "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-21.0.2.tgz",
- "integrity": "sha512-s9KKM+e+mXgFeIh4n7KmOGAVT3mkJ3Fp1bBYHIK5pjeUwlEMzp/tZfb5u0Poa680AsQTXMEMRxZi1vQ9m2X5ug==",
+ "version": "21.2.0",
+ "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-21.2.0.tgz",
+ "integrity": "sha512-Y5gmQ+KxzqCrBFJfLvFEPvvwD3LDiNZoTT2yeFBm96M8qhmqSzQc5DvX3rheAaAMjyIvMXOCLS/mWfdpONsjyQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1961,13 +1849,13 @@
}
},
"node_modules/@commitlint/types": {
- "version": "21.0.1",
- "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-21.0.1.tgz",
- "integrity": "sha512-4u7w8jcoCUFWhjWnASYzZHAP34OqOtuFBN87nQmFvqda03YU0T6z+yB4w0gSAMpekiRqqGk5rt+qSlW+a2vSEg==",
+ "version": "21.2.0",
+ "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-21.2.0.tgz",
+ "integrity": "sha512-7zVFCDB2reMvJH5dmbKnOQPjZEvjdJTH8jc0U/PIPU1r3/+vf5pD1HlfitV2MWsWXrvu7u39iY1lyLUPOaN0Gw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "conventional-commits-parser": "^6.3.0",
+ "conventional-commits-parser": "^7.0.0",
"picocolors": "^1.1.1"
},
"engines": {
@@ -1975,22 +1863,22 @@
}
},
"node_modules/@conventional-changelog/git-client": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/@conventional-changelog/git-client/-/git-client-2.7.0.tgz",
- "integrity": "sha512-j7A8/LBEQ+3rugMzPXoKYzyUPpw/0CBQCyvtTR7Lmu4olG4yRC/Tfkq79Mr3yuPs0SUitlO2HwGP3gitMJnRFw==",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@conventional-changelog/git-client/-/git-client-3.1.0.tgz",
+ "integrity": "sha512-Tqa/gHco2WJWa740NRjOrfKVvzIqxkZpecb8bemaQ8sKM5PXb1UK4uTyTb/1wIqNuOVaDOFxyBdhTIQZn6gdjQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@simple-libs/child-process-utils": "^1.0.0",
- "@simple-libs/stream-utils": "^1.2.0",
+ "@simple-libs/child-process-utils": "^2.0.0",
+ "@simple-libs/stream-utils": "^2.0.0",
"semver": "^7.5.2"
},
"engines": {
- "node": ">=18"
+ "node": ">=22"
},
"peerDependencies": {
- "conventional-commits-filter": "^5.0.0",
- "conventional-commits-parser": "^6.4.0"
+ "conventional-commits-filter": "^6.0.1",
+ "conventional-commits-parser": "^7.0.1"
},
"peerDependenciesMeta": {
"conventional-commits-filter": {
@@ -2001,6 +1889,16 @@
}
}
},
+ "node_modules/@conventional-changelog/template": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@conventional-changelog/template/-/template-1.2.1.tgz",
+ "integrity": "sha512-TzlTVpKPjaqW6qOYjQcYUDuGsLCNsvFHVBXkYGTAnf5V37jCWrE5haKNXzz0WZUtVHjrpV76L1buANjwXMfT8w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=22"
+ }
+ },
"node_modules/@cspotcode/source-map-support": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
@@ -2373,21 +2271,21 @@
]
},
"node_modules/@emnapi/core": {
- "version": "1.10.0",
- "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz",
- "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==",
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.1.tgz",
+ "integrity": "sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==",
"dev": true,
"license": "MIT",
"optional": true,
"dependencies": {
- "@emnapi/wasi-threads": "1.2.1",
+ "@emnapi/wasi-threads": "1.2.2",
"tslib": "^2.4.0"
}
},
"node_modules/@emnapi/runtime": {
- "version": "1.10.0",
- "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz",
- "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==",
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.1.tgz",
+ "integrity": "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==",
"dev": true,
"license": "MIT",
"optional": true,
@@ -2396,9 +2294,9 @@
}
},
"node_modules/@emnapi/wasi-threads": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz",
- "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==",
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.2.tgz",
+ "integrity": "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==",
"dev": true,
"license": "MIT",
"optional": true,
@@ -3817,14 +3715,14 @@
}
},
"node_modules/@napi-rs/wasm-runtime": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.5.tgz",
- "integrity": "sha512-AWPoBRJ9tsnVhor4sjO7rkni+7p+2IAEFj6cx06UgP10jkQHqay/36uRV/bFkgrh18D9vb4cr8Q0Pthskgzy+Q==",
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.6.tgz",
+ "integrity": "sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==",
"dev": true,
"license": "MIT",
"optional": true,
"dependencies": {
- "@tybys/wasm-util": "^0.10.2"
+ "@tybys/wasm-util": "^0.10.3"
},
"funding": {
"type": "github",
@@ -3835,19 +3733,6 @@
"@emnapi/runtime": "^1.7.1"
}
},
- "node_modules/@nodable/entities": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/@nodable/entities/-/entities-2.2.0.tgz",
- "integrity": "sha512-9uGyhaQavEUMC8AIddIjau4NsnsXhou+j5sBAGojCM1oxmQpVKTWR/9JxABD6UAv12vpIms55fPZKFQEhG6uBg==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/nodable"
- }
- ],
- "license": "MIT"
- },
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@@ -3893,9 +3778,9 @@
"license": "MIT"
},
"node_modules/@oxc-project/types": {
- "version": "0.133.0",
- "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.133.0.tgz",
- "integrity": "sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA==",
+ "version": "0.139.0",
+ "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.139.0.tgz",
+ "integrity": "sha512-r9gHphtCs+1M7J0pw6Sn/hh/Wpa/iQrOOkrNAlVLF/gHq+/CJmHIWKKUUhdWjcD6CIa8idarspCsASiXCXvFUw==",
"dev": true,
"license": "MIT",
"funding": {
@@ -3968,9 +3853,9 @@
"license": "MIT"
},
"node_modules/@rolldown/binding-android-arm64": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.3.tgz",
- "integrity": "sha512-454rs7jHngixp/NMxd5srYD57OnzSlZ/eFTETjORQHLwJG1lRtmNOJcBerZlfu4GjKqeq8aCCIQrMdHyhI51Hw==",
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.1.5.tgz",
+ "integrity": "sha512-lZg8fqIv2v7FF237bwMgzGZEJvGL79/s5knJ/i6FmsGF4XXlzccZ4jb+TrFIxtSSxFtIpdsgrPZeMk1I9AFcyQ==",
"cpu": [
"arm64"
],
@@ -3985,9 +3870,9 @@
}
},
"node_modules/@rolldown/binding-darwin-arm64": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.3.tgz",
- "integrity": "sha512-PcAhP+ynjURNyy8SKGl5DQP94aGuB/7JrXJb/t7P+hanXvQVMWzUvRRhBAcg/lNRadBhoUPqSoP4xw5tR/KBEA==",
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.1.5.tgz",
+ "integrity": "sha512-51Bnx9pNiMRKSUNtBfySkNJ9vMU9Hh3I1ozDd6gyPPYzaXCfnptUcEZxXGYFn+ul2dtcMUiqGR1Yai2K10uoTw==",
"cpu": [
"arm64"
],
@@ -4002,9 +3887,9 @@
}
},
"node_modules/@rolldown/binding-darwin-x64": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.3.tgz",
- "integrity": "sha512-9YpfeUvSE2RS7wysJ81uOZkXJz7f7Q55H2Gvp3VEw/EsahqDtrphrZ0EwDLK5vvKOzaCrBsjF8JmnMLcUt78Gg==",
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.1.5.tgz",
+ "integrity": "sha512-Tm+gbfC0aHu1tBA/JvKQh32S0K6YgCHkiAF4/W6xX0K0RmNuc94VeK419dJoE65R5aRxmo+noZQSWrAMF6yb6g==",
"cpu": [
"x64"
],
@@ -4019,9 +3904,9 @@
}
},
"node_modules/@rolldown/binding-freebsd-x64": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.3.tgz",
- "integrity": "sha512-yB1IlAsSNHncV6SCTL27/MVGR5htvQsoGxIv5KMGXALp+Ll1wYsn+x98M9MW7qa+NdSbvrrY7ANI4wLJ0n1e6g==",
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.1.5.tgz",
+ "integrity": "sha512-JMzDKCCXq93YccG5gz3hvOs1oXRKAf0XYpfOS88e+wZrC8Iugj6j68867vrYZkvpDDpKn/KoKORThmchMpF6TA==",
"cpu": [
"x64"
],
@@ -4036,9 +3921,9 @@
}
},
"node_modules/@rolldown/binding-linux-arm-gnueabihf": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.3.tgz",
- "integrity": "sha512-Yi30IVAAfLUCy2MseFjbB1jAMDl1VMCAas5StnYp8da9+CKvMd2H2cbEjWcw5NPaPqzvYkVIaF1nNUG+b7u/sw==",
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.1.5.tgz",
+ "integrity": "sha512-uML21j2K5TfPGutKxub+M+nLjZIrWjXQ5Grx4lCe/nimTj9B4L63zHpjXLl4y0L3mcm2htEQIb06oCG/szerNw==",
"cpu": [
"arm"
],
@@ -4053,9 +3938,9 @@
}
},
"node_modules/@rolldown/binding-linux-arm64-gnu": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.3.tgz",
- "integrity": "sha512-jsO7R8To+AdlYgUmN5sHSCZbfhtMBkO0WUx8iORQnPcMMdgr7qM2DQmMwgabs3GhNztdmoKkMKQFHD6DTMCIQw==",
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.1.5.tgz",
+ "integrity": "sha512-navSiuTMogvnQoZoM/v+l3ZWo50/NTwSHSzheABx/RCnmUPaKwq9qSo4Br2OYRs21+Fz8uFqITZM3H4opOB0/Q==",
"cpu": [
"arm64"
],
@@ -4073,9 +3958,9 @@
}
},
"node_modules/@rolldown/binding-linux-arm64-musl": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.3.tgz",
- "integrity": "sha512-VWkUHwWriDciit80wleYwKILoR/KMvxh/IdwS/paX+ZgpuRpCrKLUdadJbc0NpBEiyhpYawsJ73j9aCvOH+f7Q==",
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.1.5.tgz",
+ "integrity": "sha512-lAryqH7IteztmCXQXk0etKj4wBQ7Gx5S6LjKhsgp9zb8I5bsuvU/2llH1hDQcjsFeqIsovMVN339/8pUDDBXxA==",
"cpu": [
"arm64"
],
@@ -4093,9 +3978,9 @@
}
},
"node_modules/@rolldown/binding-linux-ppc64-gnu": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.3.tgz",
- "integrity": "sha512-5f1laC0SlIR0yDbFCd8acUhvJIag6N3zC5P7oUPN6wX0aOma+uKJ0wBDH5aq7I1PVI2ttTlhJwzwRIBnLiSGEg==",
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.1.5.tgz",
+ "integrity": "sha512-fsK/sNBnxzBlL4O1JNrZakVQxPspqpED5dLtNsZS9oOKmtSpdNIzxH2kkol5HYTWJN47sE20ztMJPxfZ89qGOg==",
"cpu": [
"ppc64"
],
@@ -4113,9 +3998,9 @@
}
},
"node_modules/@rolldown/binding-linux-s390x-gnu": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.3.tgz",
- "integrity": "sha512-Iq4ko0r4XsgbrF/LunNgHtAGLRRVE2kXonAXQ/MV0mC6jQpMOhW1SvtZja2EhC/kd05++bP78dsqBeIQyYJ6Yg==",
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.1.5.tgz",
+ "integrity": "sha512-gLYb4BIadlfTOYT5gO503n8zQjXflgzpD0FcyKh0Mzx3rqCZKnHoJWV9xe1KXUJ5lx2JfcSHr/mhzS0PC/McAA==",
"cpu": [
"s390x"
],
@@ -4133,9 +4018,9 @@
}
},
"node_modules/@rolldown/binding-linux-x64-gnu": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.3.tgz",
- "integrity": "sha512-B8m6tD5+/N5FeNQFbKlLA/2yVq9ycQP1SeedyEYYKWBNR3ZQbkvIUcNnDNM03lO1l5F2roiiFJGgvoLLyZXtSg==",
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.1.5.tgz",
+ "integrity": "sha512-FjcpEKUyJygHgs1o50VYNvkt5+7Le/VEdYt0AkRpkL33MnyQfwr8l5mXwMmfmTbyMPr5vJLC+8/Gd9gXnwU1QQ==",
"cpu": [
"x64"
],
@@ -4153,9 +4038,9 @@
}
},
"node_modules/@rolldown/binding-linux-x64-musl": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.3.tgz",
- "integrity": "sha512-pSdpdUJHkuCxun9LE7jvgUB9qsRgaiyNNCX7m/AvHTcq67AiT/Yhoxvw5zPfhrM8k/BfP8ce/hMOpthKDpEUow==",
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.1.5.tgz",
+ "integrity": "sha512-Me+PfPI2TMeOQk0gYWfLQZtTktrmzbr8cDboqX83XKc7UrgAi55gF+2dUkWdxd19n55Essp2yeca+O9N5rBxHg==",
"cpu": [
"x64"
],
@@ -4173,9 +4058,9 @@
}
},
"node_modules/@rolldown/binding-openharmony-arm64": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.3.tgz",
- "integrity": "sha512-OXXS3RKJgX2uLwM+gYyuH5omcH8fL1LJs96pZGgtetVCahON57+d4SJHzTgZiOjxgGkSnpXpOsWuPDGAKAigEg==",
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.1.5.tgz",
+ "integrity": "sha512-yc5WrLzXks6zCQfn9Oxr8pORKyl/pF+QjHmW/Qx3qu0oyrrNC+y2JLTU1E2rcWYAmzlnqngWXHQjy51VzW70Vw==",
"cpu": [
"arm64"
],
@@ -4190,9 +4075,9 @@
}
},
"node_modules/@rolldown/binding-wasm32-wasi": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.3.tgz",
- "integrity": "sha512-JTtb8BWFynicNSoPrehsCzBtOKjZ6jhMiPFEmOiuXg1Fl8dn2KHQob+GuPSGR0dryQa1PQJbzjF3dqO/whhjLg==",
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.1.5.tgz",
+ "integrity": "sha512-VbQGPX2b4r48TAMIM2cjgluIM1HYutm4pcTEJsle7iEP7sB1dFqtPLBVbdLAZCxy1txCcPxf4QFf4v8uvltPqA==",
"cpu": [
"wasm32"
],
@@ -4200,18 +4085,18 @@
"license": "MIT",
"optional": true,
"dependencies": {
- "@emnapi/core": "1.10.0",
- "@emnapi/runtime": "1.10.0",
- "@napi-rs/wasm-runtime": "^1.1.4"
+ "@emnapi/core": "1.11.1",
+ "@emnapi/runtime": "1.11.1",
+ "@napi-rs/wasm-runtime": "^1.1.6"
},
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@rolldown/binding-win32-arm64-msvc": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.3.tgz",
- "integrity": "sha512-gEdFFEN70A/jxb2svrWsN3aDL7OUtmvlOy+6fa2jxG8K0wQ1ZbdeLGnidov6Yu5/733dI5ySfzFlQ/cb0bSz1g==",
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.1.5.tgz",
+ "integrity": "sha512-gHv82k63z4qpV5+Q1y/12KrK0ltWBukVDI8nZcbT7Tt/ZlOIVwppazneq0F93oDxTo3IgAMEDIoQh3E2n6mVsw==",
"cpu": [
"arm64"
],
@@ -4226,9 +4111,9 @@
}
},
"node_modules/@rolldown/binding-win32-x64-msvc": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.3.tgz",
- "integrity": "sha512-eXB7CHuaQdqmJcc3koCNtNPmT/bj2gc999kUFgBxG8Ac0NdgXc4rkCHhqrgrhN3zddvvvrgzj1e90SuSfmyIXA==",
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.1.5.tgz",
+ "integrity": "sha512-tTZuDBPw85tEN5PQi1pnEBzDy0Z49HtScLAbD5t6hyeU92A95pRWaSMw1GZZi/RwgSgUIl0xrSlXIT/9QzvYSA==",
"cpu": [
"x64"
],
@@ -4277,29 +4162,29 @@
"license": "MIT"
},
"node_modules/@simple-libs/child-process-utils": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/@simple-libs/child-process-utils/-/child-process-utils-1.0.2.tgz",
- "integrity": "sha512-/4R8QKnd/8agJynkNdJmNw2MBxuFTRcNFnE5Sg/G+jkSsV8/UBgULMzhizWWW42p8L5H7flImV2ATi79Ove2Tw==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@simple-libs/child-process-utils/-/child-process-utils-2.0.0.tgz",
+ "integrity": "sha512-dvNoRKLijXnD0XoJAz94pbNuB5GQgDr55UhpSPhffDkTT0Cmcqh9jSCOtwfT2d4H6MI9E7c4SgtMuJXZ6F3c6A==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@simple-libs/stream-utils": "^1.2.0"
+ "@simple-libs/stream-utils": "^2.0.0"
},
"engines": {
- "node": ">=18"
+ "node": ">=22"
},
"funding": {
"url": "https://ko-fi.com/dangreen"
}
},
"node_modules/@simple-libs/stream-utils": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/@simple-libs/stream-utils/-/stream-utils-1.2.0.tgz",
- "integrity": "sha512-KxXvfapcixpz6rVEB6HPjOUZT22yN6v0vI0urQSk1L8MlEWPDFCZkhw2xmkyoTGYeFw7tWTZd7e3lVzRZRN/EA==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@simple-libs/stream-utils/-/stream-utils-2.0.0.tgz",
+ "integrity": "sha512-fCTuZK4QBa+39Oz9l4OGfJfz+GpwCp3AqO7Zch3to99xHPgstVsRFpeQ8LNd2o1Gv8raL2mCFwiaHh7bFSp5DQ==",
"dev": true,
"license": "MIT",
"engines": {
- "node": ">=18"
+ "node": ">=22"
},
"funding": {
"url": "https://ko-fi.com/dangreen"
@@ -4379,14 +4264,13 @@
}
},
"node_modules/@smithy/core": {
- "version": "3.25.0",
- "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.25.0.tgz",
- "integrity": "sha512-TTD6el7tvKyafkXBf7XO3jLOE+qVxOTrLjp/fEGiV3BMfUHK/LfdYlQO9YgZvzxC7kqA3H/IhJXNqQgnbgjb7A==",
+ "version": "3.29.3",
+ "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.29.3.tgz",
+ "integrity": "sha512-L+Ys6ecjk5vwPMAKHBpPKlJ3DkqwNcnfEISXBZIsVvWG/XKXfsAP8mwIYlTeLcd2ElHdesPI8OuOmJSFAPhm6A==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@aws-crypto/crc32": "5.2.0",
- "@smithy/types": "^4.15.0",
+ "@smithy/types": "^4.16.1",
"tslib": "^2.6.2"
},
"engines": {
@@ -4394,14 +4278,14 @@
}
},
"node_modules/@smithy/credential-provider-imds": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.4.0.tgz",
- "integrity": "sha512-pPQmNdEvMJttv9z2kdYxoui83p/nr32zjMf0aMfmzmGmFEgKXUfy0vXiNg0fx4R5XLQzmJBLM9Wg0guEq2/q8A==",
+ "version": "4.4.8",
+ "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.4.8.tgz",
+ "integrity": "sha512-q9J7JTiXrAhB8sDp4px97uEPT7CwKH61Co78grdNQvU8QZAdiuaSRhP0tUVf2ogy36RZTrlMU1rBmDEH+cnkiA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@smithy/core": "^3.25.0",
- "@smithy/types": "^4.15.0",
+ "@smithy/core": "^3.29.3",
+ "@smithy/types": "^4.16.1",
"tslib": "^2.6.2"
},
"engines": {
@@ -4409,14 +4293,14 @@
}
},
"node_modules/@smithy/fetch-http-handler": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.5.0.tgz",
- "integrity": "sha512-OG8kBYAgX7lf32+xLzgirvuLffn1KNoszaSiButt45i2cRa5irk8LQXLYQ5Smij1SBTN4KMNcBsRwRrLPfIGyA==",
+ "version": "5.6.5",
+ "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.6.5.tgz",
+ "integrity": "sha512-SuqeisTyPoiIPtIYru/sGxGyXzmZ+8nnFOhC+qRPglt06Ebd1yH//CDltZB2J/3WBNVhwfUaZ0EtHB3cm2X32g==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@smithy/core": "^3.25.0",
- "@smithy/types": "^4.15.0",
+ "@smithy/core": "^3.29.3",
+ "@smithy/types": "^4.16.1",
"tslib": "^2.6.2"
},
"engines": {
@@ -4437,14 +4321,14 @@
}
},
"node_modules/@smithy/node-http-handler": {
- "version": "4.8.0",
- "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.8.0.tgz",
- "integrity": "sha512-Mq7TNt/VhlEWiYRLQGpzUWeUxh899UGpjKh7Ru0WVIDIjnE+cTRAn0NYlFQ6bWfsQnKnpCbWJj86HzmcG0qEdg==",
+ "version": "4.9.5",
+ "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.9.5.tgz",
+ "integrity": "sha512-bNqdxTQTxmLbomSmlkZFz8L6B/feQ2HHzw4L2zY7Ecp2XffYAZq2uzdWDdxJHJFbEvqd+SRuluJso0P8+xPdbw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@smithy/core": "^3.25.0",
- "@smithy/types": "^4.15.0",
+ "@smithy/core": "^3.29.3",
+ "@smithy/types": "^4.16.1",
"tslib": "^2.6.2"
},
"engines": {
@@ -4452,14 +4336,14 @@
}
},
"node_modules/@smithy/signature-v4": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.5.0.tgz",
- "integrity": "sha512-vW6UdK7e7gV2wU/tXRsPq4pMQMusb8VymdVOyIFNA1FtyRmEClRFkYDtYI8UcO/HM0wK3qqjvvQs3HOlbgMbdg==",
+ "version": "5.6.4",
+ "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.6.4.tgz",
+ "integrity": "sha512-B89bpf2t/y/wia6LZ+4JfHXYQT9PnVftsH05rgJKKIStS7r/4XSs9HOjtPoLtgcA6HCW9jVqX5DBbq7E0PAkiQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@smithy/core": "^3.25.0",
- "@smithy/types": "^4.15.0",
+ "@smithy/core": "^3.29.3",
+ "@smithy/types": "^4.16.1",
"tslib": "^2.6.2"
},
"engines": {
@@ -4467,9 +4351,9 @@
}
},
"node_modules/@smithy/types": {
- "version": "4.15.0",
- "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.15.0.tgz",
- "integrity": "sha512-Z5TAOxygoFvybJV3igo5SloFflSokHx2hu1eFA+DxDTcn+FtKxUSui+rbTRG1pAafMA888Z3MVvCWUuvCrTXjg==",
+ "version": "4.16.1",
+ "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.16.1.tgz",
+ "integrity": "sha512-0JFs3V2y2M9tKW5na/qxe69Zv+uxLMO7QBbhxF/FHu/Gp2NFZAAL9tWl9PU02xxo07pb3G9FTyjNc6D5uZrJIg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -4693,75 +4577,18 @@
"license": "Apache-2.0"
},
"node_modules/@sveltejs/acorn-typescript": {
- "version": "1.0.10",
- "resolved": "https://registry.npmjs.org/@sveltejs/acorn-typescript/-/acorn-typescript-1.0.10.tgz",
- "integrity": "sha512-4WfKk68eTih+MiJD4fSbxN7E8kVBmTMPWHUPYjvl2N0rMs53YLTT8/YjKU5Dtnz5LqDjl7LEw4U7lXR2W3J5WA==",
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/@sveltejs/acorn-typescript/-/acorn-typescript-1.0.11.tgz",
+ "integrity": "sha512-LFuZUkjJ9iF7JZye/aG5XM0SFcQ5VyL0oVX4WJ9dc0Va3R3s0OauX1BESVCb+YN/ol8TAfqGDDAQsTG627Y5kw==",
"license": "MIT",
"peerDependencies": {
"acorn": "^8.9.0"
}
},
- "node_modules/@sveltejs/adapter-cloudflare": {
- "version": "7.2.8",
- "resolved": "https://registry.npmjs.org/@sveltejs/adapter-cloudflare/-/adapter-cloudflare-7.2.8.tgz",
- "integrity": "sha512-bIdhY/Fi4AQmqiBdQVKnafH1h9Gw+xbCvHyUu4EouC8rJOU02zwhi14k/FDhQ0mJF1iblIu3m8UNQ8GpGIvIOQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@cloudflare/workers-types": "^4.20250507.0",
- "worktop": "0.8.0-next.18"
- },
- "peerDependencies": {
- "@sveltejs/kit": "^2.0.0",
- "wrangler": "^4.0.0"
- }
- },
- "node_modules/@sveltejs/kit": {
- "version": "2.65.1",
- "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.65.1.tgz",
- "integrity": "sha512-Sa1rFYYqBB+zv3rIxAg/CsFskR/x4aj5BY/hvLxBd9r/mqbipxM945As1K3PqsDicJAyekPR0BlWoVIiw2OHYg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@standard-schema/spec": "^1.0.0",
- "@sveltejs/acorn-typescript": "^1.0.9",
- "@types/cookie": "^0.6.0",
- "acorn": "^8.16.0",
- "cookie": "^0.6.0",
- "devalue": "^5.8.1",
- "esm-env": "^1.2.2",
- "kleur": "^4.1.5",
- "magic-string": "^0.30.5",
- "mrmime": "^2.0.0",
- "set-cookie-parser": "^3.0.0",
- "sirv": "^3.0.0"
- },
- "bin": {
- "svelte-kit": "svelte-kit.js"
- },
- "engines": {
- "node": ">=18.13"
- },
- "peerDependencies": {
- "@opentelemetry/api": "^1.0.0",
- "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0 || ^7.0.0",
- "svelte": "^4.0.0 || ^5.0.0-next.0",
- "typescript": "^5.3.3 || ^6.0.0",
- "vite": "^5.0.3 || ^6.0.0 || ^7.0.0-beta.0 || ^8.0.0"
- },
- "peerDependenciesMeta": {
- "@opentelemetry/api": {
- "optional": true
- },
- "typescript": {
- "optional": true
- }
- }
- },
"node_modules/@sveltejs/vite-plugin-svelte": {
- "version": "7.1.2",
- "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-7.1.2.tgz",
- "integrity": "sha512-DrUBA2UXRfDmUX/ZTiEopd3X40yavsJF1FX2RygcuIScHL7o5YX1fMvoYnDhjeJQC4weCOklirpNWlcb2NiSeA==",
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-7.2.0.tgz",
+ "integrity": "sha512-1SpkuMSRLfugrVX+IrKfE1RUegzo8AQzKQ6qQPfVzbcWi5IhuTPaKb5ZrLpucleFznkc4/RTeSPoRnGWFxX+EQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4788,9 +4615,9 @@
}
},
"node_modules/@tybys/wasm-util": {
- "version": "0.10.2",
- "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz",
- "integrity": "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==",
+ "version": "0.10.3",
+ "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.3.tgz",
+ "integrity": "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==",
"dev": true,
"license": "MIT",
"optional": true,
@@ -4845,9 +4672,9 @@
}
},
"node_modules/@types/hast": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz",
- "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==",
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.5.tgz",
+ "integrity": "sha512-rp/ezSWaD1m44dPKICGhiskI13nVr7qTloFwDa/IYkhhf5nzwP+zIQcIJh3WIFSBOy/H1PzB40jPjMDksN4F+g==",
"license": "MIT",
"dependencies": {
"@types/unist": "*"
@@ -4877,9 +4704,9 @@
"license": "MIT"
},
"node_modules/@types/node": {
- "version": "25.9.3",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-25.9.3.tgz",
- "integrity": "sha512-603BddQMv3pUcr4U2dhujk83N2tTDVr/34wII2B6bJy6g+8WD6yUb11jszNs0gdi4PesVWl7ABt8nYMVpnLUcg==",
+ "version": "25.9.5",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-25.9.5.tgz",
+ "integrity": "sha512-OScDchr2fwuUmWdf4kZ9h7PcJiYDVInhJizG/biAq3cAvqwYktuy/TYGGdZNMtNTFUP7rnb0NU4TUdm82kt4Rg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4915,32 +4742,392 @@
"integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==",
"license": "MIT"
},
- "node_modules/@ungap/custom-elements": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/@ungap/custom-elements/-/custom-elements-1.3.0.tgz",
- "integrity": "sha512-f4q/s76+8nOy+fhrNHyetuoPDR01lmlZB5czfCG+OOnBw/Wf+x48DcCDPmMQY7oL8xYFL8qfenMoiS8DUkKBUw==",
- "license": "ISC"
+ "node_modules/@typescript/typescript-aix-ppc64": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/@typescript/typescript-aix-ppc64/-/typescript-aix-ppc64-7.0.2.tgz",
+ "integrity": "sha512-MTKKkWB7p/0E9xi1d1tHtZ5PiLkGEMIq88pK2CubZjOsLtYTLqhgIgi6zepFa+9GHZ6h05NMCkQxGKiPXMxXtQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "peer": true,
+ "engines": {
+ "node": ">=16.20.0"
+ }
},
- "node_modules/@willfarrell-ds/cli": {
- "version": "0.0.0-alpha.6",
- "resolved": "https://registry.npmjs.org/@willfarrell-ds/cli/-/cli-0.0.0-alpha.6.tgz",
- "integrity": "sha512-CIEnRyopUAil0yPrAYqg8jEnSwc1dzIe5LQbi0/ghuWukSHrwcrWGoqBwTfuBOddg3087kIHj3YXHyJncOG1qw==",
+ "node_modules/@typescript/typescript-darwin-arm64": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/@typescript/typescript-darwin-arm64/-/typescript-darwin-arm64-7.0.2.tgz",
+ "integrity": "sha512-gowzar9MwS/aRWp6f3a4KUqzRjAZjOsmGNCM6LcTgXum+dBfgsBVMN+AgvOCCbguXyick6LJhpBszxMebJ8syA==",
+ "cpu": [
+ "arm64"
+ ],
"dev": true,
- "license": "MIT",
- "dependencies": {
- "color-convert": "3.1.3",
- "commander": "14.0.3",
- "mathjs": "15.1.1"
- },
- "bin": {
- "ds": "index.js"
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "peer": true,
+ "engines": {
+ "node": ">=16.20.0"
}
},
- "node_modules/@willfarrell-ds/svelte": {
- "version": "0.0.0-alpha.6",
- "resolved": "https://registry.npmjs.org/@willfarrell-ds/svelte/-/svelte-0.0.0-alpha.6.tgz",
- "integrity": "sha512-6xnvXlOWj6h/kWIx6RG0J28XmmwMTIVp6zxqeZlmifymS8l28G8qsg2tCHyaN+09gw7hTvLoQ2P4wCF2FMr9HA==",
- "license": "MIT",
+ "node_modules/@typescript/typescript-darwin-x64": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/@typescript/typescript-darwin-x64/-/typescript-darwin-x64-7.0.2.tgz",
+ "integrity": "sha512-SZ9xZInqApNlNGc9s0W1VSsktYSOe9cFqNOIqmN1Gs8SmkjKZYFt017G4VwPxASInODuAdbTW7sXiFUf893RgA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "peer": true,
+ "engines": {
+ "node": ">=16.20.0"
+ }
+ },
+ "node_modules/@typescript/typescript-freebsd-arm64": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/@typescript/typescript-freebsd-arm64/-/typescript-freebsd-arm64-7.0.2.tgz",
+ "integrity": "sha512-W5NH4y/J0plIIS5b2xvTEkU7JFxyqdMAOgf+Ilhl0vHQXKO5dZoxd+C/jEtq56c4F3wk71RB4BMRQ2XdI+bwYQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "peer": true,
+ "engines": {
+ "node": ">=16.20.0"
+ }
+ },
+ "node_modules/@typescript/typescript-freebsd-x64": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/@typescript/typescript-freebsd-x64/-/typescript-freebsd-x64-7.0.2.tgz",
+ "integrity": "sha512-UMGDx5sTpzNw3WiPebH7l90IWfJggEd+egHt/q6p7/Cm3zqoV7VxkGXt+3DxPIw8CcmvAB0j3sVVfbhX+M4Tpw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "peer": true,
+ "engines": {
+ "node": ">=16.20.0"
+ }
+ },
+ "node_modules/@typescript/typescript-linux-arm": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-arm/-/typescript-linux-arm-7.0.2.tgz",
+ "integrity": "sha512-gffT3xPz9sR7j/YJExkyPntrI0P2EP9XbOyWzth2/Gs0RstK+90RBcO0ncXoXy/beYll1SXw846Nf2zdnEz0QQ==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "peer": true,
+ "engines": {
+ "node": ">=16.20.0"
+ }
+ },
+ "node_modules/@typescript/typescript-linux-arm64": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-arm64/-/typescript-linux-arm64-7.0.2.tgz",
+ "integrity": "sha512-Qh4eU4/y3yDjnfjjyPYihMj5/ODIlmt+Bzu17OI+fiSRDW57QmU5SiN63exPRNJPKUzcc1INa1NXdrJ+MqHjUQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "peer": true,
+ "engines": {
+ "node": ">=16.20.0"
+ }
+ },
+ "node_modules/@typescript/typescript-linux-loong64": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-loong64/-/typescript-linux-loong64-7.0.2.tgz",
+ "integrity": "sha512-uEHck9i8hoAzXPiYRib1O7miOnz23SxIeVl6F4LXox+qov1K35jHcEW6VHKvZI+pyvl7fZEP4MCU5LYvIq1GuQ==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "peer": true,
+ "engines": {
+ "node": ">=16.20.0"
+ }
+ },
+ "node_modules/@typescript/typescript-linux-mips64el": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-mips64el/-/typescript-linux-mips64el-7.0.2.tgz",
+ "integrity": "sha512-R4KvAMnE43W5Qeqb0Ly56O3mWMWIAgsMyz36DCaycd5nbg/9kzm0liw3JocfRqyJY0KPmzFjbswozXyW0DnIYA==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "peer": true,
+ "engines": {
+ "node": ">=16.20.0"
+ }
+ },
+ "node_modules/@typescript/typescript-linux-ppc64": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-ppc64/-/typescript-linux-ppc64-7.0.2.tgz",
+ "integrity": "sha512-DORx5b3sd/4S7eayxm4FQv+A7CrkUIGRaHiwI8oiHTAI1fAPWhF4J0vAlkC8biAlHSVVwxMQ3tjZ2/DVbnQiiA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "peer": true,
+ "engines": {
+ "node": ">=16.20.0"
+ }
+ },
+ "node_modules/@typescript/typescript-linux-riscv64": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-riscv64/-/typescript-linux-riscv64-7.0.2.tgz",
+ "integrity": "sha512-wf0jqEDOjrPRnKwYRyyJDRo11KMbvMFrU+q4zqKyChODBzvlkbhNQfKvLxQCcwTpdDaXSHZTVuh0JoCrKCUMHQ==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "peer": true,
+ "engines": {
+ "node": ">=16.20.0"
+ }
+ },
+ "node_modules/@typescript/typescript-linux-s390x": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-s390x/-/typescript-linux-s390x-7.0.2.tgz",
+ "integrity": "sha512-IkwJc3L7yhytWd/ewjyxNDfOmswCm9GWMJT/ue/dU4aZNbwZeYAetq42VyLmsmSjvoX7z74X6ZaYCtzAr0EuGw==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "peer": true,
+ "engines": {
+ "node": ">=16.20.0"
+ }
+ },
+ "node_modules/@typescript/typescript-linux-x64": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-x64/-/typescript-linux-x64-7.0.2.tgz",
+ "integrity": "sha512-EYdf2cNg7rgCWJnxCdJ+F3V39O8ihb37eHAu1LK8oAFizgTQbPOK7zHHXbPt8rX24COqODXeI3sIf0fCXG7H/A==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "peer": true,
+ "engines": {
+ "node": ">=16.20.0"
+ }
+ },
+ "node_modules/@typescript/typescript-netbsd-arm64": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/@typescript/typescript-netbsd-arm64/-/typescript-netbsd-arm64-7.0.2.tgz",
+ "integrity": "sha512-+polYF4MF04aPpO5FTkHran9yUQDSXqy5GiSDKpsll5jy3l3+g9QLhpf39T+ePtefhXLOGrLl0QIjkQP6VnelA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "peer": true,
+ "engines": {
+ "node": ">=16.20.0"
+ }
+ },
+ "node_modules/@typescript/typescript-netbsd-x64": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/@typescript/typescript-netbsd-x64/-/typescript-netbsd-x64-7.0.2.tgz",
+ "integrity": "sha512-8YIT0EHM/3dq10ZOVF/A7pc/YSMtbcecct4rWtexrnSCHOPcpC2KTLXfTCR6vDpnSiY12heNb1GiN/wu+T/FyA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "peer": true,
+ "engines": {
+ "node": ">=16.20.0"
+ }
+ },
+ "node_modules/@typescript/typescript-openbsd-arm64": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/@typescript/typescript-openbsd-arm64/-/typescript-openbsd-arm64-7.0.2.tgz",
+ "integrity": "sha512-APT8+ClYnuYm1u9+kgGXoMj2VzWzcymwh2gNSQVySHfkRDGOTVkoWLjCmOQSaO+PoqQ57B0flRp9SA+7GnnkzQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "peer": true,
+ "engines": {
+ "node": ">=16.20.0"
+ }
+ },
+ "node_modules/@typescript/typescript-openbsd-x64": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/@typescript/typescript-openbsd-x64/-/typescript-openbsd-x64-7.0.2.tgz",
+ "integrity": "sha512-yX7s+Q0Dln0Dt9tEzZsAjXXR/+ytBM7AlglaqyeMPxQszJ1JhlJdZ6jLA+IzldHtflX81em7lDao1xXu+aRRkg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "peer": true,
+ "engines": {
+ "node": ">=16.20.0"
+ }
+ },
+ "node_modules/@typescript/typescript-sunos-x64": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/@typescript/typescript-sunos-x64/-/typescript-sunos-x64-7.0.2.tgz",
+ "integrity": "sha512-dLJDGaLZ1D4HPQn62u1n8mBDkJREwMsAkCdkwd4Ieqw+x3TUyTsqY0YiBCtE6H6OzzgGk3iuZ3vFWRS+E8/d1g==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "peer": true,
+ "engines": {
+ "node": ">=16.20.0"
+ }
+ },
+ "node_modules/@typescript/typescript-win32-arm64": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/@typescript/typescript-win32-arm64/-/typescript-win32-arm64-7.0.2.tgz",
+ "integrity": "sha512-Gyl1Vy6OsWesLzmq+EP0Fb7b4Nid5232AvcA2SFcdYreldpNtYFFofPjnt62y9hQy7VTaZp65ICJjuAQRaVcIQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "peer": true,
+ "engines": {
+ "node": ">=16.20.0"
+ }
+ },
+ "node_modules/@typescript/typescript-win32-x64": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/@typescript/typescript-win32-x64/-/typescript-win32-x64-7.0.2.tgz",
+ "integrity": "sha512-0BQ3HkAHHlKLSp1qRvf3SUhGpGsDuhB/jgFw75guyqbxJqEaS0Cw/VFO8i2nHglJUzQCRtMMR/IBAKE3ETMC4g==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "peer": true,
+ "engines": {
+ "node": ">=16.20.0"
+ }
+ },
+ "node_modules/@ungap/custom-elements": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/@ungap/custom-elements/-/custom-elements-1.3.0.tgz",
+ "integrity": "sha512-f4q/s76+8nOy+fhrNHyetuoPDR01lmlZB5czfCG+OOnBw/Wf+x48DcCDPmMQY7oL8xYFL8qfenMoiS8DUkKBUw==",
+ "license": "ISC"
+ },
+ "node_modules/@willfarrell-ds/cli": {
+ "version": "0.0.0-alpha.6",
+ "resolved": "https://registry.npmjs.org/@willfarrell-ds/cli/-/cli-0.0.0-alpha.6.tgz",
+ "integrity": "sha512-CIEnRyopUAil0yPrAYqg8jEnSwc1dzIe5LQbi0/ghuWukSHrwcrWGoqBwTfuBOddg3087kIHj3YXHyJncOG1qw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "3.1.3",
+ "commander": "14.0.3",
+ "mathjs": "15.1.1"
+ },
+ "bin": {
+ "ds": "index.js"
+ }
+ },
+ "node_modules/@willfarrell-ds/svelte": {
+ "version": "0.0.0-alpha.6",
+ "resolved": "https://registry.npmjs.org/@willfarrell-ds/svelte/-/svelte-0.0.0-alpha.6.tgz",
+ "integrity": "sha512-6xnvXlOWj6h/kWIx6RG0J28XmmwMTIVp6zxqeZlmifymS8l28G8qsg2tCHyaN+09gw7hTvLoQ2P4wCF2FMr9HA==",
+ "license": "MIT",
"dependencies": {
"@willfarrell-ds/vanilla": "0.0.0-alpha.6",
"pretty": "2.0.0",
@@ -5163,19 +5350,6 @@
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
- "node_modules/anynum": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/anynum/-/anynum-1.0.0.tgz",
- "integrity": "sha512-xjR9/zBVnUOP6ztMIIgShjsxui80nQUQH+5xJnvrYLs+90bF25/KJqaAi8mk+B4RDtX1Nspi6fmp4YTEts8SfA==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/NaturalIntelligence"
- }
- ],
- "license": "MIT"
- },
"node_modules/apache-arrow": {
"version": "21.1.0",
"resolved": "https://registry.npmjs.org/apache-arrow/-/apache-arrow-21.1.0.tgz",
@@ -5197,9 +5371,9 @@
}
},
"node_modules/apache-arrow/node_modules/@types/node": {
- "version": "24.13.2",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-24.13.2.tgz",
- "integrity": "sha512-fRa09kZTgu8o71KFcDjUFuc7F+dEbZYZmkI0mg5YBTRs0yMKjYHsq/c0urDKeDb+D5qVgXOdFcuu+DZPKOITwA==",
+ "version": "24.13.3",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-24.13.3.tgz",
+ "integrity": "sha512-Dh8vAsV36ig5wa9OX4pXvMc9D3Veibfw2wix0CUwYODLD8nkj9UsLjASr49nPg+2eKzxhBV+v7L8pXvT4e639Q==",
"license": "MIT",
"dependencies": {
"undici-types": "~7.18.0"
@@ -5217,6 +5391,19 @@
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
"license": "Python-2.0"
},
+ "node_modules/argue-cli": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/argue-cli/-/argue-cli-3.1.0.tgz",
+ "integrity": "sha512-DhBpBfXL4SS2uC0N922MMajKR3CdrTG0u2or1PNYgXMsrSzViJrbtvT0nCLlLGUI0plam/ZZCs7aAauHtW9thw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=22"
+ },
+ "funding": {
+ "url": "https://ko-fi.com/dangreen"
+ }
+ },
"node_modules/aria-query": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.1.tgz",
@@ -5235,13 +5422,6 @@
"node": ">=12.17"
}
},
- "node_modules/array-ify": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz",
- "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/array-union": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
@@ -5270,44 +5450,6 @@
"node": ">=14.x"
}
},
- "node_modules/aws-msk-iam-sasl-signer-js/node_modules/@aws-crypto/sha256-js": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-4.0.0.tgz",
- "integrity": "sha512-MHGJyjE7TX9aaqXj7zk2ppnFUOhaDs5sP+HtNS0evOxn72c+5njUmyJmpGd7TfyoDznZlHMmdo/xGUdu2NIjNQ==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@aws-crypto/util": "^4.0.0",
- "@aws-sdk/types": "^3.222.0",
- "tslib": "^1.11.1"
- }
- },
- "node_modules/aws-msk-iam-sasl-signer-js/node_modules/@aws-crypto/sha256-js/node_modules/tslib": {
- "version": "1.14.1",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
- "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
- "dev": true,
- "license": "0BSD"
- },
- "node_modules/aws-msk-iam-sasl-signer-js/node_modules/@aws-crypto/util": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-4.0.0.tgz",
- "integrity": "sha512-2EnmPy2gsFZ6m8bwUQN4jq+IyXV3quHAcwPOS6ZA3k+geujiqI8aRokO2kFJe+idJ/P3v4qWI186rVMo0+zLDQ==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@aws-sdk/types": "^3.222.0",
- "@aws-sdk/util-utf8-browser": "^3.0.0",
- "tslib": "^1.11.1"
- }
- },
- "node_modules/aws-msk-iam-sasl-signer-js/node_modules/@aws-crypto/util/node_modules/tslib": {
- "version": "1.14.1",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
- "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
- "dev": true,
- "license": "0BSD"
- },
"node_modules/aws-msk-iam-sasl-signer-js/node_modules/@smithy/signature-v4": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-2.3.0.tgz",
@@ -5393,9 +5535,9 @@
"license": "MIT"
},
"node_modules/baseline-browser-mapping": {
- "version": "2.10.37",
- "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.37.tgz",
- "integrity": "sha512-girxaJ7WZssDOFhzCGZTDKoTa1gk6A1TbflaYTpykLJ4UU9Fz9kx1aREM8JCuoVHbL8X8T/mJg7w2oYSq72Oig==",
+ "version": "2.10.43",
+ "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.43.tgz",
+ "integrity": "sha512-AjYpR78kDWAY3Efj+cDTFH9t9SCoL7OoTp1BOb0mQV7S+6CiLwnWM3FyxhJtdPufDFKzmCSFoUncKjWgJEZTCQ==",
"dev": true,
"license": "Apache-2.0",
"bin": {
@@ -5427,9 +5569,9 @@
"license": "MIT"
},
"node_modules/brace-expansion": {
- "version": "5.0.6",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz",
- "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==",
+ "version": "5.0.7",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.7.tgz",
+ "integrity": "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5463,9 +5605,9 @@
}
},
"node_modules/browserslist": {
- "version": "4.28.2",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz",
- "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==",
+ "version": "4.28.5",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.5.tgz",
+ "integrity": "sha512-Cu2E6QejHWzuDMTkuwgpABFgDfZrXLQq5V13YOACZx4mFAG4IwGTbTfHPMr4WtxlHoXSM8FIuRwYYCz5XiabaQ==",
"dev": true,
"funding": [
{
@@ -5483,10 +5625,10 @@
],
"license": "MIT",
"dependencies": {
- "baseline-browser-mapping": "^2.10.12",
- "caniuse-lite": "^1.0.30001782",
- "electron-to-chromium": "^1.5.328",
- "node-releases": "^2.0.36",
+ "baseline-browser-mapping": "^2.10.42",
+ "caniuse-lite": "^1.0.30001800",
+ "electron-to-chromium": "^1.5.387",
+ "node-releases": "^2.0.50",
"update-browserslist-db": "^1.2.3"
},
"bin": {
@@ -5559,9 +5701,9 @@
}
},
"node_modules/caniuse-lite": {
- "version": "1.0.30001799",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001799.tgz",
- "integrity": "sha512-hG1bReV+OUU+MOqK4t/ZWI0tZOyz3rqS9XuhOUz1cIcbwBKjOyJEJuw9ER5JuNyqxNk8u/JUVbGibBOL1yrjFw==",
+ "version": "1.0.30001803",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001803.tgz",
+ "integrity": "sha512-g/uHREV2ZpK9qMalCsWaxmA6ol+DX8GYhuf3T40RKoP+oL7vhRJh8LNt73PCjpnR6l14FzfPrB5Yux4PKm2meg==",
"dev": true,
"funding": [
{
@@ -5663,9 +5805,10 @@
"license": "MIT"
},
"node_modules/chardet": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.1.tgz",
- "integrity": "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==",
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.2.0.tgz",
+ "integrity": "sha512-rddelWYNPRrXq6PtNEN2S3f6t9ILzvqaN5pVgi4kqt9jHQaXIial9PznB5iSPVlQSLNaaH22ItWz3EJtQ10+OA==",
+ "dev": true,
"license": "MIT"
},
"node_modules/cheerio": {
@@ -5826,17 +5969,6 @@
"node": ">=20"
}
},
- "node_modules/compare-func": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz",
- "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "array-ify": "^1.0.0",
- "dot-prop": "^5.1.0"
- }
- },
"node_modules/complex.js": {
"version": "2.4.3",
"resolved": "https://registry.npmjs.org/complex.js/-/complex.js-2.4.3.tgz",
@@ -5882,46 +6014,46 @@
"license": "ISC"
},
"node_modules/conventional-changelog-angular": {
- "version": "8.3.1",
- "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-8.3.1.tgz",
- "integrity": "sha512-6gfI3otXK5Ph5DfCOI1dblr+kN3FAm5a97hYoQkqNZxOaYa5WKfXH+AnpsmS+iUH2mgVC2Cg2Qw9m5OKcmNrIg==",
+ "version": "9.2.1",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-9.2.1.tgz",
+ "integrity": "sha512-oWSL6ZhnXbYraOFTK3PgRAQJ8fADDAEv5K6AdeyQPLvjFmhG8+ejL0jZZp/R7vTmGJaBvZEE+sE7dB4bCv7sAw==",
"dev": true,
"license": "ISC",
"dependencies": {
- "compare-func": "^2.0.0"
+ "@conventional-changelog/template": "^1.2.1"
},
"engines": {
- "node": ">=18"
+ "node": ">=22"
}
},
"node_modules/conventional-changelog-conventionalcommits": {
- "version": "9.3.1",
- "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-9.3.1.tgz",
- "integrity": "sha512-dTYtpIacRpcZgrvBYvBfArMmK2xvIpv2TaxM0/ZI5CBtNUzvF2x0t15HsbRABWprS6UPmvj+PzHVjSx4qAVKyw==",
+ "version": "10.2.1",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-10.2.1.tgz",
+ "integrity": "sha512-n4Kr1HFMTf3iMbES0TMxKIcYtUUv4rKqyQQp2JwfOEfFCOfGT3Tq4mCyJ8S9/YPyWhydjfKrrvnyl+gCjA+mJQ==",
"dev": true,
"license": "ISC",
"dependencies": {
- "compare-func": "^2.0.0"
+ "@conventional-changelog/template": "^1.2.1"
},
"engines": {
- "node": ">=18"
+ "node": ">=22"
}
},
"node_modules/conventional-commits-parser": {
- "version": "6.4.0",
- "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-6.4.0.tgz",
- "integrity": "sha512-tvRg7FIBNlyPzjdG8wWRlPHQJJHI7DylhtRGeU9Lq+JuoPh5BKpPRX83ZdLrvXuOSu5Eo/e7SzOQhU4Hd2Miuw==",
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-7.1.0.tgz",
+ "integrity": "sha512-DPp6hkUjvwIivxbkrTiLXeRswNv1A/4GFA2X6scXma0AMa9632V3TwxmrlkUIEtUktiM3Ln+RrSH2xlP3/jUTw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@simple-libs/stream-utils": "^1.2.0",
- "meow": "^13.0.0"
+ "@simple-libs/stream-utils": "^2.0.0",
+ "argue-cli": "^3.1.0"
},
"bin": {
"conventional-commits-parser": "dist/cli/index.js"
},
"engines": {
- "node": ">=18"
+ "node": ">=22"
}
},
"node_modules/convert-source-map": {
@@ -5932,13 +6064,17 @@
"license": "MIT"
},
"node_modules/cookie": {
- "version": "0.7.2",
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
- "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz",
+ "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==",
"dev": true,
"license": "MIT",
"engines": {
- "node": ">= 0.6"
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
}
},
"node_modules/cosmiconfig": {
@@ -6251,19 +6387,6 @@
"url": "https://github.com/fb55/domutils?sponsor=1"
}
},
- "node_modules/dot-prop": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz",
- "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "is-obj": "^2.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/dunder-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
@@ -6310,9 +6433,9 @@
"license": "MIT"
},
"node_modules/editorconfig/node_modules/brace-expansion": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.1.tgz",
- "integrity": "sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==",
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.2.tgz",
+ "integrity": "sha512-w5JZcKgdhDOgOwm8H+KgbosopHMuGcl6qbulwjtz3SM7I7P3yW1eAjzMPLrIE+NQ9vjgANKHWeMHnrT0OXW1oA==",
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0"
@@ -6343,9 +6466,9 @@
}
},
"node_modules/electron-to-chromium": {
- "version": "1.5.372",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.372.tgz",
- "integrity": "sha512-M3yhbAlilnwqC8D21t28UCDGHyitShTmmLRU/H+b74P6Ski16Nb9HONYEaVpMj/pwC7BEo5B95FpjODLCWbtfA==",
+ "version": "1.5.389",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.389.tgz",
+ "integrity": "sha512-cEto7aeOqBfU1D+c5py5pE+ooscKE75JifxLBdFUZsqAxRS6y7kebtxAZvICszSl05gPjYHDTjY+lXpyGvpJbg==",
"dev": true,
"license": "ISC"
},
@@ -6460,9 +6583,9 @@
}
},
"node_modules/es-toolkit": {
- "version": "1.47.1",
- "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.47.1.tgz",
- "integrity": "sha512-5RAqEwf4P4E17p+W75KLOWw/nOvKZzSQpxM32IpI2KZLaVonjTrZ0Ai5ghMaVI9eKC2p8eoQgcBdkEDgzFk6+Q==",
+ "version": "1.49.0",
+ "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.49.0.tgz",
+ "integrity": "sha512-G5iZ6Pc/FNRY/soKZHC+TxGDD83rHUDXxzaWhGCX44vAv/tMs56WMusnm/KMNK+luUPsgA9U28cGr4RDlSzL2g==",
"dev": true,
"license": "MIT",
"workspaces": [
@@ -6535,9 +6658,9 @@
"license": "MIT"
},
"node_modules/esrap": {
- "version": "2.2.11",
- "resolved": "https://registry.npmjs.org/esrap/-/esrap-2.2.11.tgz",
- "integrity": "sha512-gPdx+I+BjYEinNMQaBXFjbaJVyoPMU4ZODg5mE+M4DqVG9VusAVHHjcBX+zqyITlI0DIARwDMMzZwAWj36dRoQ==",
+ "version": "2.2.13",
+ "resolved": "https://registry.npmjs.org/esrap/-/esrap-2.2.13.tgz",
+ "integrity": "sha512-m8jH5hZgJE2RRUK/jjkGPcJEDAV+dYnZYFkosQaPTcE+Yw4xynXHOo6FUdwaWBtdR3b1MMa7wEDTSHeR2VWsGA==",
"license": "MIT",
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.4.15"
@@ -6601,9 +6724,9 @@
}
},
"node_modules/fast-check": {
- "version": "4.8.0",
- "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-4.8.0.tgz",
- "integrity": "sha512-GOJ158CUMnN6cSahsv4+ExARvIDuzzinFjkp0E9WtiBa5zcVeLozVkWaE4IzFcc+Y48Wp1EDlUZsXRyAztQcSg==",
+ "version": "4.9.0",
+ "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-4.9.0.tgz",
+ "integrity": "sha512-7ms6T7SybUev/PQITciI0yLM2pOSFy5zpG8Ty7tQofcVaQUvrMXp6CBwqF6fThLCLOrfBtuHAtwq6Yu4XPCllg==",
"dev": true,
"funding": [
{
@@ -6664,9 +6787,9 @@
}
},
"node_modules/fast-uri": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz",
- "integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==",
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.3.tgz",
+ "integrity": "sha512-i70LwGWUduXqzicKXWshooq+sWL1K3WUU5rKZNG/0i3a1OSoX3HqhH5WbWwTmqWfor4urUakGPiRQcleRZTwOg==",
"funding": [
{
"type": "github",
@@ -6689,45 +6812,6 @@
"fast-string-width": "^3.0.2"
}
},
- "node_modules/fast-xml-builder": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.2.0.tgz",
- "integrity": "sha512-00aAWieqff+ZJhsXA4g1g7M8k+7AYoMUUHF+/zFb5U6Uv/P0Vl4QZo84/IcufzYalLuEj9928bXN9PbbFzMF0Q==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/NaturalIntelligence"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "path-expression-matcher": "^1.5.0",
- "xml-naming": "^0.1.0"
- }
- },
- "node_modules/fast-xml-parser": {
- "version": "5.7.3",
- "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.7.3.tgz",
- "integrity": "sha512-C0AaNuC+mscy6vrAQKAc/rMq+zAPHodfHGZu4sGVehvAQt/JLG1O5zEcYcXSY5zSqr4YVgxsB+pHXTq0i7eDlg==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/NaturalIntelligence"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "@nodable/entities": "^2.1.0",
- "fast-xml-builder": "^1.1.7",
- "path-expression-matcher": "^1.5.0",
- "strnum": "^2.2.3"
- },
- "bin": {
- "fxparser": "src/cli/cli.js"
- }
- },
"node_modules/fastq": {
"version": "1.20.1",
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz",
@@ -6993,23 +7077,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/git-raw-commits": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-5.0.1.tgz",
- "integrity": "sha512-Y+csSm2GD/PCSh6Isd/WiMjNAydu0VBiG9J7EdQsNA5P9uXvLayqjmTsNlK5Gs9IhblFZqOU0yid5Il5JPoLiQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@conventional-changelog/git-client": "^2.6.0",
- "meow": "^13.0.0"
- },
- "bin": {
- "git-raw-commits": "src/cli.js"
- },
- "engines": {
- "node": ">=18"
- }
- },
"node_modules/gitignore-to-glob": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/gitignore-to-glob/-/gitignore-to-glob-0.3.0.tgz",
@@ -7225,9 +7292,10 @@
}
},
"node_modules/iconv-lite": {
- "version": "0.7.2",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz",
- "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==",
+ "version": "0.7.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.3.tgz",
+ "integrity": "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"safer-buffer": ">= 2.1.2 < 3.0.0"
@@ -7397,16 +7465,6 @@
"node": ">=0.12.0"
}
},
- "node_modules/is-obj": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz",
- "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/is-plain-obj": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz",
@@ -7530,9 +7588,9 @@
"license": "MIT"
},
"node_modules/js-beautify/node_modules/brace-expansion": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.1.tgz",
- "integrity": "sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==",
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.2.tgz",
+ "integrity": "sha512-w5JZcKgdhDOgOwm8H+KgbosopHMuGcl6qbulwjtz3SM7I7P3yW1eAjzMPLrIE+NQ9vjgANKHWeMHnrT0OXW1oA==",
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0"
@@ -7595,9 +7653,9 @@
"license": "MIT"
},
"node_modules/js-yaml": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.2.0.tgz",
- "integrity": "sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==",
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.0.tgz",
+ "integrity": "sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==",
"funding": [
{
"type": "github",
@@ -8351,9 +8409,9 @@
}
},
"node_modules/lockfile-lint/node_modules/yargs": {
- "version": "17.7.2",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
- "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
+ "version": "17.7.3",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.3.tgz",
+ "integrity": "sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -8497,19 +8555,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/meow": {
- "version": "13.2.0",
- "resolved": "https://registry.npmjs.org/meow/-/meow-13.2.0.tgz",
- "integrity": "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/merge2": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
@@ -8535,17 +8580,17 @@
}
},
"node_modules/miniflare": {
- "version": "4.20260611.0",
- "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-4.20260611.0.tgz",
- "integrity": "sha512-i+JwEo8vN96naz1WL3ntFgFyRluBDYL408zwhHKvR2jefJ464KsZ/gCmJAQ5k+oaWeb5Ug+s7yne5AyiAEswjg==",
+ "version": "4.20260708.1",
+ "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-4.20260708.1.tgz",
+ "integrity": "sha512-c94O9zRDISdqO18EHt6l0iF/fWgWt8p18PJvRsA/L/NJZ9Cfke3s/F5Blg1XXF7WDutVRzWVWy8Vy4LaT5ifsA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@cspotcode/source-map-support": "0.8.1",
"sharp": "0.34.5",
- "undici": "7.24.8",
- "workerd": "1.20260611.1",
- "ws": "8.20.1",
+ "undici": "7.28.0",
+ "workerd": "1.20260708.1",
+ "ws": "8.21.0",
"youch": "4.1.0-beta.10"
},
"bin": {
@@ -8556,9 +8601,9 @@
}
},
"node_modules/miniflare/node_modules/undici": {
- "version": "7.24.8",
- "resolved": "https://registry.npmjs.org/undici/-/undici-7.24.8.tgz",
- "integrity": "sha512-6KQ/+QxK49Z/p3HO6E5ZCZWNnCasyZLa5ExaVYyvPxUwKtbCPMKELJOqh7EqOle0t9cH/7d2TaaTRRa6Nhs4YQ==",
+ "version": "7.28.0",
+ "resolved": "https://registry.npmjs.org/undici/-/undici-7.28.0.tgz",
+ "integrity": "sha512-cRZYrTDwWznlnRiPjggAGxZXanty6M8RV1ff8Wm4LWXBp7/IG8v5DnOm74DtUBp9OONpK75YlPnIjQqX0dBDtA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -8678,9 +8723,9 @@
}
},
"node_modules/nanoid": {
- "version": "3.3.12",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz",
- "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==",
+ "version": "3.3.15",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.15.tgz",
+ "integrity": "sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==",
"dev": true,
"funding": [
{
@@ -8769,9 +8814,9 @@
}
},
"node_modules/node-releases": {
- "version": "2.0.47",
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.47.tgz",
- "integrity": "sha512-Uzmd6LXpouKo8EUK68IjH4+E01w/hXyV3R3g/geCJo+rXLNfh1xucB+LOzYEOQPSiUK3h/xZf0cQGcSsmyL2Og==",
+ "version": "2.0.51",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.51.tgz",
+ "integrity": "sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -9043,22 +9088,6 @@
"node": ">=4"
}
},
- "node_modules/path-expression-matcher": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.5.0.tgz",
- "integrity": "sha512-cbrerZV+6rvdQrrD+iGMcZFEiiSrbv9Tfdkvnusy6y0x0GKBXREFg/Y65GhIfm0tnLntThhzCnfKwp1WRjeCyQ==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/NaturalIntelligence"
- }
- ],
- "license": "MIT",
- "engines": {
- "node": ">=14.0.0"
- }
- },
"node_modules/path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
@@ -9149,9 +9178,9 @@
}
},
"node_modules/postcss": {
- "version": "8.5.15",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz",
- "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==",
+ "version": "8.5.16",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.16.tgz",
+ "integrity": "sha512-vuwillviilfKZsg0VGj5R/YwwcHx4SLsIOI/7K6mQkWx+l5cUHTjj5g0AasTBcyXsbfTgrwsUNmVUb5xVwyPwg==",
"dev": true,
"funding": [
{
@@ -9240,9 +9269,9 @@
"license": "ISC"
},
"node_modules/protobufjs": {
- "version": "8.6.3",
- "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-8.6.3.tgz",
- "integrity": "sha512-alQyzT0j401LGBtwsqu6uprjR6pfNH1UJf9N6GBFMjIcd+HzTe0/HrjAbFCqun+zvnfLarrxAtMM2xvZ+kFZ5A==",
+ "version": "8.7.0",
+ "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-8.7.0.tgz",
+ "integrity": "sha512-uu52JNxLh3vsL7tXU/h0gDaywufvuUCTbGSi0NKQKBZ2ZopkmrWQJSQO/EFqzu/5YhiwgVM8rq/a/iVpx4eZ0g==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
@@ -9253,9 +9282,9 @@
}
},
"node_modules/pure-rand": {
- "version": "8.4.0",
- "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-8.4.0.tgz",
- "integrity": "sha512-IoM8YF/jY0hiugFo/wOWqfmarlE6J0wc6fDK1PhftMk7MGhVZl88sZimmqBBFomLOCSmcCCpsfj7wXASCpvK9A==",
+ "version": "8.4.2",
+ "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-8.4.2.tgz",
+ "integrity": "sha512-vvuOGgcuPJAirlHvuQw1TrOiw7ptaIXXmIbNuiNOY6lNGJJH49PQ1Kj4nd783nPdQhQdicgOjVI2yI/9BD6/Ng==",
"dev": true,
"funding": [
{
@@ -9270,13 +9299,14 @@
"license": "MIT"
},
"node_modules/qs": {
- "version": "6.15.2",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.2.tgz",
- "integrity": "sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw==",
+ "version": "6.15.3",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.3.tgz",
+ "integrity": "sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
- "side-channel": "^1.1.0"
+ "es-define-property": "^1.0.1",
+ "side-channel": "^1.1.1"
},
"engines": {
"node": ">=0.6"
@@ -9434,13 +9464,13 @@
}
},
"node_modules/rolldown": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.3.tgz",
- "integrity": "sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g==",
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.1.5.tgz",
+ "integrity": "sha512-t9z29cJjXf/vxQ8dyhCSpt6H6aSwHTk8cT5I3iy6SMXuFpk5mB6PL6XfC8PCwrPTx93udwKUm9HRteAlTGBLiA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@oxc-project/types": "=0.133.0",
+ "@oxc-project/types": "=0.139.0",
"@rolldown/pluginutils": "^1.0.0"
},
"bin": {
@@ -9450,21 +9480,21 @@
"node": "^20.19.0 || >=22.12.0"
},
"optionalDependencies": {
- "@rolldown/binding-android-arm64": "1.0.3",
- "@rolldown/binding-darwin-arm64": "1.0.3",
- "@rolldown/binding-darwin-x64": "1.0.3",
- "@rolldown/binding-freebsd-x64": "1.0.3",
- "@rolldown/binding-linux-arm-gnueabihf": "1.0.3",
- "@rolldown/binding-linux-arm64-gnu": "1.0.3",
- "@rolldown/binding-linux-arm64-musl": "1.0.3",
- "@rolldown/binding-linux-ppc64-gnu": "1.0.3",
- "@rolldown/binding-linux-s390x-gnu": "1.0.3",
- "@rolldown/binding-linux-x64-gnu": "1.0.3",
- "@rolldown/binding-linux-x64-musl": "1.0.3",
- "@rolldown/binding-openharmony-arm64": "1.0.3",
- "@rolldown/binding-wasm32-wasi": "1.0.3",
- "@rolldown/binding-win32-arm64-msvc": "1.0.3",
- "@rolldown/binding-win32-x64-msvc": "1.0.3"
+ "@rolldown/binding-android-arm64": "1.1.5",
+ "@rolldown/binding-darwin-arm64": "1.1.5",
+ "@rolldown/binding-darwin-x64": "1.1.5",
+ "@rolldown/binding-freebsd-x64": "1.1.5",
+ "@rolldown/binding-linux-arm-gnueabihf": "1.1.5",
+ "@rolldown/binding-linux-arm64-gnu": "1.1.5",
+ "@rolldown/binding-linux-arm64-musl": "1.1.5",
+ "@rolldown/binding-linux-ppc64-gnu": "1.1.5",
+ "@rolldown/binding-linux-s390x-gnu": "1.1.5",
+ "@rolldown/binding-linux-x64-gnu": "1.1.5",
+ "@rolldown/binding-linux-x64-musl": "1.1.5",
+ "@rolldown/binding-openharmony-arm64": "1.1.5",
+ "@rolldown/binding-wasm32-wasi": "1.1.5",
+ "@rolldown/binding-win32-arm64-msvc": "1.1.5",
+ "@rolldown/binding-win32-x64-msvc": "1.1.5"
}
},
"node_modules/run-parallel": {
@@ -9569,9 +9599,9 @@
"license": "MIT"
},
"node_modules/semver": {
- "version": "7.8.4",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.4.tgz",
- "integrity": "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==",
+ "version": "7.8.5",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz",
+ "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==",
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
@@ -9588,9 +9618,9 @@
"license": "ISC"
},
"node_modules/set-cookie-parser": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-3.1.0.tgz",
- "integrity": "sha512-kjnC1DXBHcxaOaOXBHBeRtltsDG2nUiUni+jP92M9gYdW12rsmx92UsfpH7o5tDRs7I1ZZPSQJQGv3UaRfCiuw==",
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-3.1.2.tgz",
+ "integrity": "sha512-5/r/lTwbJ3zQ+qwdUFZYeRNqda7P5HD8zQKqlSjdGt1/S0cjLAphHusj4Y58ahDtWn/g32xrIS58/ikOvwl0Lw==",
"dev": true,
"license": "MIT"
},
@@ -9955,22 +9985,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/strnum": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.4.0.tgz",
- "integrity": "sha512-sHrVyWWdq28RbhjuJdZsA1SnGRJV6NiXbk6AXBxDOsgAcA+lmpUZCYjOdLBxkXMwis6RRe7dlZt4VlIWFVzkmg==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/NaturalIntelligence"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "anynum": "^1.0.0"
- }
- },
"node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@@ -9984,9 +9998,9 @@
}
},
"node_modules/svelte": {
- "version": "5.56.3",
- "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.56.3.tgz",
- "integrity": "sha512-w7JvrM5IFl5cmfbY0TLik9o7mjRUJmRMhOR51tBPu708Gr/MjbGs7VnJnr/B0CaXeI4vtnOh7RKxDr0cwhMdDA==",
+ "version": "5.56.4",
+ "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.56.4.tgz",
+ "integrity": "sha512-/d0QHehmRuJW8gVz395MTkPcPozxzdjBMBE8oEYGz8O3b9KTMzzQ9ZHJQLuFKOHOPQbU6kx/X4iid/EBBzH7iw==",
"license": "MIT",
"dependencies": {
"@jridgewell/remapping": "^2.3.4",
@@ -10000,7 +10014,7 @@
"clsx": "^2.1.1",
"devalue": "^5.8.1",
"esm-env": "^1.2.1",
- "esrap": "^2.2.11",
+ "esrap": "^2.2.12",
"is-reference": "^3.0.3",
"locate-character": "^3.0.0",
"magic-string": "^0.30.11",
@@ -10122,9 +10136,9 @@
}
},
"node_modules/tinyglobby/node_modules/picomatch": {
- "version": "4.0.4",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
- "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz",
+ "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==",
"dev": true,
"license": "MIT",
"engines": {
@@ -10268,18 +10282,39 @@
}
},
"node_modules/typescript": {
- "version": "6.0.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz",
- "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==",
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-7.0.2.tgz",
+ "integrity": "sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA==",
"dev": true,
"license": "Apache-2.0",
"peer": true,
"bin": {
- "tsc": "bin/tsc",
- "tsserver": "bin/tsserver"
+ "tsc": "bin/tsc"
},
"engines": {
- "node": ">=14.17"
+ "node": ">=16.20.0"
+ },
+ "optionalDependencies": {
+ "@typescript/typescript-aix-ppc64": "7.0.2",
+ "@typescript/typescript-darwin-arm64": "7.0.2",
+ "@typescript/typescript-darwin-x64": "7.0.2",
+ "@typescript/typescript-freebsd-arm64": "7.0.2",
+ "@typescript/typescript-freebsd-x64": "7.0.2",
+ "@typescript/typescript-linux-arm": "7.0.2",
+ "@typescript/typescript-linux-arm64": "7.0.2",
+ "@typescript/typescript-linux-loong64": "7.0.2",
+ "@typescript/typescript-linux-mips64el": "7.0.2",
+ "@typescript/typescript-linux-ppc64": "7.0.2",
+ "@typescript/typescript-linux-riscv64": "7.0.2",
+ "@typescript/typescript-linux-s390x": "7.0.2",
+ "@typescript/typescript-linux-x64": "7.0.2",
+ "@typescript/typescript-netbsd-arm64": "7.0.2",
+ "@typescript/typescript-netbsd-x64": "7.0.2",
+ "@typescript/typescript-openbsd-arm64": "7.0.2",
+ "@typescript/typescript-openbsd-x64": "7.0.2",
+ "@typescript/typescript-sunos-x64": "7.0.2",
+ "@typescript/typescript-win32-arm64": "7.0.2",
+ "@typescript/typescript-win32-x64": "7.0.2"
}
},
"node_modules/typical": {
@@ -10299,9 +10334,9 @@
"license": "MIT"
},
"node_modules/undici": {
- "version": "8.5.0",
- "resolved": "https://registry.npmjs.org/undici/-/undici-8.5.0.tgz",
- "integrity": "sha512-xamtWoB1EshgjpmlXd7GGm2VfdDtw1+rD8uhry8pSNW3If6S8E0m2T2+orSKeZXEn/aPJMviCpDBA65WJt8zhg==",
+ "version": "8.7.0",
+ "resolved": "https://registry.npmjs.org/undici/-/undici-8.7.0.tgz",
+ "integrity": "sha512-N7iQtfyLhIMOFgQubvmLV26svHpO0bqKnAiWotTQCVKCmWrcGbBotPuW1x+xwYZ2VHdSTVUfPQQnlEt1/LouTQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -10505,16 +10540,16 @@
"license": "MIT"
},
"node_modules/vite": {
- "version": "8.0.16",
- "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.16.tgz",
- "integrity": "sha512-h9bXPmJichP5fLmVQo3PyaGSDE2n3aPuomeAlVRm0JLmt4rY6zmPKd59HYI4LNW8oTK7tlTsuC7l/m7awx9Jcw==",
+ "version": "8.1.4",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-8.1.4.tgz",
+ "integrity": "sha512-bTT9PsdWO+MQMNG9ZXIP/qM9wGh37DFxTV/sPq9cFpHr3w4jkgef032PkAL9jAqhk3Nz8NQw3O8n6/xFkqO4QQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"lightningcss": "^1.32.0",
- "picomatch": "^4.0.4",
- "postcss": "^8.5.15",
- "rolldown": "1.0.3",
+ "picomatch": "^4.0.5",
+ "postcss": "^8.5.16",
+ "rolldown": "~1.1.4",
"tinyglobby": "^0.2.17"
},
"bin": {
@@ -10531,7 +10566,7 @@
},
"peerDependencies": {
"@types/node": "^20.19.0 || >=22.12.0",
- "@vitejs/devtools": "^0.1.18",
+ "@vitejs/devtools": "^0.3.0",
"esbuild": "^0.27.0 || ^0.28.0",
"jiti": ">=1.21.0",
"less": "^4.0.0",
@@ -10641,9 +10676,9 @@
}
},
"node_modules/vite/node_modules/picomatch": {
- "version": "4.0.4",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
- "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz",
+ "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==",
"dev": true,
"license": "MIT",
"engines": {
@@ -10767,9 +10802,9 @@
}
},
"node_modules/workerd": {
- "version": "1.20260611.1",
- "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20260611.1.tgz",
- "integrity": "sha512-CS/640T7pIJ2HYX6x2DwKFGbcSckAWN3tgcdq+ptB6SaqjWUhlzIgA/YhPuwIU+/NnMnGpqOFX/hC18Oyge63w==",
+ "version": "1.20260708.1",
+ "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20260708.1.tgz",
+ "integrity": "sha512-WAK+Kt/VVCSldH2qSr8lx46XCJ4Q+bdlHNaFqUtOHthBEIB8C1N8HVW+VOLrxDoTCk0NGNv0zajnBeQK4JOB9w==",
"dev": true,
"hasInstallScript": true,
"license": "Apache-2.0",
@@ -10780,11 +10815,11 @@
"node": ">=16"
},
"optionalDependencies": {
- "@cloudflare/workerd-darwin-64": "1.20260611.1",
- "@cloudflare/workerd-darwin-arm64": "1.20260611.1",
- "@cloudflare/workerd-linux-64": "1.20260611.1",
- "@cloudflare/workerd-linux-arm64": "1.20260611.1",
- "@cloudflare/workerd-windows-64": "1.20260611.1"
+ "@cloudflare/workerd-darwin-64": "1.20260708.1",
+ "@cloudflare/workerd-darwin-arm64": "1.20260708.1",
+ "@cloudflare/workerd-linux-64": "1.20260708.1",
+ "@cloudflare/workerd-linux-arm64": "1.20260708.1",
+ "@cloudflare/workerd-windows-64": "1.20260708.1"
}
},
"node_modules/worktop": {
@@ -10802,20 +10837,20 @@
}
},
"node_modules/wrangler": {
- "version": "4.100.0",
- "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-4.100.0.tgz",
- "integrity": "sha512-dSQO7DO+mD6XDzkVWIWBoGLO3yw+lacWSc/KhFvd7pgfpth+kX98qb5SGRHZN8ACCDhhfwzDLXwB6qHsIHhfBg==",
+ "version": "4.110.0",
+ "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-4.110.0.tgz",
+ "integrity": "sha512-xZeXKYi7hxQRF5anL+v77RkufJNpF9f3Eqeyqq2QBsETpLZgh0Agj0jJ6JPtkbgn6ukZdh8OK5egsGPWIditgg==",
"dev": true,
"license": "MIT OR Apache-2.0",
"dependencies": {
"@cloudflare/kv-asset-handler": "0.5.0",
"@cloudflare/unenv-preset": "2.16.1",
"blake3-wasm": "2.1.5",
- "esbuild": "0.27.3",
- "miniflare": "4.20260611.0",
+ "esbuild": "0.28.1",
+ "miniflare": "4.20260708.1",
"path-to-regexp": "6.3.0",
"unenv": "2.0.0-rc.24",
- "workerd": "1.20260611.1"
+ "workerd": "1.20260708.1"
},
"bin": {
"cf-wrangler": "bin/cf-wrangler.js",
@@ -10829,7 +10864,7 @@
"fsevents": "2.3.3"
},
"peerDependencies": {
- "@cloudflare/workers-types": "^4.20260611.1"
+ "@cloudflare/workers-types": "^5.20260708.1"
},
"peerDependenciesMeta": {
"@cloudflare/workers-types": {
@@ -10983,22 +11018,6 @@
}
}
},
- "node_modules/xml-naming": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/xml-naming/-/xml-naming-0.1.0.tgz",
- "integrity": "sha512-k8KO9hrMyNk6tUWqUfkTEZbezRRpONVOzUTnc97VnCvyj6Tf9lyUR9EDAIeiVLv56jsMcoXEwjW8Kv5yPY52lw==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/NaturalIntelligence"
- }
- ],
- "license": "MIT",
- "engines": {
- "node": ">=16.0.0"
- }
- },
"node_modules/y18n": {
"version": "5.0.8",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
@@ -11082,20 +11101,6 @@
"error-stack-parser-es": "^1.0.5"
}
},
- "node_modules/youch/node_modules/cookie": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz",
- "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/express"
- }
- },
"node_modules/zimmerframe": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/zimmerframe/-/zimmerframe-1.1.4.tgz",
@@ -11221,6 +11226,28 @@
"node": ">=24"
}
},
+ "packages/charset/node_modules/chardet": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.1.tgz",
+ "integrity": "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==",
+ "license": "MIT"
+ },
+ "packages/charset/node_modules/iconv-lite": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz",
+ "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==",
+ "license": "MIT",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
"packages/compress": {
"name": "@datastream/compress",
"version": "0.6.0",
@@ -11507,6 +11534,94 @@
"engines": {
"node": ">=24"
}
+ },
+ "websites/datastream.js.org/node_modules/@cloudflare/workers-types": {
+ "version": "4.20260702.1",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20260702.1.tgz",
+ "integrity": "sha512-mOhf5TUEB1m2vPrxtqoIGfz0fUC9xyxRDx5gWHy5s+OCo6dcV+g7wI1R7gYCMFohhqF/2y2xeKVwMwCJjfn/WA==",
+ "dev": true,
+ "license": "MIT OR Apache-2.0"
+ },
+ "websites/datastream.js.org/node_modules/@sveltejs/adapter-cloudflare": {
+ "version": "7.2.9",
+ "resolved": "https://registry.npmjs.org/@sveltejs/adapter-cloudflare/-/adapter-cloudflare-7.2.9.tgz",
+ "integrity": "sha512-LEfLRYKZIiNYBPYk9Cu4dFCCIX37NO96jESNRDv7yr3vvblKU4Yh05FPUMRSrOWFKtG6bJcGIvdG/M2DSf4D1w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@cloudflare/workers-types": "^4.20250507.0",
+ "worktop": "0.8.0-next.18"
+ },
+ "peerDependencies": {
+ "@sveltejs/kit": "^2.0.0",
+ "wrangler": "^4.0.0"
+ }
+ },
+ "websites/datastream.js.org/node_modules/@sveltejs/kit": {
+ "version": "2.69.2",
+ "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.69.2.tgz",
+ "integrity": "sha512-CMdPDbYjRwRu4KXTxBVMuOpFPCt1i/v0ANennotec+K9Cmb2e3w2yYzJiC6Vh/WSvm9Khi5sJMZa0rJPqfHlDw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@standard-schema/spec": "^1.0.0",
+ "@sveltejs/acorn-typescript": "^1.0.9",
+ "@types/cookie": "^0.6.0",
+ "acorn": "^8.16.0",
+ "cookie": "^0.6.0",
+ "devalue": "^5.8.1",
+ "esm-env": "^1.2.2",
+ "kleur": "^4.1.5",
+ "magic-string": "^0.30.5",
+ "mrmime": "^2.0.0",
+ "set-cookie-parser": "^3.0.0",
+ "sirv": "^3.0.0"
+ },
+ "bin": {
+ "svelte-kit": "svelte-kit.js"
+ },
+ "engines": {
+ "node": ">=18.13"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": "^1.0.0",
+ "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0 || ^7.0.0",
+ "svelte": "^4.0.0 || ^5.0.0-next.0",
+ "typescript": "^5.3.3 || ^6.0.0",
+ "vite": "^5.0.3 || ^6.0.0 || ^7.0.0-beta.0 || ^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@opentelemetry/api": {
+ "optional": true
+ },
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "websites/datastream.js.org/node_modules/cookie": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
+ "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "websites/datastream.js.org/node_modules/typescript": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz",
+ "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==",
+ "extraneous": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
}
}
}
diff --git a/websites/datastream.js.org/.tardisec.json b/websites/datastream.js.org/.tardisec.json
new file mode 100644
index 0000000..542c26a
--- /dev/null
+++ b/websites/datastream.js.org/.tardisec.json
@@ -0,0 +1,35 @@
+{
+ "dns": {
+ "txt": ["tardisec-verification=9a3890fa-a783-51c2-b20f-0dbe457d526f"]
+ },
+ "http": {
+ "headers": {
+ "Connection-Allowlist": "(\"*\");report-to=default",
+ "Connection-Allowlist-Report-Only": "();report-to=default",
+ "Content-Security-Policy": "base-uri 'none';connect-src 'self';default-src 'none';form-action 'self';frame-ancestors 'none';img-src 'self';manifest-src 'self';report-to default;report-uri https://9a3890fa-a783-51c2-b20f-0dbe457d526f.report-to.org;script-src 'self';script-src-attr 'report-sample';style-src 'self';style-src-attr 'report-sample';upgrade-insecure-requests;worker-src 'self'",
+ "Content-Security-Policy-Report-Only": "base-uri 'none';default-src 'report-sample' 'report-sha256';form-action 'none';frame-ancestors 'none';report-to default;report-uri https://9a3890fa-a783-51c2-b20f-0dbe457d526f.report-to.org;require-trusted-types-for 'script'",
+ "Cross-Origin-Embedder-Policy": "require-corp;report-to=default",
+ "Cross-Origin-Opener-Policy": "same-origin;report-to=default",
+ "Cross-Origin-Resource-Policy": "same-origin",
+ "Document-Isolation-Policy": "isolate-and-require-corp;report-to=\"default\"",
+ "Document-Policy-Report-Only": "*;report-to=default",
+ "Integrity-Policy": "blocked-destinations=(),endpoints=(default)",
+ "Integrity-Policy-Report-Only": "blocked-destinations=(script style),endpoints=(default)",
+ "NEL": "{\"failure_fraction\":1,\"include_subdomains\":true,\"max_age\":31536000,\"report_to\":\"default\",\"success_fraction\":0}",
+ "Origin-Agent-Cluster": "?1",
+ "Permissions-Policy-Report-Only": "accelerometer=(),all-screens-capture=(),ambient-light-sensor=(),aria-notify=(),attribution-reporting=(),autofill=(),autoplay=(),battery=(),bluetooth=(),browsing-topics=(),camera=(),captured-surface-control=(),ch-ua=(),ch-ua-arch=(),ch-ua-bitness=(),ch-ua-full-version=(),ch-ua-full-version-list=(),ch-ua-high-entropy-values=(),ch-ua-mobile=(),ch-ua-model=(),ch-ua-platform=(),ch-ua-platform-version=(),clipboard-read=(),clipboard-write=(),compute-pressure=(),cross-origin-isolated=(),deferred-fetch=(),digital-credentials-create=(),digital-credentials-get=(),direct-sockets=(),display-capture=(),encrypted-media=(),execution-while-not-rendered=(),execution-while-out-of-viewport=(),focus-without-user-activation=(),fullscreen=(),gamepad=(),geolocation=(),gyroscope=(),hid=(),identity-credentials-get=(),idle-detection=(),interest-cohort=(),join-ad-interest-group=(),keyboard-map=(),language-detector=(),language-model=(),local-fonts=(),local-network=(),local-network-access=(),loopback-network=(),magnetometer=(),manual-text=(),mediasession=(),microphone=(),midi=(),monetization=(),navigation-override=(),on-device-speech-recognition=(),otp-credentials=(),payment=(),picture-in-picture=(),private-state-token-issuance=(),private-state-token-redemption=(),publickey-credentials-create=(),publickey-credentials-get=(),rewriter=(),run-ad-auction=(),screen-wake-lock=(),serial=(),smart-card=(),speaker-selection=(),storage-access=(),summarizer=(),sync-script=(),sync-xhr=(),tools=(),translator=(),trust-token-redemption=(),unload=(),usb=(),vertical-scroll=(),web-share=(),window-management=(),writer=(),xr-spatial-tracking=()",
+ "Referrer-Policy": "no-referrer",
+ "Report-To": "{\"endpoints\":[{\"url\":\"https://9a3890fa-a783-51c2-b20f-0dbe457d526f.report-to.org\"}],\"group\":\"default\",\"include_subdomains\":true,\"max_age\":31536000}",
+ "Reporting-Endpoints": "default=\"https://9a3890fa-a783-51c2-b20f-0dbe457d526f.report-to.org\"",
+ "Require-Document-Policy-Report-Only": "*;report-to=default",
+ "Scripting-Policy": "report-to=default",
+ "Scripting-Policy-Report-Only": "eval=blocked, report-to=default",
+ "Strict-Transport-Security": "max-age=31536000;includeSubDomains;preload",
+ "X-Content-Type-Options": "nosniff",
+ "X-DNS-Prefetch-Control": "off",
+ "X-Download-Options": "noopen",
+ "X-Frame-Options": "DENY",
+ "X-Permitted-Cross-Domain-Policies": "none"
+ }
+ }
+}
diff --git a/websites/datastream.js.org/.tardisec.sveltekit.json b/websites/datastream.js.org/.tardisec.sveltekit.json
new file mode 100644
index 0000000..06d56a8
--- /dev/null
+++ b/websites/datastream.js.org/.tardisec.sveltekit.json
@@ -0,0 +1,37 @@
+{
+ "kit": {
+ "csp": {
+ "mode": "hash",
+ "directives": {
+ "report-to": ["default"],
+ "report-uri": [
+ "https://9a3890fa-a783-51c2-b20f-0dbe457d526f.report-to.org"
+ ],
+ "img-src": ["self"],
+ "base-uri": ["none"],
+ "style-src": ["self"],
+ "script-src": ["self"],
+ "worker-src": ["self"],
+ "connect-src": ["self"],
+ "default-src": ["none"],
+ "form-action": ["self"],
+ "manifest-src": ["self"],
+ "style-src-attr": ["report-sample"],
+ "frame-ancestors": ["none"],
+ "script-src-attr": ["report-sample"],
+ "upgrade-insecure-requests": true
+ },
+ "reportOnly": {
+ "base-uri": ["none"],
+ "default-src": ["none", "report-sample", "'report-sha256'"],
+ "form-action": ["none"],
+ "frame-ancestors": ["none"],
+ "report-to": ["default"],
+ "report-uri": [
+ "https://9a3890fa-a783-51c2-b20f-0dbe457d526f.report-to.org"
+ ],
+ "require-trusted-types-for": ["script"]
+ }
+ }
+ }
+}
diff --git a/websites/datastream.js.org/src/hooks/tardisecMiddleware.js b/websites/datastream.js.org/src/hooks/tardisecMiddleware.js
index eb57874..691be51 100644
--- a/websites/datastream.js.org/src/hooks/tardisecMiddleware.js
+++ b/websites/datastream.js.org/src/hooks/tardisecMiddleware.js
@@ -1,13 +1,18 @@
// TODO convert into adapter
-import tardisec from "../../tardisec.json" with { type: "json" };
+// import * as env from '$env/static/private';
+// import { redirect } from "@utils/sveltekit.js";
+//import { recommendHttpHeader } from "@utils/recommend.js";
+import tardisec from "../../.tardisec.json" with { type: "json" };
const tardisecMiddleware = async ({ event, resolve }) => {
+ // const { url, params, cookies } = event;
+
const response = await resolve(event);
- const keys = Object.keys(tardisec.raw);
+ const keys = Object.keys(tardisec.http.headers);
for (let i = keys.length; i--; ) {
const headerKey = keys[i];
- const headerValue = tardisec.raw[headerKey];
+ const headerValue = tardisec.http.headers[headerKey];
if (headerValue && !response.headers.has(headerKey)) {
response.headers.set(headerKey, headerValue);
}
diff --git a/websites/datastream.js.org/src/styles/below.css b/websites/datastream.js.org/src/styles/below.css
index a45bf3b..d416549 100644
--- a/websites/datastream.js.org/src/styles/below.css
+++ b/websites/datastream.js.org/src/styles/below.css
@@ -1,3 +1,4 @@
+@import "@willfarrell-ds/vanilla/elements/blockquote.css";
@import "@willfarrell-ds/vanilla/elements/code.css";
@import "@willfarrell-ds/vanilla/elements/details.css";
@import "@willfarrell-ds/vanilla/elements/form.css";
@@ -11,7 +12,6 @@
@import "@willfarrell-ds/vanilla/elements/p.css";
@import "@willfarrell-ds/vanilla/elements/picture.css";
@import "@willfarrell-ds/vanilla/elements/pre.css";
-@import "@willfarrell-ds/vanilla/elements/s.css";
@import "@willfarrell-ds/vanilla/elements/select.css";
@import "@willfarrell-ds/vanilla/elements/table.css";
@import "@willfarrell-ds/vanilla/classes/span.badge.css";
diff --git a/websites/datastream.js.org/svelte.config.js b/websites/datastream.js.org/svelte.config.js
index f26ddfe..5387c2d 100644
--- a/websites/datastream.js.org/svelte.config.js
+++ b/websites/datastream.js.org/svelte.config.js
@@ -1,9 +1,9 @@
import { resolve } from "node:path";
import adapter from "@sveltejs/adapter-cloudflare";
import { mdsvex } from "mdsvex";
+import tardisec from "./.tardisec.sveltekit.json" with { type: "json" };
import { rehypeAddHeadingIds } from "./src/lib/rehype-add-heading-ids.js";
import { remarkExtractHeadings } from "./src/lib/remark-extract-headings.js";
-import tardisec from "./tardisec.json" with { type: "json" };
const domain = process.env.ORIGIN ?? "datastream.js.org";
const origin = domain;
@@ -19,10 +19,10 @@ const config = {
},
appDir: "_",
csp: {
- ...tardisec["svelte.config.js"]["Content-Security-Policy"],
+ ...tardisec.kit.csp,
mode: "hash",
directives: {
- "default-src": ["none"],
+ "default-src": ["none"], // 'report-sha256'
"base-uri": ["none"],
"connect-src": ["self"],
"form-action": ["self"],
@@ -31,11 +31,27 @@ const config = {
"manifest-src": ["self"],
"script-src": ["self"],
"script-src-attr": ["report-sample"],
+ //"script-src-elem": ['self'],
"style-src": ["self"],
"style-src-attr": ["report-sample"],
+ //"style-src-elem": ['self'],
+ //'trusted-types':[],
+ //'require-trusted-types-for': ['script'],
"upgrade-insecure-requests": true,
"worker-src": ["self"],
"report-to": ["default"],
+ //'report-uri': [`https://${domain}.report-to.org`]
+ },
+ reportOnly: {
+ "base-uri": ["none"],
+ "default-src": ["none", "report-sample", "'report-sha256'"],
+ "form-action": ["none"],
+ "frame-ancestors": ["none"],
+ "report-to": ["default"],
+ "report-uri": [
+ "https://9a3890fa-a783-51c2-b20f-0dbe457d526f.report-to.org",
+ ],
+ "require-trusted-types-for": ["script"],
},
},
csrf: {
From 5135dbb7a9a0888b7ea912d0656a9c4e4bb00c8e Mon Sep 17 00:00:00 2001
From: will Farrell
Date: Sat, 11 Jul 2026 11:13:56 -0600
Subject: [PATCH 24/27] fix: clean up headers
Signed-off-by: will Farrell
---
websites/datastream.js.org/.tardisec.json | 2 +-
.../.tardisec.sveltekit.json | 28 +++++++-------
websites/datastream.js.org/svelte.config.js | 37 +------------------
3 files changed, 16 insertions(+), 51 deletions(-)
diff --git a/websites/datastream.js.org/.tardisec.json b/websites/datastream.js.org/.tardisec.json
index 542c26a..7ff8579 100644
--- a/websites/datastream.js.org/.tardisec.json
+++ b/websites/datastream.js.org/.tardisec.json
@@ -6,7 +6,7 @@
"headers": {
"Connection-Allowlist": "(\"*\");report-to=default",
"Connection-Allowlist-Report-Only": "();report-to=default",
- "Content-Security-Policy": "base-uri 'none';connect-src 'self';default-src 'none';form-action 'self';frame-ancestors 'none';img-src 'self';manifest-src 'self';report-to default;report-uri https://9a3890fa-a783-51c2-b20f-0dbe457d526f.report-to.org;script-src 'self';script-src-attr 'report-sample';style-src 'self';style-src-attr 'report-sample';upgrade-insecure-requests;worker-src 'self'",
+ "Content-Security-Policy": "base-uri 'none';connect-src 'self';default-src 'report-sample' 'report-sha256';form-action 'self';frame-ancestors 'none';img-src 'self';manifest-src 'self';report-to default;report-uri https://9a3890fa-a783-51c2-b20f-0dbe457d526f.report-to.org;script-src 'self' 'report-sample' 'report-sha256';script-src-attr 'report-sample' 'report-sha256';style-src 'self' 'report-sample' 'report-sha256';style-src-attr 'report-sample' 'report-sha256';upgrade-insecure-requests;worker-src 'self'",
"Content-Security-Policy-Report-Only": "base-uri 'none';default-src 'report-sample' 'report-sha256';form-action 'none';frame-ancestors 'none';report-to default;report-uri https://9a3890fa-a783-51c2-b20f-0dbe457d526f.report-to.org;require-trusted-types-for 'script'",
"Cross-Origin-Embedder-Policy": "require-corp;report-to=default",
"Cross-Origin-Opener-Policy": "same-origin;report-to=default",
diff --git a/websites/datastream.js.org/.tardisec.sveltekit.json b/websites/datastream.js.org/.tardisec.sveltekit.json
index 06d56a8..7f3ec17 100644
--- a/websites/datastream.js.org/.tardisec.sveltekit.json
+++ b/websites/datastream.js.org/.tardisec.sveltekit.json
@@ -3,27 +3,27 @@
"csp": {
"mode": "hash",
"directives": {
- "report-to": ["default"],
- "report-uri": [
- "https://9a3890fa-a783-51c2-b20f-0dbe457d526f.report-to.org"
- ],
- "img-src": ["self"],
"base-uri": ["none"],
- "style-src": ["self"],
- "script-src": ["self"],
- "worker-src": ["self"],
"connect-src": ["self"],
- "default-src": ["none"],
+ "default-src": ["report-sample", "'report-sha256'"],
"form-action": ["self"],
- "manifest-src": ["self"],
- "style-src-attr": ["report-sample"],
"frame-ancestors": ["none"],
- "script-src-attr": ["report-sample"],
- "upgrade-insecure-requests": true
+ "img-src": ["self"],
+ "manifest-src": ["self"],
+ "report-to": ["default"],
+ "report-uri": [
+ "https://9a3890fa-a783-51c2-b20f-0dbe457d526f.report-to.org"
+ ],
+ "script-src": ["self", "report-sample", "'report-sha256'"],
+ "script-src-attr": ["report-sample", "'report-sha256'"],
+ "style-src": ["self", "report-sample", "'report-sha256'"],
+ "style-src-attr": ["report-sample", "'report-sha256'"],
+ "upgrade-insecure-requests": true,
+ "worker-src": ["self"]
},
"reportOnly": {
"base-uri": ["none"],
- "default-src": ["none", "report-sample", "'report-sha256'"],
+ "default-src": ["report-sample", "'report-sha256'"],
"form-action": ["none"],
"frame-ancestors": ["none"],
"report-to": ["default"],
diff --git a/websites/datastream.js.org/svelte.config.js b/websites/datastream.js.org/svelte.config.js
index 5387c2d..82825f9 100644
--- a/websites/datastream.js.org/svelte.config.js
+++ b/websites/datastream.js.org/svelte.config.js
@@ -18,42 +18,7 @@ const config = {
"@styles": resolve("./src/styles"),
},
appDir: "_",
- csp: {
- ...tardisec.kit.csp,
- mode: "hash",
- directives: {
- "default-src": ["none"], // 'report-sha256'
- "base-uri": ["none"],
- "connect-src": ["self"],
- "form-action": ["self"],
- "frame-ancestors": ["none"],
- "img-src": ["self"],
- "manifest-src": ["self"],
- "script-src": ["self"],
- "script-src-attr": ["report-sample"],
- //"script-src-elem": ['self'],
- "style-src": ["self"],
- "style-src-attr": ["report-sample"],
- //"style-src-elem": ['self'],
- //'trusted-types':[],
- //'require-trusted-types-for': ['script'],
- "upgrade-insecure-requests": true,
- "worker-src": ["self"],
- "report-to": ["default"],
- //'report-uri': [`https://${domain}.report-to.org`]
- },
- reportOnly: {
- "base-uri": ["none"],
- "default-src": ["none", "report-sample", "'report-sha256'"],
- "form-action": ["none"],
- "frame-ancestors": ["none"],
- "report-to": ["default"],
- "report-uri": [
- "https://9a3890fa-a783-51c2-b20f-0dbe457d526f.report-to.org",
- ],
- "require-trusted-types-for": ["script"],
- },
- },
+ csp: tardisec.kit.csp,
csrf: {
trustedOrigins: [origin],
},
From 4dd0fd9b517d43791628363a01d2c062074e7186 Mon Sep 17 00:00:00 2001
From: will Farrell
Date: Sat, 11 Jul 2026 11:35:47 -0600
Subject: [PATCH 25/27] chore: dep update
Signed-off-by: will Farrell
---
biome.json | 2 +-
package-lock.json | 216 ++++++++----------
packages/charset/package.json | 4 +-
packages/duckdb/package.json | 8 +-
websites/datastream.js.org/package.json | 8 +-
.../src/components/BodyFooter.svelte | 4 -
.../src/components/BodyHeader.svelte | 2 +-
.../src/components/docs/AsideNav.svelte | 3 -
.../src/routes/+error.svelte | 2 -
.../src/routes/search/+page.svelte | 1 -
10 files changed, 104 insertions(+), 146 deletions(-)
diff --git a/biome.json b/biome.json
index 2ef7228..f406365 100644
--- a/biome.json
+++ b/biome.json
@@ -1,5 +1,5 @@
{
- "$schema": "https://biomejs.dev/schemas/2.5.0/schema.json",
+ "$schema": "https://biomejs.dev/schemas/2.5.3/schema.json",
"vcs": {
"enabled": true,
"clientKind": "git",
diff --git a/package-lock.json b/package-lock.json
index 05f4387..50314c7 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1605,10 +1605,10 @@
}
},
"node_modules/@cloudflare/workers-types": {
- "version": "5.20260711.1",
- "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-5.20260711.1.tgz",
- "integrity": "sha512-yY6GXfyrHJa33EWaSzS5N56Lsll02kgHo4Qodz2l2DNl4L6L5yXBMZVMvcYArirdYA1xn+o8LKVRQGdRpmSMzA==",
- "extraneous": true,
+ "version": "4.20260702.1",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20260702.1.tgz",
+ "integrity": "sha512-mOhf5TUEB1m2vPrxtqoIGfz0fUC9xyxRDx5gWHy5s+OCo6dcV+g7wI1R7gYCMFohhqF/2y2xeKVwMwCJjfn/WA==",
+ "dev": true,
"license": "MIT OR Apache-2.0"
},
"node_modules/@commitlint/cli": {
@@ -2012,9 +2012,9 @@
"link": true
},
"node_modules/@duckdb/duckdb-wasm": {
- "version": "1.33.1-dev45.0",
- "resolved": "https://registry.npmjs.org/@duckdb/duckdb-wasm/-/duckdb-wasm-1.33.1-dev45.0.tgz",
- "integrity": "sha512-ETlrjhiGQzNdaOhpro/Y9u/RCcK+iyuczLy7uOn0kG5Mqlj8C+gTuhBXjs4JpK9ocdUgr3oT8zYYIbUnFD9AYA==",
+ "version": "1.33.1-dev57.0",
+ "resolved": "https://registry.npmjs.org/@duckdb/duckdb-wasm/-/duckdb-wasm-1.33.1-dev57.0.tgz",
+ "integrity": "sha512-ndn5l2EHq1PEMvCg8G6lRV0vjhSUcbqdM/niNBTTqH4/PyyUUVKbge0uUyCnj27b9SF/CiqBwDsgKLTqBvaxdw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -2117,39 +2117,39 @@
"license": "MIT"
},
"node_modules/@duckdb/node-api": {
- "version": "1.5.3-r.3",
- "resolved": "https://registry.npmjs.org/@duckdb/node-api/-/node-api-1.5.3-r.3.tgz",
- "integrity": "sha512-FzuL6sevuFfEFwkgiUMRMUAj4TaVqV//L0oo2FVZ9s9oYpLpALF9qZyQv2ucclTNQZwDCkm8+e6yLMc6t8IjlA==",
+ "version": "1.5.4-r.1",
+ "resolved": "https://registry.npmjs.org/@duckdb/node-api/-/node-api-1.5.4-r.1.tgz",
+ "integrity": "sha512-3PYk/4//svuYmb9RYVM71cCoNa6ngoYWwrMhJaqbm010txzIMWbJCbxrFeqDl+krdIug+Hc/MNCeS0gHsTXSIw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@duckdb/node-bindings": "1.5.3-r.3"
+ "@duckdb/node-bindings": "1.5.4-r.1"
}
},
"node_modules/@duckdb/node-bindings": {
- "version": "1.5.3-r.3",
- "resolved": "https://registry.npmjs.org/@duckdb/node-bindings/-/node-bindings-1.5.3-r.3.tgz",
- "integrity": "sha512-Dphw1a9kKXZnCiWX1YCEAJsQ7WJQO2Ikgxy7m8jy0QVXqAwB9esr5NGsuEL3vMKL7velZHeZCjGOMnHZEcIsdg==",
+ "version": "1.5.4-r.1",
+ "resolved": "https://registry.npmjs.org/@duckdb/node-bindings/-/node-bindings-1.5.4-r.1.tgz",
+ "integrity": "sha512-v834OZZKQ59yAvh8GOEmM+R1foPNgdMGL0VTBgHywgblgQNyq11HvWgT4QGJIUFfo/cQ9WFyf1MFhK0+hV1aiA==",
"dev": true,
"license": "MIT",
"dependencies": {
"detect-libc": "^2.1.2"
},
"optionalDependencies": {
- "@duckdb/node-bindings-darwin-arm64": "1.5.3-r.3",
- "@duckdb/node-bindings-darwin-x64": "1.5.3-r.3",
- "@duckdb/node-bindings-linux-arm64": "1.5.3-r.3",
- "@duckdb/node-bindings-linux-arm64-musl": "1.5.3-r.3",
- "@duckdb/node-bindings-linux-x64": "1.5.3-r.3",
- "@duckdb/node-bindings-linux-x64-musl": "1.5.3-r.3",
- "@duckdb/node-bindings-win32-arm64": "1.5.3-r.3",
- "@duckdb/node-bindings-win32-x64": "1.5.3-r.3"
+ "@duckdb/node-bindings-darwin-arm64": "1.5.4-r.1",
+ "@duckdb/node-bindings-darwin-x64": "1.5.4-r.1",
+ "@duckdb/node-bindings-linux-arm64": "1.5.4-r.1",
+ "@duckdb/node-bindings-linux-arm64-musl": "1.5.4-r.1",
+ "@duckdb/node-bindings-linux-x64": "1.5.4-r.1",
+ "@duckdb/node-bindings-linux-x64-musl": "1.5.4-r.1",
+ "@duckdb/node-bindings-win32-arm64": "1.5.4-r.1",
+ "@duckdb/node-bindings-win32-x64": "1.5.4-r.1"
}
},
"node_modules/@duckdb/node-bindings-darwin-arm64": {
- "version": "1.5.3-r.3",
- "resolved": "https://registry.npmjs.org/@duckdb/node-bindings-darwin-arm64/-/node-bindings-darwin-arm64-1.5.3-r.3.tgz",
- "integrity": "sha512-ttD8QBesgzHu7Sc4qouuIGLM7PWedLW8GvFbnZEyMqk24mQz1HWFgaT0ivw6nDRaDPUQLB9QnAOq8MZUh1zWHQ==",
+ "version": "1.5.4-r.1",
+ "resolved": "https://registry.npmjs.org/@duckdb/node-bindings-darwin-arm64/-/node-bindings-darwin-arm64-1.5.4-r.1.tgz",
+ "integrity": "sha512-fl8EC5xdmI7VAI7bX4W6D7lOGNtxyLvSxGjOY8Ov7viVEKwIcBXXKlMPgh3sw+PiVlwZhKlknuCI8BL5xXpSDg==",
"cpu": [
"arm64"
],
@@ -2161,9 +2161,9 @@
]
},
"node_modules/@duckdb/node-bindings-darwin-x64": {
- "version": "1.5.3-r.3",
- "resolved": "https://registry.npmjs.org/@duckdb/node-bindings-darwin-x64/-/node-bindings-darwin-x64-1.5.3-r.3.tgz",
- "integrity": "sha512-Vp9MYtoYf6zUWHdCmHXwUcJlHq3YaaIeULWeSiPUM1hsDflLiZKXtz5i250Ulz03VsfWBjpO4wdM99sjjrYKkg==",
+ "version": "1.5.4-r.1",
+ "resolved": "https://registry.npmjs.org/@duckdb/node-bindings-darwin-x64/-/node-bindings-darwin-x64-1.5.4-r.1.tgz",
+ "integrity": "sha512-E8bECZ6abJqunPqVR1NA0Zho7qxanfDWWFuJrKMsU1NCUqyGLyhXqZwsRHAx7J6jrM+lhQ7wOZj1x/N4OVml3A==",
"cpu": [
"x64"
],
@@ -2175,9 +2175,9 @@
]
},
"node_modules/@duckdb/node-bindings-linux-arm64": {
- "version": "1.5.3-r.3",
- "resolved": "https://registry.npmjs.org/@duckdb/node-bindings-linux-arm64/-/node-bindings-linux-arm64-1.5.3-r.3.tgz",
- "integrity": "sha512-3HLcrzQE83947JS51UVR7C9qnXQMltCOk4Dnhiz1CD+9u32DGLMgPTIIxclk7O+Q7EwfqzD8JV86Ud+LT1crcQ==",
+ "version": "1.5.4-r.1",
+ "resolved": "https://registry.npmjs.org/@duckdb/node-bindings-linux-arm64/-/node-bindings-linux-arm64-1.5.4-r.1.tgz",
+ "integrity": "sha512-4EsB+cgRqOE++mdPQ2ZoGJCg4ylmuqdbLDtmo3L19B+C5OzGmrhxlKD4o75eGEtfO52M+w+TdL0qhy0H5XvaKQ==",
"cpu": [
"arm64"
],
@@ -2192,9 +2192,9 @@
]
},
"node_modules/@duckdb/node-bindings-linux-arm64-musl": {
- "version": "1.5.3-r.3",
- "resolved": "https://registry.npmjs.org/@duckdb/node-bindings-linux-arm64-musl/-/node-bindings-linux-arm64-musl-1.5.3-r.3.tgz",
- "integrity": "sha512-IadRyx+98FEynKLXAk2MzReinFgduiDXgNd5Z8c5VKch+8FgBfqkEUYGOnBMMUPT8kuheKdLj23vpWXaCzOgoQ==",
+ "version": "1.5.4-r.1",
+ "resolved": "https://registry.npmjs.org/@duckdb/node-bindings-linux-arm64-musl/-/node-bindings-linux-arm64-musl-1.5.4-r.1.tgz",
+ "integrity": "sha512-96Pyk5Syy18S5DSN0CKkOQ7/CsyVGRML8ewox1qpFDjYvPH1VsULlQoIRwbpw7mkFEy17wuWmbwzb7oKu/nGMw==",
"cpu": [
"arm64"
],
@@ -2209,9 +2209,9 @@
]
},
"node_modules/@duckdb/node-bindings-linux-x64": {
- "version": "1.5.3-r.3",
- "resolved": "https://registry.npmjs.org/@duckdb/node-bindings-linux-x64/-/node-bindings-linux-x64-1.5.3-r.3.tgz",
- "integrity": "sha512-TXndAL0ZoETq17Df6wB+SUZjLGDmOsKuDSySxB+wy6sHfpRtbDgQibyXRlajVeUkRDwSzBFC5ymy16YG0Fl4iw==",
+ "version": "1.5.4-r.1",
+ "resolved": "https://registry.npmjs.org/@duckdb/node-bindings-linux-x64/-/node-bindings-linux-x64-1.5.4-r.1.tgz",
+ "integrity": "sha512-IldapRydno5kf4VkPCe8yK+j4pCg+j6Qs46UmLnKex/mtIdJa7ifhMYRkvdc5KIAFEC0eEL5c830QeuwcUROyg==",
"cpu": [
"x64"
],
@@ -2226,9 +2226,9 @@
]
},
"node_modules/@duckdb/node-bindings-linux-x64-musl": {
- "version": "1.5.3-r.3",
- "resolved": "https://registry.npmjs.org/@duckdb/node-bindings-linux-x64-musl/-/node-bindings-linux-x64-musl-1.5.3-r.3.tgz",
- "integrity": "sha512-5bulS16YhftXcarki4tvCufVslntpQDLOEF6RZ+FSMOGiv5d7SDXqklmVRy4DKW3C5ekgN7S2oYzuGL/ss9BuA==",
+ "version": "1.5.4-r.1",
+ "resolved": "https://registry.npmjs.org/@duckdb/node-bindings-linux-x64-musl/-/node-bindings-linux-x64-musl-1.5.4-r.1.tgz",
+ "integrity": "sha512-tWgnttlKfWTktyv+m9YbxaedKBon5wmUoJ9DaIbE3D98KhhUaqmJhnjzso9O8hp6WUeRmwXR//hpT/X6Ft9nYA==",
"cpu": [
"x64"
],
@@ -2243,9 +2243,9 @@
]
},
"node_modules/@duckdb/node-bindings-win32-arm64": {
- "version": "1.5.3-r.3",
- "resolved": "https://registry.npmjs.org/@duckdb/node-bindings-win32-arm64/-/node-bindings-win32-arm64-1.5.3-r.3.tgz",
- "integrity": "sha512-55Vu13S0jUudiAGlNWJd7UvlW1iKjwWehD8s93jBCNm0AdE/EJN4nz5rQ0IuWzPWXpMjAYuKu00yE7NdtbTyug==",
+ "version": "1.5.4-r.1",
+ "resolved": "https://registry.npmjs.org/@duckdb/node-bindings-win32-arm64/-/node-bindings-win32-arm64-1.5.4-r.1.tgz",
+ "integrity": "sha512-77apmuNo51bPZzv8xjdeCp+hlU6JLwMPtS1CMViy83ONTsah+CGnpBx1lCnEqPL5Va0meufZyjSdZCVCijLdDA==",
"cpu": [
"arm64"
],
@@ -2257,9 +2257,9 @@
]
},
"node_modules/@duckdb/node-bindings-win32-x64": {
- "version": "1.5.3-r.3",
- "resolved": "https://registry.npmjs.org/@duckdb/node-bindings-win32-x64/-/node-bindings-win32-x64-1.5.3-r.3.tgz",
- "integrity": "sha512-rlOc9ltWQNHuDq99Ah8XaD80nN1ucrSK5AcH/7ibSp9ogX/jswPYlRVE7ODFJAjnQNf8bVvs++Mp+wyGvuG7ag==",
+ "version": "1.5.4-r.1",
+ "resolved": "https://registry.npmjs.org/@duckdb/node-bindings-win32-x64/-/node-bindings-win32-x64-1.5.4-r.1.tgz",
+ "integrity": "sha512-Wme7dScBGqjn2PUJ+RLFiFAblW1qQRBraX7SJc4uKtftZiUJJWZapEUh+doGfb68Qxvw8JhlMBSdaUsSUDJYsw==",
"cpu": [
"x64"
],
@@ -5109,44 +5109,54 @@
"license": "ISC"
},
"node_modules/@willfarrell-ds/cli": {
- "version": "0.0.0-alpha.6",
- "resolved": "https://registry.npmjs.org/@willfarrell-ds/cli/-/cli-0.0.0-alpha.6.tgz",
- "integrity": "sha512-CIEnRyopUAil0yPrAYqg8jEnSwc1dzIe5LQbi0/ghuWukSHrwcrWGoqBwTfuBOddg3087kIHj3YXHyJncOG1qw==",
+ "version": "0.0.0-alpha.8",
+ "resolved": "https://registry.npmjs.org/@willfarrell-ds/cli/-/cli-0.0.0-alpha.8.tgz",
+ "integrity": "sha512-UgxKWi7Pj3f3G/tr/mZV+dSFZn9htjp5iDzzWWfwmC/8JBxzapSSUaG46VY33a/y3zTro6ruuY2oGX7Hi5uBmg==",
"dev": true,
"license": "MIT",
"dependencies": {
"color-convert": "3.1.3",
- "commander": "14.0.3",
- "mathjs": "15.1.1"
+ "commander": "15.0.0",
+ "mathjs": "15.2.0"
},
"bin": {
"ds": "index.js"
}
},
+ "node_modules/@willfarrell-ds/cli/node_modules/commander": {
+ "version": "15.0.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-15.0.0.tgz",
+ "integrity": "sha512-z67u4ZhzCL/Tydu1lJARtEZYWbWaN7oYLHbsuzocr6y4N6WZAagG3RQ4FW61V1/0+jImpj293XfrcYnd1qxtPg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=22.12.0"
+ }
+ },
"node_modules/@willfarrell-ds/svelte": {
- "version": "0.0.0-alpha.6",
- "resolved": "https://registry.npmjs.org/@willfarrell-ds/svelte/-/svelte-0.0.0-alpha.6.tgz",
- "integrity": "sha512-6xnvXlOWj6h/kWIx6RG0J28XmmwMTIVp6zxqeZlmifymS8l28G8qsg2tCHyaN+09gw7hTvLoQ2P4wCF2FMr9HA==",
+ "version": "0.0.0-alpha.8",
+ "resolved": "https://registry.npmjs.org/@willfarrell-ds/svelte/-/svelte-0.0.0-alpha.8.tgz",
+ "integrity": "sha512-S5a/qPwPa5n2POUs8XyfmzXFbXouJ+zQuSjnJIuA7R7iF2CLRHUfc2a/QeV8bD1E/L5aCGTlqtBLpTw7Z3XS0g==",
"license": "MIT",
"dependencies": {
- "@willfarrell-ds/vanilla": "0.0.0-alpha.6",
+ "@willfarrell-ds/vanilla": "0.0.0-alpha.8",
"pretty": "2.0.0",
- "prismjs": "1.30.0",
- "tinykeys": "3.0.0"
+ "prismjs": "1.30.0"
},
"peerDependencies": {
- "svelte": "^5.0.0"
+ "svelte": "^5.55.7"
}
},
"node_modules/@willfarrell-ds/vanilla": {
- "version": "0.0.0-alpha.6",
- "resolved": "https://registry.npmjs.org/@willfarrell-ds/vanilla/-/vanilla-0.0.0-alpha.6.tgz",
- "integrity": "sha512-a7fWbPJZkDcMQ/OK1pLMSAk6DIBBVN52VaJrXu/lUur4VUrX3Sa0W3UVPAQgWaJ5gkFYfxBjTw3rVkm2PwWLGQ==",
+ "version": "0.0.0-alpha.8",
+ "resolved": "https://registry.npmjs.org/@willfarrell-ds/vanilla/-/vanilla-0.0.0-alpha.8.tgz",
+ "integrity": "sha512-XpTDThlFuX338TGXtwQWL1uryddY85rsAeFg7IyMFBrS/8vJuZr/5wmW82LX5bB+h6DR45IiUtvB262VXMI+jg==",
"license": "MIT",
"dependencies": {
"@simplewebauthn/browser": "13.3.0",
"@ungap/custom-elements": "1.3.0",
- "accessible-autocomplete": "3.0.1"
+ "accessible-autocomplete": "3.0.1",
+ "tinykeys": "4.0.0"
}
},
"node_modules/@yarnpkg/parsers": {
@@ -5808,7 +5818,6 @@
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/chardet/-/chardet-2.2.0.tgz",
"integrity": "sha512-rddelWYNPRrXq6PtNEN2S3f6t9ILzvqaN5pVgi4kqt9jHQaXIial9PznB5iSPVlQSLNaaH22ItWz3EJtQ10+OA==",
- "dev": true,
"license": "MIT"
},
"node_modules/cheerio": {
@@ -7295,7 +7304,6 @@
"version": "0.7.3",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.3.tgz",
"integrity": "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==",
- "dev": true,
"license": "MIT",
"dependencies": {
"safer-buffer": ">= 2.1.2 < 3.0.0"
@@ -10149,10 +10157,13 @@
}
},
"node_modules/tinykeys": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/tinykeys/-/tinykeys-3.0.0.tgz",
- "integrity": "sha512-nazawuGv5zx6MuDfDY0rmfXjuOGhD5XU2z0GLURQ1nzl0RUe9OuCJq+0u8xxJZINHe+mr7nw8PWYYZ9WhMFujw==",
- "license": "MIT"
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/tinykeys/-/tinykeys-4.0.0.tgz",
+ "integrity": "sha512-z5bQRQHL1PSx3lGOZEAMM2oKp0EBtn5T5f7HJnaKPOzk6vEH0wUPvdHLeQ7F4tmkek8AgoTQISUFmn/5SNF2xA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=22"
+ }
},
"node_modules/to-regex-range": {
"version": "5.0.1",
@@ -10505,9 +10516,9 @@
"license": "MIT"
},
"node_modules/uuid": {
- "version": "14.0.0",
- "resolved": "https://registry.npmjs.org/uuid/-/uuid-14.0.0.tgz",
- "integrity": "sha512-Qo+uWgilfSmAhXCMav1uYFynlQO7fMFiMVZsQqZRMIXp0O7rR7qjkj+cPvBHLgBqi960QCoo/PH2/6ZtVqKvrg==",
+ "version": "14.0.1",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-14.0.1.tgz",
+ "integrity": "sha512-6ZxzVpzDXDa3bJWaHilVayA+BH/1zmxCJoVgvmqJnid/gPoKHxUrS/aC/T6LGQtNHT+XHG9fXPJB4d+IrU30Ew==",
"funding": [
"https://github.com/sponsors/broofa",
"https://github.com/sponsors/ctavan"
@@ -11219,35 +11230,13 @@
"license": "MIT",
"dependencies": {
"@datastream/core": "0.6.0",
- "chardet": "2.1.1",
- "iconv-lite": "0.7.2"
+ "chardet": "2.2.0",
+ "iconv-lite": "0.7.3"
},
"engines": {
"node": ">=24"
}
},
- "packages/charset/node_modules/chardet": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.1.tgz",
- "integrity": "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==",
- "license": "MIT"
- },
- "packages/charset/node_modules/iconv-lite": {
- "version": "0.7.2",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz",
- "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==",
- "license": "MIT",
- "dependencies": {
- "safer-buffer": ">= 2.1.2 < 3.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/express"
- }
- },
"packages/compress": {
"name": "@datastream/compress",
"version": "0.6.0",
@@ -11314,16 +11303,16 @@
},
"devDependencies": {
"@datastream/arrow": "0.6.0",
- "@duckdb/duckdb-wasm": "1.33.1-dev45.0",
- "@duckdb/node-api": "1.5.3-r.3",
+ "@duckdb/duckdb-wasm": "1.33.1-dev57.0",
+ "@duckdb/node-api": "1.5.4-r.1",
"apache-arrow": "21.1.0"
},
"engines": {
"node": ">=24"
},
"peerDependencies": {
- "@duckdb/duckdb-wasm": "^1.33.1-dev45.0",
- "@duckdb/node-api": "^1.5.3-r.1",
+ "@duckdb/duckdb-wasm": "^1.33.1-dev57.0",
+ "@duckdb/node-api": "^1.5.4-r.1",
"apache-arrow": "21.1.0"
},
"peerDependenciesMeta": {
@@ -11509,17 +11498,17 @@
"version": "0.6.0",
"dependencies": {
"@plausible-analytics/tracker": "0.4.5",
- "@willfarrell-ds/svelte": "0.0.0-alpha.6",
- "@willfarrell-ds/vanilla": "0.0.0-alpha.6",
+ "@willfarrell-ds/svelte": "0.0.0-alpha.8",
+ "@willfarrell-ds/vanilla": "0.0.0-alpha.8",
"hast-util-to-string": "3.0.1",
"mdast-util-to-string": "4.0.0",
- "uuid": "14.0.0"
+ "uuid": "14.0.1"
},
"devDependencies": {
"@sveltejs/adapter-cloudflare": "^7.0.0",
"@sveltejs/kit": "^2.60.1",
"@sveltejs/vite-plugin-svelte": "^7.0.0",
- "@willfarrell-ds/cli": "0.0.0-alpha.6",
+ "@willfarrell-ds/cli": "0.0.0-alpha.8",
"esbuild": "^0.28.0",
"mdsvex": "^0.12.0",
"svelte": "^5.55.7",
@@ -11535,13 +11524,6 @@
"node": ">=24"
}
},
- "websites/datastream.js.org/node_modules/@cloudflare/workers-types": {
- "version": "4.20260702.1",
- "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20260702.1.tgz",
- "integrity": "sha512-mOhf5TUEB1m2vPrxtqoIGfz0fUC9xyxRDx5gWHy5s+OCo6dcV+g7wI1R7gYCMFohhqF/2y2xeKVwMwCJjfn/WA==",
- "dev": true,
- "license": "MIT OR Apache-2.0"
- },
"websites/datastream.js.org/node_modules/@sveltejs/adapter-cloudflare": {
"version": "7.2.9",
"resolved": "https://registry.npmjs.org/@sveltejs/adapter-cloudflare/-/adapter-cloudflare-7.2.9.tgz",
@@ -11608,20 +11590,6 @@
"engines": {
"node": ">= 0.6"
}
- },
- "websites/datastream.js.org/node_modules/typescript": {
- "version": "6.0.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz",
- "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==",
- "extraneous": true,
- "license": "Apache-2.0",
- "bin": {
- "tsc": "bin/tsc",
- "tsserver": "bin/tsserver"
- },
- "engines": {
- "node": ">=14.17"
- }
}
}
}
diff --git a/packages/charset/package.json b/packages/charset/package.json
index b118e78..0857daf 100644
--- a/packages/charset/package.json
+++ b/packages/charset/package.json
@@ -110,7 +110,7 @@
"homepage": "https://datastream.js.org",
"dependencies": {
"@datastream/core": "0.6.0",
- "chardet": "2.1.1",
- "iconv-lite": "0.7.2"
+ "chardet": "2.2.0",
+ "iconv-lite": "0.7.3"
}
}
diff --git a/packages/duckdb/package.json b/packages/duckdb/package.json
index 70992d9..6a1f28f 100644
--- a/packages/duckdb/package.json
+++ b/packages/duckdb/package.json
@@ -67,8 +67,8 @@
"@datastream/core": "0.6.0"
},
"peerDependencies": {
- "@duckdb/duckdb-wasm": "^1.33.1-dev45.0",
- "@duckdb/node-api": "^1.5.3-r.1",
+ "@duckdb/duckdb-wasm": "^1.33.1-dev57.0",
+ "@duckdb/node-api": "^1.5.4-r.1",
"apache-arrow": "21.1.0"
},
"peerDependenciesMeta": {
@@ -84,8 +84,8 @@
},
"devDependencies": {
"@datastream/arrow": "0.6.0",
- "@duckdb/duckdb-wasm": "1.33.1-dev45.0",
- "@duckdb/node-api": "1.5.3-r.3",
+ "@duckdb/duckdb-wasm": "1.33.1-dev57.0",
+ "@duckdb/node-api": "1.5.4-r.1",
"apache-arrow": "21.1.0"
}
}
diff --git a/websites/datastream.js.org/package.json b/websites/datastream.js.org/package.json
index cc3a0d7..b14441d 100644
--- a/websites/datastream.js.org/package.json
+++ b/websites/datastream.js.org/package.json
@@ -23,17 +23,17 @@
},
"dependencies": {
"@plausible-analytics/tracker": "0.4.5",
- "@willfarrell-ds/svelte": "0.0.0-alpha.6",
- "@willfarrell-ds/vanilla": "0.0.0-alpha.6",
+ "@willfarrell-ds/svelte": "0.0.0-alpha.8",
+ "@willfarrell-ds/vanilla": "0.0.0-alpha.8",
"hast-util-to-string": "3.0.1",
"mdast-util-to-string": "4.0.0",
- "uuid": "14.0.0"
+ "uuid": "14.0.1"
},
"devDependencies": {
"@sveltejs/adapter-cloudflare": "^7.0.0",
"@sveltejs/kit": "^2.60.1",
"@sveltejs/vite-plugin-svelte": "^7.0.0",
- "@willfarrell-ds/cli": "0.0.0-alpha.6",
+ "@willfarrell-ds/cli": "0.0.0-alpha.8",
"esbuild": "^0.28.0",
"mdsvex": "^0.12.0",
"svelte": "^5.55.7",
diff --git a/websites/datastream.js.org/src/components/BodyFooter.svelte b/websites/datastream.js.org/src/components/BodyFooter.svelte
index b5b4cc8..40e9916 100644
--- a/websites/datastream.js.org/src/components/BodyFooter.svelte
+++ b/websites/datastream.js.org/src/components/BodyFooter.svelte
@@ -2,10 +2,6 @@
import BodyFooter from "@design-system/components/BodyFooter.svelte";
import Image from "@design-system/components/Image.svelte";
import A from "@design-system/elements/a.svelte";
-import { page } from "$app/state";
-
-const { children } = $props();
-const { url, params, data, form } = page;
const navLinks = {
Docs: {
diff --git a/websites/datastream.js.org/src/components/BodyHeader.svelte b/websites/datastream.js.org/src/components/BodyHeader.svelte
index 93c02cf..3fae7c6 100644
--- a/websites/datastream.js.org/src/components/BodyHeader.svelte
+++ b/websites/datastream.js.org/src/components/BodyHeader.svelte
@@ -12,7 +12,7 @@ import Span from "@design-system/elements/span.svelte";
import webComponentUrl from "@willfarrell-ds/vanilla/components/ds-input-focus.js?worker&url";
import { page } from "$app/state";
-const { params, data, form } = page;
+const { data, form } = page;
const navTopLinks = {
[`v${data.version}`]: true,
diff --git a/websites/datastream.js.org/src/components/docs/AsideNav.svelte b/websites/datastream.js.org/src/components/docs/AsideNav.svelte
index 8d941de..278d21f 100644
--- a/websites/datastream.js.org/src/components/docs/AsideNav.svelte
+++ b/websites/datastream.js.org/src/components/docs/AsideNav.svelte
@@ -1,8 +1,5 @@
diff --git a/websites/datastream.js.org/src/routes/search/+page.svelte b/websites/datastream.js.org/src/routes/search/+page.svelte
index bc7edb5..ecca25a 100644
--- a/websites/datastream.js.org/src/routes/search/+page.svelte
+++ b/websites/datastream.js.org/src/routes/search/+page.svelte
@@ -4,7 +4,6 @@ import H1 from "@design-system/components/Heading1.svelte";
import H2 from "@design-system/components/Heading2.svelte";
import LayoutCenter from "@design-system/components/LayoutCenter.svelte";
import A from "@design-system/elements/a.svelte";
-import Li from "@design-system/elements/li.svelte";
import P from "@design-system/elements/p.svelte";
import Section from "@design-system/elements/section.svelte";
import Span from "@design-system/elements/span.svelte";
From f0a574c7d95b401ddff9bc9811c445c1b94679bf Mon Sep 17 00:00:00 2001
From: will Farrell
Date: Sat, 11 Jul 2026 11:36:55 -0600
Subject: [PATCH 26/27] chore: version bump
Signed-off-by: will Farrell
---
.github/package.json | 2 +-
package-lock.json | 125 ++++++++++++++----------
package.json | 2 +-
packages/arrow/package.json | 4 +-
packages/aws/package.json | 4 +-
packages/base64/package.json | 4 +-
packages/charset/package.json | 4 +-
packages/compress/package.json | 4 +-
packages/core/package.json | 4 +-
packages/csv/package.json | 6 +-
packages/digest/package.json | 4 +-
packages/duckdb/package.json | 6 +-
packages/encrypt/package.json | 4 +-
packages/fetch/package.json | 4 +-
packages/file/package.json | 4 +-
packages/indexeddb/package.json | 4 +-
packages/ipfs/package.json | 4 +-
packages/json/package.json | 4 +-
packages/kafka/package.json | 4 +-
packages/object/package.json | 4 +-
packages/protobuf/package.json | 4 +-
packages/schema-registry/package.json | 4 +-
packages/string/package.json | 4 +-
packages/validate/package.json | 4 +-
websites/datastream.js.org/package.json | 2 +-
25 files changed, 120 insertions(+), 99 deletions(-)
diff --git a/.github/package.json b/.github/package.json
index debb2db..fcb2ded 100644
--- a/.github/package.json
+++ b/.github/package.json
@@ -1,6 +1,6 @@
{
"name": "@datastream/github-workflows",
- "version": "0.6.0",
+ "version": "0.6.1",
"private": true,
"type": "module",
"engines": {
diff --git a/package-lock.json b/package-lock.json
index 50314c7..3546e59 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "@datastream/monorepo",
- "version": "0.6.0",
+ "version": "0.6.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@datastream/monorepo",
- "version": "0.6.0",
+ "version": "0.6.1",
"license": "MIT",
"workspaces": [
"packages/*",
@@ -31,7 +31,7 @@
},
".github": {
"name": "@datastream/github-workflows",
- "version": "0.6.0",
+ "version": "0.6.1",
"devDependencies": {
"license-check-and-add": "4.0.5",
"lockfile-lint": "5.0.0"
@@ -1605,10 +1605,10 @@
}
},
"node_modules/@cloudflare/workers-types": {
- "version": "4.20260702.1",
- "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20260702.1.tgz",
- "integrity": "sha512-mOhf5TUEB1m2vPrxtqoIGfz0fUC9xyxRDx5gWHy5s+OCo6dcV+g7wI1R7gYCMFohhqF/2y2xeKVwMwCJjfn/WA==",
- "dev": true,
+ "version": "5.20260711.1",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-5.20260711.1.tgz",
+ "integrity": "sha512-yY6GXfyrHJa33EWaSzS5N56Lsll02kgHo4Qodz2l2DNl4L6L5yXBMZVMvcYArirdYA1xn+o8LKVRQGdRpmSMzA==",
+ "extraneous": true,
"license": "MIT OR Apache-2.0"
},
"node_modules/@commitlint/cli": {
@@ -11130,10 +11130,10 @@
},
"packages/arrow": {
"name": "@datastream/arrow",
- "version": "0.6.0",
+ "version": "0.6.1",
"license": "MIT",
"dependencies": {
- "@datastream/core": "0.6.0",
+ "@datastream/core": "0.6.1",
"apache-arrow": "21.1.0"
},
"engines": {
@@ -11142,10 +11142,10 @@
},
"packages/aws": {
"name": "@datastream/aws",
- "version": "0.6.0",
+ "version": "0.6.1",
"license": "MIT",
"dependencies": {
- "@datastream/core": "0.6.0"
+ "@datastream/core": "0.6.1"
},
"devDependencies": {
"@aws-sdk/client-cloudwatch-logs": "^3.0.0",
@@ -11215,10 +11215,10 @@
},
"packages/base64": {
"name": "@datastream/base64",
- "version": "0.6.0",
+ "version": "0.6.1",
"license": "MIT",
"dependencies": {
- "@datastream/core": "0.6.0"
+ "@datastream/core": "0.6.1"
},
"engines": {
"node": ">=24"
@@ -11226,10 +11226,10 @@
},
"packages/charset": {
"name": "@datastream/charset",
- "version": "0.6.0",
+ "version": "0.6.1",
"license": "MIT",
"dependencies": {
- "@datastream/core": "0.6.0",
+ "@datastream/core": "0.6.1",
"chardet": "2.2.0",
"iconv-lite": "0.7.3"
},
@@ -11239,10 +11239,10 @@
},
"packages/compress": {
"name": "@datastream/compress",
- "version": "0.6.0",
+ "version": "0.6.1",
"license": "MIT",
"dependencies": {
- "@datastream/core": "0.6.0"
+ "@datastream/core": "0.6.1"
},
"devDependencies": {
"brotli-wasm": "^3.0.0"
@@ -11261,10 +11261,10 @@
},
"packages/core": {
"name": "@datastream/core",
- "version": "0.6.0",
+ "version": "0.6.1",
"license": "MIT",
"devDependencies": {
- "@datastream/object": "0.6.0"
+ "@datastream/object": "0.6.1"
},
"engines": {
"node": ">=24"
@@ -11272,11 +11272,11 @@
},
"packages/csv": {
"name": "@datastream/csv",
- "version": "0.6.0",
+ "version": "0.6.1",
"license": "MIT",
"dependencies": {
- "@datastream/core": "0.6.0",
- "@datastream/object": "0.6.0"
+ "@datastream/core": "0.6.1",
+ "@datastream/object": "0.6.1"
},
"engines": {
"node": ">=24"
@@ -11284,10 +11284,10 @@
},
"packages/digest": {
"name": "@datastream/digest",
- "version": "0.6.0",
+ "version": "0.6.1",
"license": "MIT",
"dependencies": {
- "@datastream/core": "0.6.0",
+ "@datastream/core": "0.6.1",
"hash-wasm": "4.12.0"
},
"engines": {
@@ -11296,13 +11296,13 @@
},
"packages/duckdb": {
"name": "@datastream/duckdb",
- "version": "0.6.0",
+ "version": "0.6.1",
"license": "MIT",
"dependencies": {
- "@datastream/core": "0.6.0"
+ "@datastream/core": "0.6.1"
},
"devDependencies": {
- "@datastream/arrow": "0.6.0",
+ "@datastream/arrow": "0.6.1",
"@duckdb/duckdb-wasm": "1.33.1-dev57.0",
"@duckdb/node-api": "1.5.4-r.1",
"apache-arrow": "21.1.0"
@@ -11329,10 +11329,10 @@
},
"packages/encrypt": {
"name": "@datastream/encrypt",
- "version": "0.6.0",
+ "version": "0.6.1",
"license": "MIT",
"dependencies": {
- "@datastream/core": "0.6.0"
+ "@datastream/core": "0.6.1"
},
"devDependencies": {
"libsodium-wrappers": ">=0.7.0"
@@ -11351,10 +11351,10 @@
},
"packages/fetch": {
"name": "@datastream/fetch",
- "version": "0.6.0",
+ "version": "0.6.1",
"license": "MIT",
"dependencies": {
- "@datastream/core": "0.6.0"
+ "@datastream/core": "0.6.1"
},
"engines": {
"node": ">=24"
@@ -11362,10 +11362,10 @@
},
"packages/file": {
"name": "@datastream/file",
- "version": "0.6.0",
+ "version": "0.6.1",
"license": "MIT",
"dependencies": {
- "@datastream/core": "0.6.0"
+ "@datastream/core": "0.6.1"
},
"engines": {
"node": ">=24"
@@ -11373,10 +11373,10 @@
},
"packages/indexeddb": {
"name": "@datastream/indexeddb",
- "version": "0.6.0",
+ "version": "0.6.1",
"license": "MIT",
"dependencies": {
- "@datastream/core": "0.6.0",
+ "@datastream/core": "0.6.1",
"idb": "8.0.3"
},
"engines": {
@@ -11385,10 +11385,10 @@
},
"packages/ipfs": {
"name": "@datastream/ipfs",
- "version": "0.6.0",
+ "version": "0.6.1",
"license": "MIT",
"dependencies": {
- "@datastream/core": "0.6.0"
+ "@datastream/core": "0.6.1"
},
"engines": {
"node": ">=24"
@@ -11396,10 +11396,10 @@
},
"packages/json": {
"name": "@datastream/json",
- "version": "0.6.0",
+ "version": "0.6.1",
"license": "MIT",
"dependencies": {
- "@datastream/core": "0.6.0"
+ "@datastream/core": "0.6.1"
},
"engines": {
"node": ">=24"
@@ -11407,10 +11407,10 @@
},
"packages/kafka": {
"name": "@datastream/kafka",
- "version": "0.6.0",
+ "version": "0.6.1",
"license": "MIT",
"dependencies": {
- "@datastream/core": "0.6.0"
+ "@datastream/core": "0.6.1"
},
"devDependencies": {
"kafkajs": "^2.0.0"
@@ -11429,10 +11429,10 @@
},
"packages/object": {
"name": "@datastream/object",
- "version": "0.6.0",
+ "version": "0.6.1",
"license": "MIT",
"dependencies": {
- "@datastream/core": "0.6.0"
+ "@datastream/core": "0.6.1"
},
"engines": {
"node": ">=24"
@@ -11440,10 +11440,10 @@
},
"packages/protobuf": {
"name": "@datastream/protobuf",
- "version": "0.6.0",
+ "version": "0.6.1",
"license": "MIT",
"dependencies": {
- "@datastream/core": "0.6.0"
+ "@datastream/core": "0.6.1"
},
"devDependencies": {
"protobufjs": "^8.0.0"
@@ -11462,10 +11462,10 @@
},
"packages/schema-registry": {
"name": "@datastream/schema-registry",
- "version": "0.6.0",
+ "version": "0.6.1",
"license": "MIT",
"dependencies": {
- "@datastream/core": "0.6.0"
+ "@datastream/core": "0.6.1"
},
"engines": {
"node": ">=24"
@@ -11473,10 +11473,10 @@
},
"packages/string": {
"name": "@datastream/string",
- "version": "0.6.0",
+ "version": "0.6.1",
"license": "MIT",
"dependencies": {
- "@datastream/core": "0.6.0"
+ "@datastream/core": "0.6.1"
},
"engines": {
"node": ">=24"
@@ -11484,10 +11484,10 @@
},
"packages/validate": {
"name": "@datastream/validate",
- "version": "0.6.0",
+ "version": "0.6.1",
"license": "MIT",
"dependencies": {
- "@datastream/core": "0.6.0",
+ "@datastream/core": "0.6.1",
"ajv-cmd": "0.13.3"
},
"engines": {
@@ -11495,7 +11495,7 @@
}
},
"websites/datastream.js.org": {
- "version": "0.6.0",
+ "version": "0.6.1",
"dependencies": {
"@plausible-analytics/tracker": "0.4.5",
"@willfarrell-ds/svelte": "0.0.0-alpha.8",
@@ -11524,6 +11524,13 @@
"node": ">=24"
}
},
+ "websites/datastream.js.org/node_modules/@cloudflare/workers-types": {
+ "version": "4.20260702.1",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20260702.1.tgz",
+ "integrity": "sha512-mOhf5TUEB1m2vPrxtqoIGfz0fUC9xyxRDx5gWHy5s+OCo6dcV+g7wI1R7gYCMFohhqF/2y2xeKVwMwCJjfn/WA==",
+ "dev": true,
+ "license": "MIT OR Apache-2.0"
+ },
"websites/datastream.js.org/node_modules/@sveltejs/adapter-cloudflare": {
"version": "7.2.9",
"resolved": "https://registry.npmjs.org/@sveltejs/adapter-cloudflare/-/adapter-cloudflare-7.2.9.tgz",
@@ -11590,6 +11597,20 @@
"engines": {
"node": ">= 0.6"
}
+ },
+ "websites/datastream.js.org/node_modules/typescript": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz",
+ "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==",
+ "extraneous": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
}
}
}
diff --git a/package.json b/package.json
index d1e58b6..5101220 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@datastream/monorepo",
- "version": "0.6.0",
+ "version": "0.6.1",
"description": "Streams made easy.",
"private": true,
"type": "module",
diff --git a/packages/arrow/package.json b/packages/arrow/package.json
index e28dff0..753a7ef 100644
--- a/packages/arrow/package.json
+++ b/packages/arrow/package.json
@@ -1,6 +1,6 @@
{
"name": "@datastream/arrow",
- "version": "0.6.0",
+ "version": "0.6.1",
"description": "Apache Arrow record batch transform streams",
"type": "module",
"engines": {
@@ -64,7 +64,7 @@
},
"homepage": "https://datastream.js.org",
"dependencies": {
- "@datastream/core": "0.6.0",
+ "@datastream/core": "0.6.1",
"apache-arrow": "21.1.0"
}
}
diff --git a/packages/aws/package.json b/packages/aws/package.json
index 4579a48..771a00a 100644
--- a/packages/aws/package.json
+++ b/packages/aws/package.json
@@ -1,6 +1,6 @@
{
"name": "@datastream/aws",
- "version": "0.6.0",
+ "version": "0.6.1",
"description": "AWS service streaming integrations for CloudWatch Logs, DynamoDB, DynamoDB Streams, Kinesis, Lambda, S3, SNS, and SQS",
"type": "module",
"engines": {
@@ -187,7 +187,7 @@
},
"homepage": "https://datastream.js.org",
"dependencies": {
- "@datastream/core": "0.6.0"
+ "@datastream/core": "0.6.1"
},
"peerDependencies": {
"@aws-sdk/client-cloudwatch-logs": "^3.0.0",
diff --git a/packages/base64/package.json b/packages/base64/package.json
index c77452b..62750fb 100644
--- a/packages/base64/package.json
+++ b/packages/base64/package.json
@@ -1,6 +1,6 @@
{
"name": "@datastream/base64",
- "version": "0.6.0",
+ "version": "0.6.1",
"description": "Base64 encoding and decoding transform streams",
"type": "module",
"engines": {
@@ -61,6 +61,6 @@
},
"homepage": "https://datastream.js.org",
"dependencies": {
- "@datastream/core": "0.6.0"
+ "@datastream/core": "0.6.1"
}
}
diff --git a/packages/charset/package.json b/packages/charset/package.json
index 0857daf..943428a 100644
--- a/packages/charset/package.json
+++ b/packages/charset/package.json
@@ -1,6 +1,6 @@
{
"name": "@datastream/charset",
- "version": "0.6.0",
+ "version": "0.6.1",
"description": "Character encoding detection, decoding, and conversion streams",
"type": "module",
"engines": {
@@ -109,7 +109,7 @@
},
"homepage": "https://datastream.js.org",
"dependencies": {
- "@datastream/core": "0.6.0",
+ "@datastream/core": "0.6.1",
"chardet": "2.2.0",
"iconv-lite": "0.7.3"
}
diff --git a/packages/compress/package.json b/packages/compress/package.json
index 5e2c3bf..420216e 100644
--- a/packages/compress/package.json
+++ b/packages/compress/package.json
@@ -1,6 +1,6 @@
{
"name": "@datastream/compress",
- "version": "0.6.0",
+ "version": "0.6.1",
"description": "Compression and decompression streams for gzip, deflate, brotli, and zstd",
"type": "module",
"engines": {
@@ -125,7 +125,7 @@
},
"homepage": "https://datastream.js.org",
"dependencies": {
- "@datastream/core": "0.6.0"
+ "@datastream/core": "0.6.1"
},
"devDependencies": {
"brotli-wasm": "^3.0.0"
diff --git a/packages/core/package.json b/packages/core/package.json
index d42e7a0..4bdd7f3 100644
--- a/packages/core/package.json
+++ b/packages/core/package.json
@@ -1,6 +1,6 @@
{
"name": "@datastream/core",
- "version": "0.6.0",
+ "version": "0.6.1",
"description": "Stream creation utilities and pipeline functions for Web Streams API and Node.js streams",
"type": "module",
"engines": {
@@ -62,6 +62,6 @@
"homepage": "https://datastream.js.org",
"dependencies": {},
"devDependencies": {
- "@datastream/object": "0.6.0"
+ "@datastream/object": "0.6.1"
}
}
diff --git a/packages/csv/package.json b/packages/csv/package.json
index dcd6154..07c2ebc 100644
--- a/packages/csv/package.json
+++ b/packages/csv/package.json
@@ -1,6 +1,6 @@
{
"name": "@datastream/csv",
- "version": "0.6.0",
+ "version": "0.6.1",
"description": "CSV parsing and formatting transform streams",
"type": "module",
"engines": {
@@ -64,7 +64,7 @@
},
"homepage": "https://datastream.js.org",
"dependencies": {
- "@datastream/core": "0.6.0",
- "@datastream/object": "0.6.0"
+ "@datastream/core": "0.6.1",
+ "@datastream/object": "0.6.1"
}
}
diff --git a/packages/digest/package.json b/packages/digest/package.json
index 626cca9..4636989 100644
--- a/packages/digest/package.json
+++ b/packages/digest/package.json
@@ -1,6 +1,6 @@
{
"name": "@datastream/digest",
- "version": "0.6.0",
+ "version": "0.6.1",
"description": "Cryptographic hash digest pass-through streams",
"type": "module",
"engines": {
@@ -61,7 +61,7 @@
},
"homepage": "https://datastream.js.org",
"dependencies": {
- "@datastream/core": "0.6.0",
+ "@datastream/core": "0.6.1",
"hash-wasm": "4.12.0"
}
}
diff --git a/packages/duckdb/package.json b/packages/duckdb/package.json
index 6a1f28f..d63c81d 100644
--- a/packages/duckdb/package.json
+++ b/packages/duckdb/package.json
@@ -1,6 +1,6 @@
{
"name": "@datastream/duckdb",
- "version": "0.6.0",
+ "version": "0.6.1",
"description": "DuckDB writable streams (copy-from) for Node and browser",
"type": "module",
"engines": {
@@ -64,7 +64,7 @@
},
"homepage": "https://datastream.js.org",
"dependencies": {
- "@datastream/core": "0.6.0"
+ "@datastream/core": "0.6.1"
},
"peerDependencies": {
"@duckdb/duckdb-wasm": "^1.33.1-dev57.0",
@@ -83,7 +83,7 @@
}
},
"devDependencies": {
- "@datastream/arrow": "0.6.0",
+ "@datastream/arrow": "0.6.1",
"@duckdb/duckdb-wasm": "1.33.1-dev57.0",
"@duckdb/node-api": "1.5.4-r.1",
"apache-arrow": "21.1.0"
diff --git a/packages/encrypt/package.json b/packages/encrypt/package.json
index 86ca642..e5f449b 100644
--- a/packages/encrypt/package.json
+++ b/packages/encrypt/package.json
@@ -1,6 +1,6 @@
{
"name": "@datastream/encrypt",
- "version": "0.6.0",
+ "version": "0.6.1",
"description": "Symmetric encryption/decryption streams",
"type": "module",
"engines": {
@@ -60,7 +60,7 @@
},
"homepage": "https://datastream.js.org",
"dependencies": {
- "@datastream/core": "0.6.0"
+ "@datastream/core": "0.6.1"
},
"devDependencies": {
"libsodium-wrappers": ">=0.7.0"
diff --git a/packages/fetch/package.json b/packages/fetch/package.json
index 27b73e8..a2298b9 100644
--- a/packages/fetch/package.json
+++ b/packages/fetch/package.json
@@ -1,6 +1,6 @@
{
"name": "@datastream/fetch",
- "version": "0.6.0",
+ "version": "0.6.1",
"description": "HTTP fetch-based readable and writable streams with pagination and rate limiting",
"type": "module",
"engines": {
@@ -61,6 +61,6 @@
},
"homepage": "https://datastream.js.org",
"dependencies": {
- "@datastream/core": "0.6.0"
+ "@datastream/core": "0.6.1"
}
}
diff --git a/packages/file/package.json b/packages/file/package.json
index 7088e83..8184c18 100644
--- a/packages/file/package.json
+++ b/packages/file/package.json
@@ -1,6 +1,6 @@
{
"name": "@datastream/file",
- "version": "0.6.0",
+ "version": "0.6.1",
"description": "File system readable and writable streams with extension type enforcement",
"type": "module",
"engines": {
@@ -61,6 +61,6 @@
},
"homepage": "https://datastream.js.org",
"dependencies": {
- "@datastream/core": "0.6.0"
+ "@datastream/core": "0.6.1"
}
}
diff --git a/packages/indexeddb/package.json b/packages/indexeddb/package.json
index a01e1f8..6e52252 100644
--- a/packages/indexeddb/package.json
+++ b/packages/indexeddb/package.json
@@ -1,6 +1,6 @@
{
"name": "@datastream/indexeddb",
- "version": "0.6.0",
+ "version": "0.6.1",
"description": "IndexedDB readable and writable streams for browser storage",
"type": "module",
"engines": {
@@ -61,7 +61,7 @@
},
"homepage": "https://datastream.js.org",
"dependencies": {
- "@datastream/core": "0.6.0",
+ "@datastream/core": "0.6.1",
"idb": "8.0.3"
}
}
diff --git a/packages/ipfs/package.json b/packages/ipfs/package.json
index 54b7749..cd2fb6e 100644
--- a/packages/ipfs/package.json
+++ b/packages/ipfs/package.json
@@ -1,6 +1,6 @@
{
"name": "@datastream/ipfs",
- "version": "0.6.0",
+ "version": "0.6.1",
"description": "IPFS get and add streaming operations",
"type": "module",
"engines": {
@@ -62,6 +62,6 @@
},
"homepage": "https://datastream.js.org",
"dependencies": {
- "@datastream/core": "0.6.0"
+ "@datastream/core": "0.6.1"
}
}
diff --git a/packages/json/package.json b/packages/json/package.json
index e0f3539..c05c577 100644
--- a/packages/json/package.json
+++ b/packages/json/package.json
@@ -1,6 +1,6 @@
{
"name": "@datastream/json",
- "version": "0.6.0",
+ "version": "0.6.1",
"description": "JSON and NDJSON (JSON Lines) parsing and formatting transform streams",
"type": "module",
"engines": {
@@ -64,6 +64,6 @@
},
"homepage": "https://datastream.js.org",
"dependencies": {
- "@datastream/core": "0.6.0"
+ "@datastream/core": "0.6.1"
}
}
diff --git a/packages/kafka/package.json b/packages/kafka/package.json
index 460ef38..88542d9 100644
--- a/packages/kafka/package.json
+++ b/packages/kafka/package.json
@@ -1,6 +1,6 @@
{
"name": "@datastream/kafka",
- "version": "0.6.0",
+ "version": "0.6.1",
"description": "Kafka producer and consumer streams (Node, via kafkajs)",
"type": "module",
"engines": {
@@ -65,7 +65,7 @@
},
"homepage": "https://datastream.js.org",
"dependencies": {
- "@datastream/core": "0.6.0"
+ "@datastream/core": "0.6.1"
},
"peerDependencies": {
"kafkajs": "^2.0.0"
diff --git a/packages/object/package.json b/packages/object/package.json
index 33d9627..46dbd3a 100644
--- a/packages/object/package.json
+++ b/packages/object/package.json
@@ -1,6 +1,6 @@
{
"name": "@datastream/object",
- "version": "0.6.0",
+ "version": "0.6.1",
"description": "Object transform streams for picking, omitting, pivoting, batching, and key mapping",
"type": "module",
"engines": {
@@ -61,6 +61,6 @@
},
"homepage": "https://datastream.js.org",
"dependencies": {
- "@datastream/core": "0.6.0"
+ "@datastream/core": "0.6.1"
}
}
diff --git a/packages/protobuf/package.json b/packages/protobuf/package.json
index cce1bb7..38d3936 100644
--- a/packages/protobuf/package.json
+++ b/packages/protobuf/package.json
@@ -1,6 +1,6 @@
{
"name": "@datastream/protobuf",
- "version": "0.6.0",
+ "version": "0.6.1",
"description": "Protobuf encode/decode and length-prefix framing transform streams",
"type": "module",
"engines": {
@@ -65,7 +65,7 @@
},
"homepage": "https://datastream.js.org",
"dependencies": {
- "@datastream/core": "0.6.0"
+ "@datastream/core": "0.6.1"
},
"devDependencies": {
"protobufjs": "^8.0.0"
diff --git a/packages/schema-registry/package.json b/packages/schema-registry/package.json
index 1c0ab0d..cd2e0d9 100644
--- a/packages/schema-registry/package.json
+++ b/packages/schema-registry/package.json
@@ -1,6 +1,6 @@
{
"name": "@datastream/schema-registry",
- "version": "0.6.0",
+ "version": "0.6.1",
"description": "Schema-Registry wire-format framing transform streams (Confluent and AWS Glue)",
"type": "module",
"engines": {
@@ -66,6 +66,6 @@
},
"homepage": "https://datastream.js.org",
"dependencies": {
- "@datastream/core": "0.6.0"
+ "@datastream/core": "0.6.1"
}
}
diff --git a/packages/string/package.json b/packages/string/package.json
index 9601481..bfc0929 100644
--- a/packages/string/package.json
+++ b/packages/string/package.json
@@ -1,6 +1,6 @@
{
"name": "@datastream/string",
- "version": "0.6.0",
+ "version": "0.6.1",
"description": "String transform streams for splitting, replacing, counting, and deduplication",
"type": "module",
"engines": {
@@ -61,6 +61,6 @@
},
"homepage": "https://datastream.js.org",
"dependencies": {
- "@datastream/core": "0.6.0"
+ "@datastream/core": "0.6.1"
}
}
diff --git a/packages/validate/package.json b/packages/validate/package.json
index b5ded71..a6dd099 100644
--- a/packages/validate/package.json
+++ b/packages/validate/package.json
@@ -1,6 +1,6 @@
{
"name": "@datastream/validate",
- "version": "0.6.0",
+ "version": "0.6.1",
"description": "JSON Schema validation transform streams using Ajv",
"type": "module",
"engines": {
@@ -61,7 +61,7 @@
},
"homepage": "https://datastream.js.org",
"dependencies": {
- "@datastream/core": "0.6.0",
+ "@datastream/core": "0.6.1",
"ajv-cmd": "0.13.3"
}
}
diff --git a/websites/datastream.js.org/package.json b/websites/datastream.js.org/package.json
index b14441d..554c530 100644
--- a/websites/datastream.js.org/package.json
+++ b/websites/datastream.js.org/package.json
@@ -2,7 +2,7 @@
"name": "datastream.js.org",
"description": "SvelteKit SSR",
"private": true,
- "version": "0.6.0",
+ "version": "0.6.1",
"type": "module",
"engines": {
"node": ">=24"
From 58a5795bb7120de788e0ade535793aa98b82db16 Mon Sep 17 00:00:00 2001
From: will Farrell
Date: Sat, 11 Jul 2026 11:39:36 -0600
Subject: [PATCH 27/27] ci: simplify dep update
Signed-off-by: will Farrell
---
.github/dependabot.yml | 10 ----------
1 file changed, 10 deletions(-)
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 476febc..9848ecc 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -18,13 +18,3 @@ updates:
interval: "weekly"
cooldown:
default-days: 14
- groups:
- dev-dependencies:
- dependency-type: "development"
- update-types:
- - "minor"
- - "patch"
- prod-dependencies:
- dependency-type: "production"
- update-types:
- - "patch"