diff --git a/examples/indexer/package.json b/examples/indexer/package.json index a661c35..6a8e39e 100644 --- a/examples/indexer/package.json +++ b/examples/indexer/package.json @@ -19,13 +19,14 @@ "@opentelemetry/sdk-node": "^0.52.0", "@opentelemetry/sdk-trace-base": "^1.25.0", "@opentelemetry/semantic-conventions": "^1.25.0", + "better-sqlite3": "^11.1.2", "citty": "^0.1.6", "consola": "^3.2.3", "csv-stringify": "^6.5.0", - "sqlite": "^5.1.1", "viem": "^2.12.4" }, "devDependencies": { + "@types/better-sqlite3": "^7.6.11", "@types/node": "^20.12.12", "jiti": "^1.21.0" } diff --git a/packages/indexer/package.json b/packages/indexer/package.json index 2a6e51a..2f57d4a 100644 --- a/packages/indexer/package.json +++ b/packages/indexer/package.json @@ -48,10 +48,10 @@ "format": "biome format . --write" }, "devDependencies": { + "@types/better-sqlite3": "^7.6.11", "@types/node": "^20.14.0", + "better-sqlite3": "^11.1.2", "csv-stringify": "^6.5.0", - "sqlite": "^5.1.1", - "sqlite3": "^5.1.7", "unbuild": "^2.0.0", "vitest": "^1.6.0" }, @@ -65,8 +65,8 @@ "unctx": "^2.3.1" }, "peerDependencies": { + "better-sqlite3": "^11.1.2", "csv-stringify": "^6.5.0", - "sqlite": "^5.1.1", "vitest": "^1.6.0" } } diff --git a/packages/indexer/src/indexer.test.ts b/packages/indexer/src/indexer.test.ts index e532cd1..89f0da5 100644 --- a/packages/indexer/src/indexer.test.ts +++ b/packages/indexer/src/indexer.test.ts @@ -1,33 +1,17 @@ -import fs from "node:fs/promises"; import { type MockBlock, MockClient, type MockFilter, } from "@apibara/protocol/testing"; +import Database from "better-sqlite3"; import { klona } from "klona/full"; -import { open } from "sqlite"; -import sqlite3 from "sqlite3"; -import { afterEach, beforeEach, describe, expect, it } from "vitest"; +import { describe, expect, it } from "vitest"; import { run } from "./indexer"; import { SqlitePersistence, sqlitePersistence } from "./plugins/persistence"; import { generateMockMessages, vcr } from "./testing"; import { type MockRet, getMockIndexer } from "./testing/indexer"; describe("Run Test", () => { - async function cleanup() { - try { - await fs.unlink("file:memdb_indexer?mode=memory&cache=shared"); - } catch {} - } - - beforeEach(async () => { - await cleanup(); - }); - - afterEach(async () => { - await cleanup(); - }); - it("should stream messages", async () => { const client = new MockClient((request, options) => { return generateMockMessages(); @@ -260,9 +244,10 @@ describe("Run Test", () => { return []; }); + const db = Database(":memory:"); + const persistence = sqlitePersistence({ - driver: sqlite3.Database, - filename: "file:memdb_indexer?mode=memory&cache=shared", + database: db, }); // create mock indexer with persistence plugin @@ -284,15 +269,9 @@ describe("Run Test", () => { await run(client, indexer, sink); - // open same db again to check last cursor - const db = await open({ - driver: sqlite3.Database, - filename: "file:memdb_indexer?mode=memory&cache=shared", - }); - const store = new SqlitePersistence(db); - const latest = await store.get(); + const latest = store.get(); expect(latest.cursor?.orderKey).toEqual(108n); expect(latest.filter?.filter).toEqual("BC"); @@ -361,6 +340,8 @@ describe("Run Test", () => { }, ] `); + + db.close(); }); it("factory mode: last cursor should persist when error is thrown in indexer", async () => { @@ -440,9 +421,10 @@ describe("Run Test", () => { return []; }); + const db = Database(":memory:"); + const persistence = sqlitePersistence({ - driver: sqlite3.Database, - filename: "file:memdb_indexer?mode=memory&cache=shared", + database: db, }); // create mock indexer with persistence plugin @@ -466,19 +448,15 @@ describe("Run Test", () => { "this error should occurr!", ); - // open same db again to check last cursor - const db = await open({ - driver: sqlite3.Database, - filename: "file:memdb_indexer?mode=memory&cache=shared", - }); - const store = new SqlitePersistence(db); - const latest = await store.get(); + const latest = store.get(); expect(latest.cursor?.orderKey).toEqual(103n); expect(latest.filter?.filter).toEqual("B"); expect(sink.result).toMatchInlineSnapshot("[]"); + + db.close(); }); }); diff --git a/packages/indexer/src/plugins/kv.test.ts b/packages/indexer/src/plugins/kv.test.ts index d322d2a..390b1b1 100644 --- a/packages/indexer/src/plugins/kv.test.ts +++ b/packages/indexer/src/plugins/kv.test.ts @@ -1,55 +1,61 @@ -import { type Database, open } from "sqlite"; -import sqlite3 from "sqlite3"; +import Database, { type Database as SqliteDatabase } from "better-sqlite3"; import { afterAll, beforeAll, describe, expect, it } from "vitest"; import { KVStore } from "./kv"; type ValueType = { data: bigint }; +type DatabaseRowType = { + from_block: number; + k: string; + to_block: number; + v: unknown; +}; + describe("KVStore", () => { - let db: Database; + let db: SqliteDatabase; let store: KVStore; const key = "test_key"; - beforeAll(async () => { - db = await open({ driver: sqlite3.Database, filename: ":memory:" }); - await KVStore.initialize(db); + beforeAll(() => { + db = new Database(":memory:"); + KVStore.initialize(db); store = new KVStore(db, "finalized", { orderKey: 5_000_000n }); }); afterAll(async () => { - await db.close(); + db.close(); }); - it("should begin transaction", async () => { - await store.beginTransaction(); + it("should begin transaction", () => { + store.beginTransaction(); }); it("should put and get a value", async () => { const value = { data: 0n }; - await store.put(key, value); - const result = await store.get(key); + store.put(key, value); + const result = store.get(key); expect(result).toEqual(value); }); it("should commit transaction", async () => { - await store.commitTransaction(); + store.commitTransaction(); const value = { data: 0n }; - const result = await store.get(key); + const result = store.get(key); expect(result).toEqual(value); }); it("should return undefined for non-existing key", async () => { - const result = await store.get("non_existent_key"); + const result = store.get("non_existent_key"); expect(result).toBeUndefined(); }); it("should begin transaction", async () => { - await store.beginTransaction(); + store.beginTransaction(); }); it("should update an existing value", async () => { @@ -57,26 +63,27 @@ describe("KVStore", () => { const value = { data: 50n }; - await store.put(key, value); - const result = await store.get(key); + store.put(key, value); + const result = store.get(key); expect(result).toEqual(value); }); it("should delete a value", async () => { - await store.del(key); - const result = await store.get(key); + store.del(key); + const result = store.get(key); expect(result).toBeUndefined(); - const rows = await db.all( - ` + const rows = db + .prepare( + ` SELECT from_block, to_block, k, v FROM kvs WHERE k = ? `, - [key], - ); + ) + .all(key); // Check that the old is correctly marked with to_block expect(rows[0].to_block).toBe(Number(5_000_020n)); @@ -87,14 +94,15 @@ describe("KVStore", () => { }); it("should revert the changes to last commit", async () => { - const rows = await db.all( - ` + const rows = db + .prepare( + ` SELECT from_block, to_block, k, v FROM kvs WHERE k = ? `, - [key], - ); + ) + .all([key]); expect(rows).toMatchInlineSnapshot(` [ diff --git a/packages/indexer/src/plugins/kv.ts b/packages/indexer/src/plugins/kv.ts index a69ba68..459e11c 100644 --- a/packages/indexer/src/plugins/kv.ts +++ b/packages/indexer/src/plugins/kv.ts @@ -1,128 +1,132 @@ import assert from "node:assert"; import type { Cursor, DataFinality } from "@apibara/protocol"; -import { type Database, type ISqlite, open } from "sqlite"; +import type { Database as SqliteDatabase, Statement } from "better-sqlite3"; import { useIndexerContext } from "../context"; import { deserialize, serialize } from "../vcr"; import { defineIndexerPlugin } from "./config"; -type SqliteArgs = ISqlite.Config; - -export function kv(args: SqliteArgs) { +export function kv({ + database, +}: { database: SqliteDatabase }) { return defineIndexerPlugin((indexer) => { - let db: Database; - - indexer.hooks.hook("run:before", async () => { - db = await open(args); - await KVStore.initialize(db); + indexer.hooks.hook("run:before", () => { + KVStore.initialize(database); }); - indexer.hooks.hook("handler:before", async ({ finality, endCursor }) => { + indexer.hooks.hook("handler:before", ({ finality, endCursor }) => { const ctx = useIndexerContext(); assert(endCursor, new Error("endCursor cannot be undefined")); - ctx.kv = new KVStore(db, finality, endCursor); + ctx.kv = new KVStore(database, finality, endCursor); - await ctx.kv.beginTransaction(); + ctx.kv.beginTransaction(); }); - indexer.hooks.hook("handler:after", async () => { + indexer.hooks.hook("handler:after", () => { const ctx = useIndexerContext(); - await ctx.kv.commitTransaction(); + ctx.kv.commitTransaction(); ctx.kv = null; }); - indexer.hooks.hook("handler:exception", async () => { + indexer.hooks.hook("handler:exception", () => { const ctx = useIndexerContext(); - await ctx.kv.rollbackTransaction(); + ctx.kv.rollbackTransaction(); ctx.kv = null; }); - - indexer.hooks.hook("run:after", async () => { - console.log("kv: ", useIndexerContext().kv); - }); }); } export class KVStore { + /** Sqlite Queries Prepare Statements */ + private _beginTxnQuery: Statement; + private _commitTxnQuery: Statement; + private _rollbackTxnQuery: Statement; + private _getQuery: Statement; + private _updateToBlockQuery: Statement<[number, string]>; + private _insertIntoKvsQuery: Statement<[number, string, string]>; + private _delQuery: Statement<[number, string]>; + constructor( - private _db: Database, + private _db: SqliteDatabase, private _finality: DataFinality, private _endCursor: Cursor, - ) {} - - static async initialize(db: Database) { - await db.exec(` - CREATE TABLE IF NOT EXISTS kvs ( - from_block INTEGER NOT NULL, - to_block INTEGER, - k TEXT NOT NULL, - v BLOB NOT NULL, - PRIMARY KEY (from_block, k) - ); - `); + ) { + this._beginTxnQuery = this._db.prepare(statements.beginTxn); + this._commitTxnQuery = this._db.prepare(statements.commitTxn); + this._rollbackTxnQuery = this._db.prepare(statements.rollbackTxn); + this._getQuery = this._db.prepare(statements.get); + this._updateToBlockQuery = this._db.prepare(statements.updateToBlock); + this._insertIntoKvsQuery = this._db.prepare(statements.insertIntoKvs); + this._delQuery = this._db.prepare(statements.del); } - async beginTransaction() { - await this._db.exec("BEGIN TRANSACTION"); + static initialize(db: SqliteDatabase) { + db.prepare(statements.createTable).run(); } - async commitTransaction() { - await this._db.exec("COMMIT TRANSACTION"); + beginTransaction() { + this._beginTxnQuery.run(); } - async rollbackTransaction() { - await this._db.exec("ROLLBACK TRANSACTION"); + commitTransaction() { + this._commitTxnQuery.run(); } - async get(key: string): Promise { - const row = await this._db.get<{ v: string }>( - ` - SELECT v - FROM kvs - WHERE k = ? AND to_block IS NULL - `, - [key], - ); + rollbackTransaction() { + this._rollbackTxnQuery.run(); + } + + get(key: string): T { + const row = this._getQuery.get(key); return row ? deserialize(row.v) : undefined; } - async put(key: string, value: T) { - await this._db.run( - ` - UPDATE kvs - SET to_block = ? - WHERE k = ? AND to_block IS NULL - `, - [Number(this._endCursor.orderKey), key], - ); + put(key: string, value: T) { + this._updateToBlockQuery.run(Number(this._endCursor.orderKey), key); - await this._db.run( - ` - INSERT INTO kvs (from_block, to_block, k, v) - VALUES (?, NULL, ?, ?) - `, - [ - Number(this._endCursor.orderKey), - key, - serialize(value as Record), - ], + this._insertIntoKvsQuery.run( + Number(this._endCursor.orderKey), + key, + serialize(value as Record), ); } - async del(key: string) { - await this._db.run( - ` - UPDATE kvs - SET to_block = ? - WHERE k = ? AND to_block IS NULL - `, - [Number(this._endCursor.orderKey), key], - ); + del(key: string) { + this._delQuery.run(Number(this._endCursor.orderKey), key); } } + +const statements = { + beginTxn: "BEGIN TRANSACTION", + commitTxn: "COMMIT TRANSACTION", + rollbackTxn: "ROLLBACK TRANSACTION", + createTable: ` + CREATE TABLE IF NOT EXISTS kvs ( + from_block INTEGER NOT NULL, + to_block INTEGER, + k TEXT NOT NULL, + v BLOB NOT NULL, + PRIMARY KEY (from_block, k) + );`, + get: ` + SELECT v + FROM kvs + WHERE k = ? AND to_block IS NULL`, + updateToBlock: ` + UPDATE kvs + SET to_block = ? + WHERE k = ? AND to_block IS NULL`, + insertIntoKvs: ` + INSERT INTO kvs (from_block, to_block, k, v) + VALUES (?, NULL, ?, ?)`, + del: ` + UPDATE kvs + SET to_block = ? + WHERE k = ? AND to_block IS NULL`, +}; diff --git a/packages/indexer/src/plugins/persistence.test.ts b/packages/indexer/src/plugins/persistence.test.ts index 5af2dfd..533915f 100644 --- a/packages/indexer/src/plugins/persistence.test.ts +++ b/packages/indexer/src/plugins/persistence.test.ts @@ -1,32 +1,30 @@ -import fs from "node:fs/promises"; import type { Cursor } from "@apibara/protocol"; import { type MockBlock, MockClient, type MockFilter, } from "@apibara/protocol/testing"; +import Database from "better-sqlite3"; import { klona } from "klona/full"; -import { open } from "sqlite"; -import sqlite3 from "sqlite3"; -import { afterEach, describe, expect, it } from "vitest"; +import { describe, expect, it } from "vitest"; import { run } from "../indexer"; import { generateMockMessages } from "../testing"; import { type MockRet, getMockIndexer } from "../testing/indexer"; import { SqlitePersistence, sqlitePersistence } from "./persistence"; describe("Persistence", () => { - const initDB = async () => { - const db = await open({ driver: sqlite3.Database, filename: ":memory:" }); - await SqlitePersistence.initialize(db); + const initDB = () => { + const db = new Database(":memory:"); + SqlitePersistence.initialize(db); return db; }; - it("should handle storing and updating a cursor & filter", async () => { - const db = await initDB(); + it("should handle storing and updating a cursor & filter", () => { + const db = initDB(); const store = new SqlitePersistence(db); // Assert there's no data - let latest = await store.get(); + let latest = store.get(); expect(latest.cursor).toBeUndefined(); expect(latest.filter).toBeUndefined(); @@ -38,10 +36,10 @@ describe("Persistence", () => { const filter: MockFilter = { filter: "X", }; - await store.put({ cursor, filter }); + store.put({ cursor, filter }); // Check that value was stored - latest = await store.get(); + latest = store.get(); expect(latest.cursor).toEqual({ orderKey: 5_000_000n, @@ -60,10 +58,10 @@ describe("Persistence", () => { filter: "Y", }; - await store.put({ cursor: updatedCursor, filter: updatedFilter }); + store.put({ cursor: updatedCursor, filter: updatedFilter }); // Check that value was updated - latest = await store.get(); + latest = store.get(); expect(latest.cursor).toEqual({ orderKey: 5_000_010n, @@ -73,15 +71,15 @@ describe("Persistence", () => { filter: "Y", }); - await db.close(); + db.close(); }); - it("should handle storing and deleting a cursor & filter", async () => { - const db = await initDB(); + it("should handle storing and deleting a cursor & filter", () => { + const db = initDB(); const store = new SqlitePersistence(db); // Assert there's no data - let latest = await store.get(); + let latest = store.get(); expect(latest.cursor).toBeUndefined(); expect(latest.filter).toBeUndefined(); @@ -92,10 +90,10 @@ describe("Persistence", () => { const filter: MockFilter = { filter: "X", }; - await store.put({ cursor, filter }); + store.put({ cursor, filter }); // Check that value was stored - latest = await store.get(); + latest = store.get(); expect(latest.cursor).toEqual({ orderKey: 5_000_000n, uniqueKey: null, @@ -105,14 +103,14 @@ describe("Persistence", () => { }); // Delete value - await store.del(); + store.del(); // Check there's no data - latest = await store.get(); + latest = store.get(); expect(latest.cursor).toBeUndefined(); expect(latest.filter).toBeUndefined(); - await db.close(); + db.close(); }); it("should work with indexer and store cursor of last message", async () => { @@ -120,9 +118,10 @@ describe("Persistence", () => { return messages; }); + const db = new Database(":memory:"); + const persistence = sqlitePersistence({ - driver: sqlite3.Database, - filename: "file:memdb1?mode=memory&cache=shared", + database: db, }); // create mock indexer with persistence plugin @@ -130,15 +129,9 @@ describe("Persistence", () => { await run(client, indexer); - // open same db again to check last cursor - const db = await open({ - driver: sqlite3.Database, - filename: "file:memdb1?mode=memory&cache=shared", - }); - const store = new SqlitePersistence(db); - const latest = await store.get(); + const latest = store.get(); expect(latest.cursor).toMatchInlineSnapshot(` { @@ -146,13 +139,8 @@ describe("Persistence", () => { "uniqueKey": null, } `); - }); - // Cleanup - afterEach(async () => { - try { - await fs.unlink("file:memdb1?mode=memory&cache=shared"); - } catch {} + db.close(); }); }); diff --git a/packages/indexer/src/plugins/persistence.ts b/packages/indexer/src/plugins/persistence.ts index 9f3c292..93f0295 100644 --- a/packages/indexer/src/plugins/persistence.ts +++ b/packages/indexer/src/plugins/persistence.ts @@ -1,25 +1,22 @@ import type { Cursor } from "@apibara/protocol"; -import { type Database, type ISqlite, open } from "sqlite"; +import type { Database as SqliteDatabase, Statement } from "better-sqlite3"; import { deserialize, serialize } from "../vcr"; import { defineIndexerPlugin } from "./config"; -type SqliteArgs = ISqlite.Config; - -export function sqlitePersistence(args: SqliteArgs) { +export function sqlitePersistence({ + database, +}: { database: SqliteDatabase }) { return defineIndexerPlugin((indexer) => { - let db: Database; let store: SqlitePersistence; - indexer.hooks.hook("run:before", async () => { - db = await open(args); - - await SqlitePersistence.initialize(db); + indexer.hooks.hook("run:before", () => { + SqlitePersistence.initialize(database); - store = new SqlitePersistence(db); + store = new SqlitePersistence(database); }); - indexer.hooks.hook("connect:before", async ({ request }) => { - const { cursor, filter } = await store.get(); + indexer.hooks.hook("connect:before", ({ request }) => { + const { cursor, filter } = store.get(); if (cursor) { request.startingCursor = cursor; @@ -30,157 +27,167 @@ export function sqlitePersistence(args: SqliteArgs) { } }); - indexer.hooks.hook("sink:flush", async ({ endCursor }) => { + indexer.hooks.hook("sink:flush", ({ endCursor }) => { if (endCursor) { - await store.put({ cursor: endCursor }); + store.put({ cursor: endCursor }); } }); - indexer.hooks.hook("connect:factory", async ({ request, endCursor }) => { + indexer.hooks.hook("connect:factory", ({ request, endCursor }) => { if (request.filter[1]) { - await store.put({ cursor: endCursor, filter: request.filter[1] }); + store.put({ cursor: endCursor, filter: request.filter[1] }); } }); }); } export class SqlitePersistence { - constructor(private _db: Database) {} - - static async initialize(db: Database) { - await db.exec(` - CREATE TABLE IF NOT EXISTS checkpoints ( - id TEXT NOT NULL PRIMARY KEY, - order_key INTEGER NOT NULL, - unique_key TEXT - ); - - CREATE TABLE IF NOT EXISTS filters ( - id TEXT NOT NULL, - filter BLOB NOT NULL, - from_block INTEGER NOT NULL, - to_block INTEGER, - PRIMARY KEY (id, from_block) - ); - `); + /** Sqlite Queries Prepare Statements */ + private _getCheckpointQuery: Statement; + private _putCheckpointQuery: Statement< + [string, number, `0x${string}` | undefined] + >; + private _delCheckpointQuery: Statement; + private _getFilterQuery: Statement; + private _updateFilterToBlockQuery: Statement<[number, string]>; + private _insertFilterQuery: Statement<[string, string, number]>; + private _delFilterQuery: Statement; + + constructor(private _db: SqliteDatabase) { + this._getCheckpointQuery = this._db.prepare(statements.getCheckpoint); + this._putCheckpointQuery = this._db.prepare(statements.putCheckpoint); + this._delCheckpointQuery = this._db.prepare(statements.delCheckpoint); + this._getFilterQuery = this._db.prepare(statements.getFilter); + this._updateFilterToBlockQuery = this._db.prepare( + statements.updateFilterToBlock, + ); + this._insertFilterQuery = this._db.prepare(statements.insertFilter); + this._delFilterQuery = this._db.prepare(statements.delFilter); + } + + static initialize(db: SqliteDatabase) { + db.prepare(statements.createCheckpointsTable).run(); + db.prepare(statements.createFiltersTable).run(); } - public async get(): Promise<{ cursor?: Cursor; filter?: TFilter }> { - const cursor = await this._getCheckpoint(); - const filter = await this._getFilter(); + public get(): { cursor?: Cursor; filter?: TFilter } { + const cursor = this._getCheckpoint(); + const filter = this._getFilter(); return { cursor, filter }; } - public async put({ cursor, filter }: { cursor?: Cursor; filter?: TFilter }) { + public put({ cursor, filter }: { cursor?: Cursor; filter?: TFilter }) { if (cursor) { - await this._putCheckpoint(cursor); + this._putCheckpoint(cursor); if (filter) { - await this._putFilter(filter, cursor); + this._putFilter(filter, cursor); } } } - public async del() { - await this._delCheckpoint(); - await this._delFilter(); + public del() { + this._delCheckpoint(); + this._delFilter(); } // --- CHECKPOINTS TABLE METHODS --- - private async _getCheckpoint(): Promise { - const row = await this._db.get( - ` - SELECT * - FROM checkpoints - WHERE id = ? - `, - ["default"], - ); + private _getCheckpoint(): Cursor | undefined { + const row = this._getCheckpointQuery.get("default"); if (!row) return undefined; return { orderKey: BigInt(row.order_key), uniqueKey: row.unique_key }; } - private async _putCheckpoint(cursor: Cursor) { - await this._db.run( - ` - INSERT INTO checkpoints (id, order_key, unique_key) - VALUES (?, ?, ?) - ON CONFLICT(id) DO UPDATE SET - order_key = excluded.order_key, - unique_key = excluded.unique_key - `, - ["default", Number(cursor.orderKey), cursor.uniqueKey], + private _putCheckpoint(cursor: Cursor) { + this._putCheckpointQuery.run( + "default", + Number(cursor.orderKey), + cursor.uniqueKey, ); } - private async _delCheckpoint() { - await this._db.run( - ` - DELETE FROM checkpoints - WHERE id = ? - `, - ["default"], - ); + private _delCheckpoint() { + this._delCheckpointQuery.run("default"); } // --- FILTERS TABLE METHODS --- - private async _getFilter(): Promise { - const row = await this._db.get( - ` - SELECT * - FROM filters - WHERE id = ? AND to_block IS NULL - `, - ["default"], - ); + private _getFilter(): TFilter | undefined { + const row = this._getFilterQuery.get("default"); if (!row) return undefined; return deserialize(row.filter) as TFilter; } - private async _putFilter(filter: TFilter, endCursor: Cursor) { - await this._db.run( - ` - UPDATE filters - SET to_block = ? - WHERE id = ? AND to_block IS NULL - `, - [Number(endCursor.orderKey), "default"], - ); - - await this._db.run( - ` - INSERT INTO filters (id, filter, from_block) - VALUES (?, ?, ?) - ON CONFLICT(id, from_block) DO UPDATE SET - filter = excluded.filter, - from_block = excluded.from_block - `, - [ - "default", - serialize(filter as Record), - Number(endCursor.orderKey), - ], + private _putFilter(filter: TFilter, endCursor: Cursor) { + this._updateFilterToBlockQuery.run(Number(endCursor.orderKey), "default"); + this._insertFilterQuery.run( + "default", + serialize(filter as Record), + Number(endCursor.orderKey), ); } - private async _delFilter() { - await this._db.run( - ` - DELETE FROM filters - WHERE id = ? - `, - ["default"], - ); + private _delFilter() { + this._delFilterQuery.run("default"); } } +const statements = { + beginTxn: "BEGIN TRANSACTION", + commitTxn: "COMMIT TRANSACTION", + rollbackTxn: "ROLLBACK TRANSACTION", + createCheckpointsTable: ` + CREATE TABLE IF NOT EXISTS checkpoints ( + id TEXT NOT NULL PRIMARY KEY, + order_key INTEGER NOT NULL, + unique_key TEXT + );`, + createFiltersTable: ` + CREATE TABLE IF NOT EXISTS filters ( + id TEXT NOT NULL, + filter BLOB NOT NULL, + from_block INTEGER NOT NULL, + to_block INTEGER, + PRIMARY KEY (id, from_block) + );`, + getCheckpoint: ` + SELECT * + FROM checkpoints + WHERE id = ?`, + putCheckpoint: ` + INSERT INTO checkpoints (id, order_key, unique_key) + VALUES (?, ?, ?) + ON CONFLICT(id) DO UPDATE SET + order_key = excluded.order_key, + unique_key = excluded.unique_key`, + delCheckpoint: ` + DELETE FROM checkpoints + WHERE id = ?`, + getFilter: ` + SELECT * + FROM filters + WHERE id = ? AND to_block IS NULL`, + updateFilterToBlock: ` + UPDATE filters + SET to_block = ? + WHERE id = ? AND to_block IS NULL`, + insertFilter: ` + INSERT INTO filters (id, filter, from_block) + VALUES (?, ?, ?) + ON CONFLICT(id, from_block) DO UPDATE SET + filter = excluded.filter, + from_block = excluded.from_block`, + delFilter: ` + DELETE FROM filters + WHERE id = ?`, +}; + export type CheckpointRow = { id: string; order_key: number; diff --git a/packages/indexer/src/sinks/csv.test.ts b/packages/indexer/src/sinks/csv.test.ts new file mode 100644 index 0000000..3080f67 --- /dev/null +++ b/packages/indexer/src/sinks/csv.test.ts @@ -0,0 +1,53 @@ +import fs from "node:fs/promises"; +import { + type MockBlock, + MockClient, + type MockFilter, +} from "@apibara/protocol/testing"; +import { afterEach, beforeEach, describe, expect, it } from "vitest"; +import { run } from "../indexer"; +import {} from "../plugins/persistence"; +import { generateMockMessages } from "../testing"; +import { type MockRet, getMockIndexer } from "../testing/indexer"; +import { csv } from "./csv"; + +describe("Run Test", () => { + async function cleanup() { + try { + await fs.unlink("test.csv"); + } catch {} + } + + beforeEach(async () => { + await cleanup(); + }); + + afterEach(async () => { + await cleanup(); + }); + + it("should store in csv file via csv sink", async () => { + const client = new MockClient((request, options) => { + return generateMockMessages(); + }); + + const sink = csv({ filepath: "test.csv" }); + await run(client, getMockIndexer(), sink); + + const csvData = await fs.readFile("test.csv", "utf-8"); + + expect(csvData).toMatchInlineSnapshot(` + "5000000,5000000 + 5000001,5000001 + 5000002,5000002 + 5000003,5000003 + 5000004,5000004 + 5000005,5000005 + 5000006,5000006 + 5000007,5000007 + 5000008,5000008 + 5000009,5000009 + " + `); + }); +}); diff --git a/packages/indexer/src/sinks/csv.ts b/packages/indexer/src/sinks/csv.ts index 25aca49..4e2fa5e 100644 --- a/packages/indexer/src/sinks/csv.ts +++ b/packages/indexer/src/sinks/csv.ts @@ -85,11 +85,13 @@ export class CsvSink< } } -export const csv = (args: CsvArgs & CsvSinkOptions) => { +export const csv = >( + args: CsvArgs & CsvSinkOptions, +) => { const { csvOptions, filepath, ...sinkOptions } = args; const stringifier = stringify({ ...csvOptions }); const writeStream = fs.createWriteStream(filepath, { flags: "a" }); stringifier.pipe(writeStream); - return new CsvSink(stringifier, sinkOptions); + return new CsvSink(stringifier, sinkOptions); }; diff --git a/packages/indexer/src/sinks/sqlite.test.ts b/packages/indexer/src/sinks/sqlite.test.ts new file mode 100644 index 0000000..03d1c50 --- /dev/null +++ b/packages/indexer/src/sinks/sqlite.test.ts @@ -0,0 +1,87 @@ +import { + type MockBlock, + MockClient, + type MockFilter, +} from "@apibara/protocol/testing"; +import Database from "better-sqlite3"; +import { describe, expect, it } from "vitest"; +import { run } from "../indexer"; +import {} from "../plugins/persistence"; +import { generateMockMessages } from "../testing"; +import { type MockRet, getMockIndexer } from "../testing/indexer"; +import { sqlite } from "./sqlite"; + +describe("Run Test", () => { + it("should store in sqlite db via sqlitesink", async () => { + const client = new MockClient((request, options) => { + return generateMockMessages(); + }); + + const db = new Database(":memory:"); + + db.prepare("DROP TABLE IF EXISTS test;").run(); + + db.prepare( + ` + CREATE TABLE IF NOT EXISTS test ( + data BLOB, + _cursor BIGINT + );`, + ).run(); + + const sink = sqlite({ + database: db, + tableName: "test", + }); + await run(client, getMockIndexer(), sink); + + const sinkData = db.prepare("SELECT * FROM test").all(); + + expect(sinkData).toMatchInlineSnapshot(` + [ + { + "_cursor": 5000000, + "data": "5000000", + }, + { + "_cursor": 5000001, + "data": "5000001", + }, + { + "_cursor": 5000002, + "data": "5000002", + }, + { + "_cursor": 5000003, + "data": "5000003", + }, + { + "_cursor": 5000004, + "data": "5000004", + }, + { + "_cursor": 5000005, + "data": "5000005", + }, + { + "_cursor": 5000006, + "data": "5000006", + }, + { + "_cursor": 5000007, + "data": "5000007", + }, + { + "_cursor": 5000008, + "data": "5000008", + }, + { + "_cursor": 5000009, + "data": "5000009", + }, + ] + `); + + db.close(); + }); +}); diff --git a/packages/indexer/src/sinks/sqlite.ts b/packages/indexer/src/sinks/sqlite.ts index 94869b0..ac69a8b 100644 --- a/packages/indexer/src/sinks/sqlite.ts +++ b/packages/indexer/src/sinks/sqlite.ts @@ -1,10 +1,12 @@ import type { Cursor } from "@apibara/protocol"; -import { type Database, type ISqlite, open } from "sqlite"; +import type { Database as SqliteDatabase } from "better-sqlite3"; import { Sink, type SinkWriteArgs } from "../sink"; -export type SqliteArgs = ISqlite.Config; - export type SqliteSinkOptions = { + /** + * Database instance of better-sqlite3 + */ + database: SqliteDatabase; /** * The name of the table where data will be inserted. */ @@ -25,13 +27,14 @@ export type SqliteSinkOptions = { export class SqliteSink< TData extends Record, > extends Sink { - private _config: SqliteSinkOptions; - private _db: Database; + private _config: Omit; + private _db: SqliteDatabase; - constructor(db: Database, config: SqliteSinkOptions) { + constructor(options: SqliteSinkOptions) { super(); + const { database, ...config } = options; this._config = config; - this._db = db; + this._db = database; } async write({ data, endCursor, finality }: SinkWriteArgs) { @@ -62,7 +65,7 @@ export class SqliteSink< // Prepare and execute the SQL statement const values = data.flatMap((row) => columns.map((col) => row[col])); - await this._db.run(statement, values); + this._db.prepare(statement).run(values); } private processCursorColumn(data: TData[], endCursor?: Cursor): TData[] { @@ -101,8 +104,8 @@ export class SqliteSink< } } -export const sqlite = async (args: SqliteArgs & SqliteSinkOptions) => { - const { filename, mode, driver, ...sinkOptions } = args; - const db = await open({ filename, mode, driver }); - return new SqliteSink(db, sinkOptions); +export const sqlite = >( + args: SqliteSinkOptions, +) => { + return new SqliteSink(args); }; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9a49853..fab0c6d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -106,6 +106,9 @@ importers: '@opentelemetry/semantic-conventions': specifier: ^1.25.0 version: 1.25.0 + better-sqlite3: + specifier: ^11.1.2 + version: 11.1.2 citty: specifier: ^0.1.6 version: 0.1.6 @@ -115,13 +118,13 @@ importers: csv-stringify: specifier: ^6.5.0 version: 6.5.0 - sqlite: - specifier: ^5.1.1 - version: 5.1.1 viem: specifier: ^2.12.4 version: 2.13.8(typescript@5.4.5) devDependencies: + '@types/better-sqlite3': + specifier: ^7.6.11 + version: 7.6.11 '@types/node': specifier: ^20.12.12 version: 20.14.0 @@ -261,18 +264,18 @@ importers: specifier: ^2.3.1 version: 2.3.1 devDependencies: + '@types/better-sqlite3': + specifier: ^7.6.11 + version: 7.6.11 '@types/node': specifier: ^20.14.0 version: 20.14.0 + better-sqlite3: + specifier: ^11.1.2 + version: 11.1.2 csv-stringify: specifier: ^6.5.0 version: 6.5.0 - sqlite: - specifier: ^5.1.1 - version: 5.1.1 - sqlite3: - specifier: ^5.1.7 - version: 5.1.7 unbuild: specifier: ^2.0.0 version: 2.0.0(typescript@5.4.5) @@ -1451,12 +1454,6 @@ packages: dev: true optional: true - /@gar/promisify@1.1.3: - resolution: {integrity: sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==} - requiresBuild: true - dev: true - optional: true - /@grpc/grpc-js@1.9.14: resolution: {integrity: sha512-nOpuzZ2G3IuMFN+UPPpKrC6NsLmWsTqSsm66IRfnBt1D4pwTqE27lmbpcPM+l2Ua4gE7PfjRHI6uedAy7hoXUw==} engines: {node: ^8.13.0 || >=10.10.0} @@ -1566,26 +1563,6 @@ packages: fastq: 1.17.1 dev: true - /@npmcli/fs@1.1.1: - resolution: {integrity: sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==} - requiresBuild: true - dependencies: - '@gar/promisify': 1.1.3 - semver: 7.6.0 - dev: true - optional: true - - /@npmcli/move-file@1.1.2: - resolution: {integrity: sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==} - engines: {node: '>=10'} - deprecated: This functionality has been moved to @npmcli/fs - requiresBuild: true - dependencies: - mkdirp: 1.0.4 - rimraf: 3.0.2 - dev: true - optional: true - /@opentelemetry/api-logs@0.52.0: resolution: {integrity: sha512-HxjD7xH9iAE4OyhNaaSec65i1H6QZYBWSwWkowFfsc5YAcDvJG30/J1sRKXEQqdmUcKTXEAnA66UciqZha/4+Q==} engines: {node: '>=14'} @@ -2128,18 +2105,17 @@ packages: engines: {node: '>=18'} dev: true - /@tootallnate/once@1.1.2: - resolution: {integrity: sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==} - engines: {node: '>= 6'} - requiresBuild: true - dev: true - optional: true - /@trysound/sax@0.2.0: resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} engines: {node: '>=10.13.0'} dev: true + /@types/better-sqlite3@7.6.11: + resolution: {integrity: sha512-i8KcD3PgGtGBLl3+mMYA8PdKkButvPyARxA7IQAd6qeslht13qxb1zzO8dRCtE7U3IoJS782zDBAeoKiM695kg==} + dependencies: + '@types/node': 20.14.0 + dev: true + /@types/estree@1.0.5: resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} @@ -2230,12 +2206,6 @@ packages: pretty-format: 29.7.0 dev: true - /abbrev@1.1.1: - resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} - requiresBuild: true - dev: true - optional: true - /abitype@1.0.0(typescript@5.4.5): resolution: {integrity: sha512-NMeMah//6bJ56H5XRj8QCV4AwuW6hB6zqz2LnhhLdcWVQOsXki6/Pn3APeqxCma62nXIcmZWdu1DlHWS74umVQ==} peerDependencies: @@ -2271,36 +2241,6 @@ packages: engines: {node: '>=0.4.0'} hasBin: true - /agent-base@6.0.2: - resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} - engines: {node: '>= 6.0.0'} - requiresBuild: true - dependencies: - debug: 4.3.4 - transitivePeerDependencies: - - supports-color - dev: true - optional: true - - /agentkeepalive@4.5.0: - resolution: {integrity: sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==} - engines: {node: '>= 8.0.0'} - requiresBuild: true - dependencies: - humanize-ms: 1.2.1 - dev: true - optional: true - - /aggregate-error@3.1.0: - resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} - engines: {node: '>=8'} - requiresBuild: true - dependencies: - clean-stack: 2.2.0 - indent-string: 4.0.0 - dev: true - optional: true - /ansi-colors@4.1.3: resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} engines: {node: '>=6'} @@ -2337,23 +2277,6 @@ packages: picomatch: 2.3.1 dev: false - /aproba@2.0.0: - resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==} - requiresBuild: true - dev: true - optional: true - - /are-we-there-yet@3.0.1: - resolution: {integrity: sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} - deprecated: This package is no longer supported. - requiresBuild: true - dependencies: - delegates: 1.0.0 - readable-stream: 3.6.2 - dev: true - optional: true - /argparse@1.0.10: resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} dependencies: @@ -2435,7 +2358,6 @@ packages: /base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - dev: true /better-path-resolve@1.0.0: resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} @@ -2444,6 +2366,13 @@ packages: is-windows: 1.0.2 dev: true + /better-sqlite3@11.1.2: + resolution: {integrity: sha512-gujtFwavWU4MSPT+h9B+4pkvZdyOUkH54zgLdIrMmmmd4ZqiBIrRNBzNzYVFO417xo882uP5HBu4GjOfaSrIQw==} + requiresBuild: true + dependencies: + bindings: 1.5.0 + prebuild-install: 7.1.2 + /binary-extensions@2.3.0: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} @@ -2453,7 +2382,6 @@ packages: resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} dependencies: file-uri-to-path: 1.0.0 - dev: true /bl@4.1.0: resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} @@ -2461,21 +2389,11 @@ packages: buffer: 5.7.1 inherits: 2.0.4 readable-stream: 3.6.2 - dev: true /boolbase@1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} dev: true - /brace-expansion@1.1.11: - resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} - requiresBuild: true - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - dev: true - optional: true - /brace-expansion@2.0.1: resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} dependencies: @@ -2510,7 +2428,6 @@ packages: dependencies: base64-js: 1.5.1 ieee754: 1.2.1 - dev: true /builtin-modules@3.3.0: resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} @@ -2522,34 +2439,6 @@ packages: engines: {node: '>=8'} dev: true - /cacache@15.3.0: - resolution: {integrity: sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==} - engines: {node: '>= 10'} - requiresBuild: true - dependencies: - '@npmcli/fs': 1.1.1 - '@npmcli/move-file': 1.1.2 - chownr: 2.0.0 - fs-minipass: 2.1.0 - glob: 7.2.3 - infer-owner: 1.0.4 - lru-cache: 6.0.0 - minipass: 3.3.6 - minipass-collect: 1.0.2 - minipass-flush: 1.0.5 - minipass-pipeline: 1.2.4 - mkdirp: 1.0.4 - p-map: 4.0.0 - promise-inflight: 1.0.1 - rimraf: 3.0.2 - ssri: 8.0.1 - tar: 6.2.1 - unique-filename: 1.1.1 - transitivePeerDependencies: - - bluebird - dev: true - optional: true - /call-bind@1.0.7: resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} engines: {node: '>= 0.4'} @@ -2651,12 +2540,6 @@ packages: /chownr@1.1.4: resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} - dev: true - - /chownr@2.0.0: - resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} - engines: {node: '>=10'} - dev: true /ci-info@3.9.0: resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} @@ -2672,13 +2555,6 @@ packages: resolution: {integrity: sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==} dev: false - /clean-stack@2.2.0: - resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} - engines: {node: '>=6'} - requiresBuild: true - dev: true - optional: true - /cliui@6.0.0: resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} dependencies: @@ -2721,13 +2597,6 @@ packages: /color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - /color-support@1.1.3: - resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} - hasBin: true - requiresBuild: true - dev: true - optional: true - /colord@2.9.3: resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==} dev: true @@ -2741,12 +2610,6 @@ packages: resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} dev: true - /concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - requiresBuild: true - dev: true - optional: true - /confbox@0.1.7: resolution: {integrity: sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==} dev: true @@ -2755,12 +2618,6 @@ packages: resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==} engines: {node: ^14.18.0 || >=16.10.0} - /console-control-strings@1.1.0: - resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==} - requiresBuild: true - dev: true - optional: true - /convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} dev: true @@ -2979,7 +2836,6 @@ packages: engines: {node: '>=10'} dependencies: mimic-response: 3.1.0 - dev: true /deep-eql@4.1.3: resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==} @@ -2991,7 +2847,6 @@ packages: /deep-extend@0.6.0: resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} engines: {node: '>=4.0.0'} - dev: true /deepmerge@4.3.1: resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} @@ -3026,12 +2881,6 @@ packages: resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} dev: true - /delegates@1.0.0: - resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} - requiresBuild: true - dev: true - optional: true - /detect-indent@6.1.0: resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} engines: {node: '>=8'} @@ -3040,7 +2889,6 @@ packages: /detect-libc@2.0.3: resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==} engines: {node: '>=8'} - dev: true /diff-sequences@29.6.3: resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} @@ -3097,19 +2945,10 @@ packages: /emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - /encoding@0.1.13: - resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==} - requiresBuild: true - dependencies: - iconv-lite: 0.6.3 - dev: true - optional: true - /end-of-stream@1.4.4: resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} dependencies: once: 1.4.0 - dev: true /enquirer@2.4.1: resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} @@ -3124,19 +2963,6 @@ packages: engines: {node: '>=0.12'} dev: true - /env-paths@2.2.1: - resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} - engines: {node: '>=6'} - requiresBuild: true - dev: true - optional: true - - /err-code@2.0.3: - resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==} - requiresBuild: true - dev: true - optional: true - /error-ex@1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} dependencies: @@ -3348,7 +3174,6 @@ packages: /expand-template@2.0.3: resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} engines: {node: '>=6'} - dev: true /extendable-error@0.1.7: resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} @@ -3389,7 +3214,6 @@ packages: /file-uri-to-path@1.0.0: resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} - dev: true /fill-range@7.0.1: resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} @@ -3432,7 +3256,6 @@ packages: /fs-constants@1.0.0: resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} - dev: true /fs-extra@11.2.0: resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} @@ -3461,13 +3284,6 @@ packages: universalify: 0.1.2 dev: true - /fs-minipass@2.1.0: - resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} - engines: {node: '>= 8'} - dependencies: - minipass: 3.3.6 - dev: true - /fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} dev: true @@ -3496,23 +3312,6 @@ packages: resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} dev: true - /gauge@4.0.4: - resolution: {integrity: sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} - deprecated: This package is no longer supported. - requiresBuild: true - dependencies: - aproba: 2.0.0 - color-support: 1.1.3 - console-control-strings: 1.1.0 - has-unicode: 2.0.1 - signal-exit: 3.0.7 - string-width: 4.2.3 - strip-ansi: 6.0.1 - wide-align: 1.1.5 - dev: true - optional: true - /gensync@1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} @@ -3553,7 +3352,6 @@ packages: /github-from-package@0.0.0: resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} - dev: true /glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} @@ -3561,20 +3359,6 @@ packages: dependencies: is-glob: 4.0.3 - /glob@7.2.3: - resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - deprecated: Glob versions prior to v9 are no longer supported - requiresBuild: true - dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 3.1.2 - once: 1.4.0 - path-is-absolute: 1.0.1 - dev: true - optional: true - /glob@8.1.0: resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} engines: {node: '>=12'} @@ -3691,12 +3475,6 @@ packages: has-symbols: 1.0.3 dev: true - /has-unicode@2.0.1: - resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==} - requiresBuild: true - dev: true - optional: true - /hasown@2.0.2: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} @@ -3710,37 +3488,6 @@ packages: resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} dev: true - /http-cache-semantics@4.1.1: - resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==} - requiresBuild: true - dev: true - optional: true - - /http-proxy-agent@4.0.1: - resolution: {integrity: sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==} - engines: {node: '>= 6'} - requiresBuild: true - dependencies: - '@tootallnate/once': 1.1.2 - agent-base: 6.0.2 - debug: 4.3.4 - transitivePeerDependencies: - - supports-color - dev: true - optional: true - - /https-proxy-agent@5.0.1: - resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} - engines: {node: '>= 6'} - requiresBuild: true - dependencies: - agent-base: 6.0.2 - debug: 4.3.4 - transitivePeerDependencies: - - supports-color - dev: true - optional: true - /human-id@1.0.2: resolution: {integrity: sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==} dev: true @@ -3750,14 +3497,6 @@ packages: engines: {node: '>=16.17.0'} dev: true - /humanize-ms@1.2.1: - resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} - requiresBuild: true - dependencies: - ms: 2.1.2 - dev: true - optional: true - /iconv-lite@0.4.24: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} @@ -3765,18 +3504,8 @@ packages: safer-buffer: 2.1.2 dev: true - /iconv-lite@0.6.3: - resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} - engines: {node: '>=0.10.0'} - requiresBuild: true - dependencies: - safer-buffer: 2.1.2 - dev: true - optional: true - /ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - dev: true /ignore@5.3.1: resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} @@ -3792,24 +3521,11 @@ packages: module-details-from-path: 1.0.3 dev: false - /imurmurhash@0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} - requiresBuild: true - dev: true - optional: true - /indent-string@4.0.0: resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} engines: {node: '>=8'} dev: true - /infer-owner@1.0.4: - resolution: {integrity: sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==} - requiresBuild: true - dev: true - optional: true - /inflight@1.0.6: resolution: {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. @@ -3820,11 +3536,9 @@ packages: /inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - dev: true /ini@1.3.8: resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} - dev: true /internal-slot@1.0.7: resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} @@ -3835,16 +3549,6 @@ packages: side-channel: 1.0.6 dev: true - /ip-address@9.0.5: - resolution: {integrity: sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==} - engines: {node: '>= 12'} - requiresBuild: true - dependencies: - jsbn: 1.1.0 - sprintf-js: 1.1.3 - dev: true - optional: true - /is-array-buffer@3.0.4: resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} engines: {node: '>= 0.4'} @@ -3923,12 +3627,6 @@ packages: dependencies: is-extglob: 2.1.1 - /is-lambda@1.0.1: - resolution: {integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==} - requiresBuild: true - dev: true - optional: true - /is-module@1.0.0: resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} dev: true @@ -4056,12 +3754,6 @@ packages: esprima: 4.0.1 dev: true - /jsbn@1.1.0: - resolution: {integrity: sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==} - requiresBuild: true - dev: true - optional: true - /jsesc@2.5.2: resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} engines: {node: '>=4'} @@ -4201,33 +3893,6 @@ packages: dependencies: '@jridgewell/sourcemap-codec': 1.4.15 - /make-fetch-happen@9.1.0: - resolution: {integrity: sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==} - engines: {node: '>= 10'} - requiresBuild: true - dependencies: - agentkeepalive: 4.5.0 - cacache: 15.3.0 - http-cache-semantics: 4.1.1 - http-proxy-agent: 4.0.1 - https-proxy-agent: 5.0.1 - is-lambda: 1.0.1 - lru-cache: 6.0.0 - minipass: 3.3.6 - minipass-collect: 1.0.2 - minipass-fetch: 1.4.1 - minipass-flush: 1.0.5 - minipass-pipeline: 1.2.4 - negotiator: 0.6.3 - promise-retry: 2.0.1 - socks-proxy-agent: 6.2.1 - ssri: 8.0.1 - transitivePeerDependencies: - - bluebird - - supports-color - dev: true - optional: true - /map-obj@1.0.1: resolution: {integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==} engines: {node: '>=0.10.0'} @@ -4288,21 +3953,12 @@ packages: /mimic-response@3.1.0: resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} engines: {node: '>=10'} - dev: true /min-indent@1.0.1: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} engines: {node: '>=4'} dev: true - /minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - requiresBuild: true - dependencies: - brace-expansion: 1.1.11 - dev: true - optional: true - /minimatch@5.1.6: resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} engines: {node: '>=10'} @@ -4321,76 +3977,6 @@ packages: /minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - dev: true - - /minipass-collect@1.0.2: - resolution: {integrity: sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==} - engines: {node: '>= 8'} - requiresBuild: true - dependencies: - minipass: 3.3.6 - dev: true - optional: true - - /minipass-fetch@1.4.1: - resolution: {integrity: sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==} - engines: {node: '>=8'} - requiresBuild: true - dependencies: - minipass: 3.3.6 - minipass-sized: 1.0.3 - minizlib: 2.1.2 - optionalDependencies: - encoding: 0.1.13 - dev: true - optional: true - - /minipass-flush@1.0.5: - resolution: {integrity: sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==} - engines: {node: '>= 8'} - requiresBuild: true - dependencies: - minipass: 3.3.6 - dev: true - optional: true - - /minipass-pipeline@1.2.4: - resolution: {integrity: sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==} - engines: {node: '>=8'} - requiresBuild: true - dependencies: - minipass: 3.3.6 - dev: true - optional: true - - /minipass-sized@1.0.3: - resolution: {integrity: sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==} - engines: {node: '>=8'} - requiresBuild: true - dependencies: - minipass: 3.3.6 - dev: true - optional: true - - /minipass@3.3.6: - resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} - engines: {node: '>=8'} - dependencies: - yallist: 4.0.0 - dev: true - - /minipass@5.0.0: - resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} - engines: {node: '>=8'} - dev: true - - /minizlib@2.1.2: - resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} - engines: {node: '>= 8'} - dependencies: - minipass: 3.3.6 - yallist: 4.0.0 - dev: true /mixme@0.5.10: resolution: {integrity: sha512-5H76ANWinB1H3twpJ6JY8uvAtpmFvHNArpilJAjXRKXSDDLPIMoZArw5SH0q9z+lLs8IrMw7Q2VWpWimFKFT1Q==} @@ -4399,13 +3985,6 @@ packages: /mkdirp-classic@0.5.3: resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} - dev: true - - /mkdirp@1.0.4: - resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} - engines: {node: '>=10'} - hasBin: true - dev: true /mkdist@1.5.1(typescript@5.4.5): resolution: {integrity: sha512-lCu1spNiA52o7IaKgZnOjg28nNHwYqUDjBfXePXyUtzD7Xhe6rRTkGTalQ/ALfrZC/SrPw2+A/0qkeJ+fPDZtQ==} @@ -4469,14 +4048,6 @@ packages: /napi-build-utils@1.0.2: resolution: {integrity: sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==} - dev: true - - /negotiator@0.6.3: - resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} - engines: {node: '>= 0.6'} - requiresBuild: true - dev: true - optional: true /nice-grpc-common@2.0.2: resolution: {integrity: sha512-7RNWbls5kAL1QVUOXvBsv1uO0wPQK3lHv+cY1gwkTzirnG1Nop4cBJZubpgziNbaVc/bl9QJcyvsf/NQxa3rjQ==} @@ -4497,12 +4068,6 @@ packages: engines: {node: '>=10'} dependencies: semver: 7.6.0 - dev: true - - /node-addon-api@7.1.0: - resolution: {integrity: sha512-mNcltoe1R8o7STTegSOHdnJNN7s5EUvhoS7ShnTHDyOSd+8H+UdWODq6qSv67PjC8Zc5JRT8+oLAMCr0SIXw7g==} - engines: {node: ^16 || ^18 || >= 20} - dev: true /node-fetch@2.7.0: resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} @@ -4516,42 +4081,10 @@ packages: whatwg-url: 5.0.0 dev: true - /node-gyp@8.4.1: - resolution: {integrity: sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w==} - engines: {node: '>= 10.12.0'} - hasBin: true - requiresBuild: true - dependencies: - env-paths: 2.2.1 - glob: 7.2.3 - graceful-fs: 4.2.11 - make-fetch-happen: 9.1.0 - nopt: 5.0.0 - npmlog: 6.0.2 - rimraf: 3.0.2 - semver: 7.6.0 - tar: 6.2.1 - which: 2.0.2 - transitivePeerDependencies: - - bluebird - - supports-color - dev: true - optional: true - /node-releases@2.0.14: resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} dev: true - /nopt@5.0.0: - resolution: {integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==} - engines: {node: '>=6'} - hasBin: true - requiresBuild: true - dependencies: - abbrev: 1.1.1 - dev: true - optional: true - /normalize-package-data@2.5.0: resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} dependencies: @@ -4578,19 +4111,6 @@ packages: path-key: 4.0.0 dev: true - /npmlog@6.0.2: - resolution: {integrity: sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} - deprecated: This package is no longer supported. - requiresBuild: true - dependencies: - are-we-there-yet: 3.0.1 - console-control-strings: 1.1.0 - gauge: 4.0.4 - set-blocking: 2.0.0 - dev: true - optional: true - /nth-check@2.1.1: resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} dependencies: @@ -4620,7 +4140,6 @@ packages: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} dependencies: wrappy: 1.0.2 - dev: true /onetime@6.0.0: resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} @@ -4685,15 +4204,6 @@ packages: engines: {node: '>=6'} dev: true - /p-map@4.0.0: - resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} - engines: {node: '>=10'} - requiresBuild: true - dependencies: - aggregate-error: 3.1.0 - dev: true - optional: true - /p-try@2.2.0: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} @@ -4714,13 +4224,6 @@ packages: engines: {node: '>=8'} dev: true - /path-is-absolute@1.0.1: - resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} - engines: {node: '>=0.10.0'} - requiresBuild: true - dev: true - optional: true - /path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} @@ -5119,7 +4622,6 @@ packages: simple-get: 4.0.1 tar-fs: 2.1.1 tunnel-agent: 0.6.0 - dev: true /preferred-pm@3.1.3: resolution: {integrity: sha512-MkXsENfftWSRpzCzImcp4FRsCc3y1opwB73CfCNWyzMqArju2CrlMHlqB7VexKiPEOjGMbttv1r9fSCn5S610w==} @@ -5151,27 +4653,6 @@ packages: react-is: 18.3.1 dev: true - /promise-inflight@1.0.1: - resolution: {integrity: sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==} - requiresBuild: true - peerDependencies: - bluebird: '*' - peerDependenciesMeta: - bluebird: - optional: true - dev: true - optional: true - - /promise-retry@2.0.1: - resolution: {integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==} - engines: {node: '>=10'} - requiresBuild: true - dependencies: - err-code: 2.0.3 - retry: 0.12.0 - dev: true - optional: true - /protobufjs@7.2.5: resolution: {integrity: sha512-gGXRSXvxQ7UiPgfw8gevrfRWcTlSbOFg+p/N+JVJEK5VhueL2miT6qTymqAmjr1Q5WbOCyJbyrk6JfWKwlFn6A==} engines: {node: '>=12.0.0'} @@ -5219,7 +4700,6 @@ packages: dependencies: end-of-stream: 1.4.4 once: 1.4.0 - dev: true /pure-rand@6.1.0: resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} @@ -5242,7 +4722,6 @@ packages: ini: 1.3.8 minimist: 1.2.8 strip-json-comments: 2.0.1 - dev: true /react-is@18.3.1: resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} @@ -5284,7 +4763,6 @@ packages: inherits: 2.0.4 string_decoder: 1.3.0 util-deprecate: 1.0.2 - dev: true /readdirp@3.6.0: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} @@ -5347,28 +4825,11 @@ packages: path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 - /retry@0.12.0: - resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} - engines: {node: '>= 4'} - requiresBuild: true - dev: true - optional: true - /reusify@1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} dev: true - /rimraf@3.0.2: - resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} - deprecated: Rimraf versions prior to v4 are no longer supported - hasBin: true - requiresBuild: true - dependencies: - glob: 7.2.3 - dev: true - optional: true - /rollup-plugin-dts@6.1.1(rollup@3.29.4)(typescript@5.4.5): resolution: {integrity: sha512-aSHRcJ6KG2IHIioYlvAOcEq6U99sVtqDDKVhnwt70rW6tsz3tv5OSjEiWcgzfsHdLyGXZ/3b/7b/+Za3Y6r1XA==} engines: {node: '>=16'} @@ -5435,7 +4896,6 @@ packages: /safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - dev: true /safe-regex-test@1.0.3: resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==} @@ -5550,7 +5010,6 @@ packages: /simple-concat@1.0.1: resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} - dev: true /simple-get@4.0.1: resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} @@ -5558,7 +5017,6 @@ packages: decompress-response: 6.0.0 once: 1.4.0 simple-concat: 1.0.1 - dev: true /slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} @@ -5575,13 +5033,6 @@ packages: engines: {node: '>=14.16'} dev: true - /smart-buffer@4.2.0: - resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} - engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} - requiresBuild: true - dev: true - optional: true - /smartwrap@2.0.2: resolution: {integrity: sha512-vCsKNQxb7PnCNd2wY1WClWifAc2lwqsG8OaswpJkVJsvMGcnEntdTCDajZCkk93Ay1U3t/9puJmb525Rg5MZBA==} engines: {node: '>=6'} @@ -5595,29 +5046,6 @@ packages: yargs: 15.4.1 dev: true - /socks-proxy-agent@6.2.1: - resolution: {integrity: sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ==} - engines: {node: '>= 10'} - requiresBuild: true - dependencies: - agent-base: 6.0.2 - debug: 4.3.4 - socks: 2.8.3 - transitivePeerDependencies: - - supports-color - dev: true - optional: true - - /socks@2.8.3: - resolution: {integrity: sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==} - engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} - requiresBuild: true - dependencies: - ip-address: 9.0.5 - smart-buffer: 4.2.0 - dev: true - optional: true - /source-map-js@1.2.0: resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} engines: {node: '>=0.10.0'} @@ -5656,39 +5084,6 @@ packages: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} dev: true - /sprintf-js@1.1.3: - resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==} - requiresBuild: true - dev: true - optional: true - - /sqlite3@5.1.7: - resolution: {integrity: sha512-GGIyOiFaG+TUra3JIfkI/zGP8yZYLPQ0pl1bH+ODjiX57sPhrLU5sQJn1y9bDKZUFYkX1crlrPfSYt0BKKdkog==} - requiresBuild: true - dependencies: - bindings: 1.5.0 - node-addon-api: 7.1.0 - prebuild-install: 7.1.2 - tar: 6.2.1 - optionalDependencies: - node-gyp: 8.4.1 - transitivePeerDependencies: - - bluebird - - supports-color - dev: true - - /sqlite@5.1.1: - resolution: {integrity: sha512-oBkezXa2hnkfuJwUo44Hl9hS3er+YFtueifoajrgidvqsJRQFpc5fKoAkAor1O5ZnLoa28GBScfHXs8j0K358Q==} - - /ssri@8.0.1: - resolution: {integrity: sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==} - engines: {node: '>= 8'} - requiresBuild: true - dependencies: - minipass: 3.3.6 - dev: true - optional: true - /stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} dev: true @@ -5743,7 +5138,6 @@ packages: requiresBuild: true dependencies: safe-buffer: 5.2.1 - dev: true /strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} @@ -5771,7 +5165,6 @@ packages: /strip-json-comments@2.0.1: resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} engines: {node: '>=0.10.0'} - dev: true /strip-literal@2.1.0: resolution: {integrity: sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==} @@ -5830,7 +5223,6 @@ packages: mkdirp-classic: 0.5.3 pump: 3.0.0 tar-stream: 2.2.0 - dev: true /tar-stream@2.2.0: resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} @@ -5841,19 +5233,6 @@ packages: fs-constants: 1.0.0 inherits: 2.0.4 readable-stream: 3.6.2 - dev: true - - /tar@6.2.1: - resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} - engines: {node: '>=10'} - dependencies: - chownr: 2.0.0 - fs-minipass: 2.1.0 - minipass: 5.0.0 - minizlib: 2.1.2 - mkdirp: 1.0.4 - yallist: 4.0.0 - dev: true /term-size@2.2.1: resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} @@ -5923,7 +5302,6 @@ packages: resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} dependencies: safe-buffer: 5.2.1 - dev: true /turbo-darwin-64@2.0.1: resolution: {integrity: sha512-GO391pUmI6c6l/EpUIaXNzwbVDWRvYahm5oLB176dAWRYKYO+Osqs/XBdOM0G3l7ZFdR6nUtRJc8qinJp7qDUQ==} @@ -6124,22 +5502,6 @@ packages: engines: {node: '>=18'} dev: true - /unique-filename@1.1.1: - resolution: {integrity: sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==} - requiresBuild: true - dependencies: - unique-slug: 2.0.2 - dev: true - optional: true - - /unique-slug@2.0.2: - resolution: {integrity: sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==} - requiresBuild: true - dependencies: - imurmurhash: 0.1.4 - dev: true - optional: true - /universalify@0.1.2: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} engines: {node: '>= 4.0.0'} @@ -6188,7 +5550,6 @@ packages: /util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - dev: true /validate-npm-package-license@3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} @@ -6687,14 +6048,6 @@ packages: stackback: 0.0.2 dev: true - /wide-align@1.1.5: - resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} - requiresBuild: true - dependencies: - string-width: 4.2.3 - dev: true - optional: true - /wrap-ansi@6.2.0: resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} engines: {node: '>=8'} @@ -6714,7 +6067,6 @@ packages: /wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - dev: true /ws@8.13.0: resolution: {integrity: sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==}