diff --git a/.changeset/brave-berries-bathe.md b/.changeset/brave-berries-bathe.md new file mode 100644 index 0000000..8599ff7 --- /dev/null +++ b/.changeset/brave-berries-bathe.md @@ -0,0 +1,5 @@ +--- +'@electric-sql/d2ts': patch +--- + +ElectricSQL intigration diff --git a/README.md b/README.md index 9e320d2..4123dfa 100644 --- a/README.md +++ b/README.md @@ -139,9 +139,6 @@ graph.run() D2TS can be used in conjunction with [ElectricSQL](https://electric-sql.com) to build data pipelines on top of [ShapeStreams](https://electric-sql.com/docs/api/clients/typescript#shapestream) that can be executed incrementally. -> [!NOTE] -> Electric support has not yet been merged to main, you can follow the progress [in this PR](https://github.com/electric-sql/d2ts/pull/11). - Here's an example of how to use D2TS with ElectricSQL: ```typescript @@ -180,6 +177,8 @@ const electricStream = new ShapeStream({ electricStreamToD2Input(electricStream, input) ``` +There is a complete example in the [./examples/electric](./examples/electric) directory. + ## Examples There are a number of examples in the [./examples](./examples) directory, covering: @@ -189,6 +188,7 @@ There are a number of examples in the [./examples](./examples) directory, coveri - [Joins between two streams](./examples/join.ts) - [Iterative computations](./examples/iterate.ts) - [Modeling "includes" using joins](./examples/includes.ts) +- [ElectricSQL example](./examples/electric/) (using D2TS with ElectricSQL) ## API diff --git a/examples/electric/README.md b/examples/electric/README.md new file mode 100644 index 0000000..21d8062 --- /dev/null +++ b/examples/electric/README.md @@ -0,0 +1,105 @@ +# ElectricSQL Example with D2TS + +This example demonstrates how to use [D2TS](https://github.com/electric-sql/d2ts) with [ElectricSQL](https://electric-sql.com) to build a real-time data pipeline that processes changes incrementally. The example implements an issue tracking system with users, issues, and comments. + +## Overview + +This example showcases: + +1. Setting up ElectricSQL with PostgreSQL +2. Building an incremental data pipeline using D2TS +3. Performing joins, aggregations, and transformations on real-time data +4. Processing data changes efficiently with differential dataflow + +## Architecture + +The example consists of: + +- A PostgreSQL database paired with ElectricSQL for syncing out changes in real-time +- Schema for users, issues, and comments +- A D2TS pipeline that: + - Joins issues with their creators (users) + - Counts comments for each issue + - Consolidates the data into a unified view + +## Data Model + +The example implements a simple issue tracking system with: + +- **Users**: People who create issues and comments +- **Issues**: Tasks or bugs with properties like priority and status +- **Comments**: Text comments on issues + +## Prerequisites + +- Node.js and pnpm +- Docker and Docker Compose (for running PostgreSQL and ElectricSQL) + +## Setup and Running + +1. **Start the backend services** + + ```bash + pnpm backend:up + ``` + + This starts PostgreSQL and ElectricSQL services using Docker Compose. + +2. **Set up the database** + + ```bash + pnpm db:migrate + ``` + + This applies the database migrations to create the necessary tables. + +3. **Load sample data** + + ```bash + pnpm db:load-data + ``` + + This loads sample users, issues, and comments data into the database. + +4. **Run the example** + + ```bash + pnpm start + ``` + + This starts the D2TS pipeline that consumes data from ElectricSQL and processes it incrementally. The pipeline will output the processed data to the console. + +5. **Reset everything (optional)** + + ```bash + pnpm reset + ``` + + This command tears down the services, recreates them, applies migrations, and loads fresh data. + +## How It Works + +The pipeline in `src/index.ts` demonstrates: + +1. **Creating a D2TS graph** - The foundation for the data processing pipeline +2. **Setting up inputs** - Connecting ElectricSQL shape streams to D2TS inputs +3. **Building transformations**: + - Calculating comment counts per issue + - Joining issues with their creators + - Transforming and consolidating the data +4. **Consuming the results** - Outputting processed data as it changes + +The ElectricSQL integration uses `MultiShapeStream` to consume multiple shapes (one per table) from the same Electric instance and the `electricStreamToD2Input` helper to connect Electric streams to D2TS inputs. + +## Key Concepts + +- **Differential Dataflow**: D2TS enables incremental computations, only reprocessing what's changed +- **ElectricSQL ShapeStreams**: Real-time data streams that emit changes to the database +- **LSN-based Processing**: Changes are processed based on PostgreSQL Log Sequence Numbers (LSNs) for consistency - these are used at the "version" of the data passed to D2TS + +## Resources + +- [D2TS Documentation](https://github.com/electric-sql/d2ts) +- [ElectricSQL Documentation](https://electric-sql.com/docs) +- [Differential Dataflow Paper](https://github.com/frankmcsherry/blog/blob/master/posts/2015-09-29.md) + diff --git a/examples/electric/db/generate_data.js b/examples/electric/db/generate_data.js new file mode 100644 index 0000000..79dd037 --- /dev/null +++ b/examples/electric/db/generate_data.js @@ -0,0 +1,62 @@ +import { faker } from '@faker-js/faker' +import { v4 as uuidv4 } from 'uuid' + +export function generateUsers(numUsers) { + return Array.from({ length: numUsers }, generateUser) +} + +function generateUser() { + return { + id: uuidv4(), + username: faker.internet.userName(), + email: faker.internet.email(), + full_name: faker.person.fullName() + } +} + +export function generateIssues(numIssues, userIds) { + if (!userIds?.length) { + throw new Error('User IDs are required to generate issues') + } + + return Array.from({ length: numIssues }, () => generateIssue(userIds)) +} + +function generateIssue(userIds) { + const issueId = uuidv4() + const createdAt = faker.date.past() + return { + id: issueId, + title: faker.lorem.sentence({ min: 3, max: 8 }), + description: faker.lorem.sentences({ min: 2, max: 6 }, `\n`), + priority: faker.helpers.arrayElement([`none`, `low`, `medium`, `high`]), + status: faker.helpers.arrayElement([ + `backlog`, + `todo`, + `in_progress`, + `done`, + `canceled`, + ]), + created: createdAt.toISOString(), + modified: faker.date + .between({ from: createdAt, to: new Date() }) + .toISOString(), + user_id: faker.helpers.arrayElement(userIds), + comments: faker.helpers.multiple( + () => generateComment(issueId, createdAt, userIds), + { count: faker.number.int({ min: 0, max: 10 }) } + ), + } +} + +function generateComment(issueId, issueCreatedAt, userIds) { + return { + id: uuidv4(), + body: faker.lorem.text(), + user_id: faker.helpers.arrayElement(userIds), + issue_id: issueId, + created_at: faker.date + .between({ from: issueCreatedAt, to: new Date() }) + .toISOString(), + } +} diff --git a/examples/electric/db/load_data.js b/examples/electric/db/load_data.js new file mode 100644 index 0000000..daa7401 --- /dev/null +++ b/examples/electric/db/load_data.js @@ -0,0 +1,69 @@ +import createPool, { sql } from '@databases/pg' +import { generateUsers, generateIssues } from './generate_data.js' + +const DATABASE_URL = process.env.DATABASE_URL || 'postgresql://postgres:password@localhost:54321/electric' +const ISSUES_TO_LOAD = process.env.ISSUES_TO_LOAD || 10 +const USERS_TO_LOAD = process.env.USERS_TO_LOAD || 3 + +console.info(`Connecting to Postgres at ${DATABASE_URL}`) +const db = createPool(DATABASE_URL) + +async function makeInsertQuery(db, table, data) { + const columns = Object.keys(data) + const columnsNames = columns.join(`, `) + const values = columns.map((column) => data[column]) + return await db.query(sql` + INSERT INTO ${sql.ident(table)} (${sql(columnsNames)}) + VALUES (${sql.join(values.map(sql.value), `, `)}) + `) +} + +async function importUser(db, user) { + return await makeInsertQuery(db, `user`, user) +} + +async function importIssue(db, issue) { + const { comments: _, ...rest } = issue + return await makeInsertQuery(db, `issue`, rest) +} + +async function importComment(db, comment) { + return await makeInsertQuery(db, `comment`, comment) +} + +// Generate and load users first +const users = generateUsers(USERS_TO_LOAD) +const userIds = users.map(user => user.id) + +console.info(`Loading ${users.length} users...`) +await db.tx(async (db) => { + for (const user of users) { + await importUser(db, user) + } +}) + +// Then generate and load issues with comments +const issues = generateIssues(ISSUES_TO_LOAD, userIds) +const issueCount = issues.length +let commentCount = 0 +const batchSize = 100 + +for (let i = 0; i < issueCount; i += batchSize) { + await db.tx(async (db) => { + db.query(sql`SET CONSTRAINTS ALL DEFERRED;`) // disable FK checks + for (let j = i; j < i + batchSize && j < issueCount; j++) { + process.stdout.write(`Loading issue ${j + 1} of ${issueCount}\r`) + const issue = issues[j] + await importIssue(db, issue) + for (const comment of issue.comments) { + commentCount++ + await importComment(db, comment) + } + } + }) +} + +process.stdout.write(`\n`) + +await db.dispose() +console.info(`Loaded ${users.length} users, ${issueCount} issues with ${commentCount} comments.`) diff --git a/examples/electric/db/migrations/01-create_tables.sql b/examples/electric/db/migrations/01-create_tables.sql new file mode 100644 index 0000000..7f2127a --- /dev/null +++ b/examples/electric/db/migrations/01-create_tables.sql @@ -0,0 +1,31 @@ +CREATE TABLE IF NOT EXISTS "user" ( + "id" UUID NOT NULL, + "username" TEXT NOT NULL, + "email" TEXT NOT NULL, + "full_name" TEXT NOT NULL, + CONSTRAINT "user_pkey" PRIMARY KEY ("id") +); + +CREATE TABLE IF NOT EXISTS "issue" ( + "id" UUID NOT NULL, + "title" TEXT NOT NULL, + "description" TEXT NOT NULL, + "priority" TEXT NOT NULL, + "status" TEXT NOT NULL, + "modified" TIMESTAMPTZ NOT NULL, + "created" TIMESTAMPTZ NOT NULL, + "user_id" UUID NOT NULL, + CONSTRAINT "issue_pkey" PRIMARY KEY ("id"), + FOREIGN KEY (user_id) REFERENCES "user"(id) ON DELETE CASCADE DEFERRABLE +); + +CREATE TABLE IF NOT EXISTS "comment" ( + "id" UUID NOT NULL, + "body" TEXT NOT NULL, + "user_id" UUID NOT NULL, + "issue_id" UUID NOT NULL, + "created_at" TIMESTAMPTZ NOT NULL, + CONSTRAINT "comment_pkey" PRIMARY KEY ("id"), + FOREIGN KEY (user_id) REFERENCES "user"(id) ON DELETE CASCADE DEFERRABLE, + FOREIGN KEY (issue_id) REFERENCES issue(id) ON DELETE CASCADE DEFERRABLE +); \ No newline at end of file diff --git a/examples/electric/docker-compose.yml b/examples/electric/docker-compose.yml new file mode 100644 index 0000000..fff654e --- /dev/null +++ b/examples/electric/docker-compose.yml @@ -0,0 +1,29 @@ +version: "3.3" +name: "electric_d2_example" + +services: + postgres: + image: postgres:16-alpine + environment: + POSTGRES_DB: electric + POSTGRES_USER: postgres + POSTGRES_PASSWORD: password + ports: + - 54321:5432 + tmpfs: + - /var/lib/postgresql/data + - /tmp + command: + - -c + - listen_addresses=* + - -c + - wal_level=logical + + backend: + image: electricsql/electric:latest + environment: + DATABASE_URL: postgresql://postgres:password@postgres:5432/electric?sslmode=disable + ports: + - 3000:3000 + depends_on: + - postgres diff --git a/examples/electric/package.json b/examples/electric/package.json new file mode 100644 index 0000000..6f002b5 --- /dev/null +++ b/examples/electric/package.json @@ -0,0 +1,34 @@ +{ + "name": "@electric-sql/d2ts-electric-example", + "version": "0.0.0", + "private": true, + "description": "", + "main": "index.js", + "scripts": { + "backend:down": "docker compose down --volumes", + "backend:up": "docker compose up -d", + "db:load-data": "node ./db/load_data.js", + "db:migrate": "DATABASE_URL=postgresql://postgres:password@localhost:54321/electric pnpm exec pg-migrations apply --directory ./db/migrations", + "reset": "pnpm backend:down && pnpm backend:up && pnpm db:migrate && pnpm db:load-data", + "start": "tsx src/index.ts", + "format": "prettier --write \"src/**/*.{ts,tsx,js,jsx,json}\"", + "format:check": "prettier --check \"src/**/*.{ts,tsx,js,jsx,json}\"" + }, + "keywords": [], + "author": "", + "license": "Apache-2.0", + "devDependencies": { + "@databases/pg": "^5.5.0", + "@databases/pg-migrations": "^5.0.3", + "@faker-js/faker": "^8.4.1", + "prettier": "^3.2.5", + "tsx": "^4.7.0", + "typescript": "^5.0.0", + "uuid": "^9.0.0" + }, + "dependencies": { + "@electric-sql/client": ">=1.0.0-beta.4", + "@electric-sql/experimental": ">=0.1.2-beta.3", + "@electric-sql/d2ts": "workspace:*" + } +} diff --git a/examples/electric/src/index.ts b/examples/electric/src/index.ts new file mode 100644 index 0000000..1b34c60 --- /dev/null +++ b/examples/electric/src/index.ts @@ -0,0 +1,177 @@ +import { MultiShapeStream } from '@electric-sql/experimental' +import { IssuePriority, IssueStatus, Issue, User, Comment } from './types' +import { + D2, + map, + join, + reduce, + consolidate, + concat, +} from '@electric-sql/d2ts' +import { + electricStreamToD2Input, + outputElectricMessages, +} from '@electric-sql/d2ts/electric' + +// The URL of the ElectricSQL instance +const ELECTRIC_URL = 'http://localhost:3000/v1/shape' + +// This is the structure of the data that we want to output +export interface IssueData { + id: string + title: string + description: string + priority: IssuePriority + status: IssueStatus + modified: Date + created: Date + user_id: string + username: string + user_email: string + user_full_name: string + comment_count: number +} + +// Create D2 graph +const graph = new D2({ initialFrontier: 0 }) + +// Create D2 inputs +// These will be connected to the ElectricSQL streams below +const issuesInput = graph.newInput<[string, Issue]>() +const usersInput = graph.newInput<[string, User]>() +const commentsInput = graph.newInput<[string, Comment]>() + +// We now construct the D2 pipeline + +// Calculate comment counts per issue +// We need a zero for each issue to ensure that we get a row for each issue, even if +// there are no comments +const commentCountZero = issuesInput.pipe( + map(([_key, issue]) => [issue.id, 0] as [string, number]), +) +// We "key" the comments by issue_id, combine with the zero for each issue, and then +// reduce to get the comment count +const commentCounts = commentsInput.pipe( + map(([_key, comment]) => [comment.issue_id, 1] as [string, number]), + concat(commentCountZero), + reduce((values) => { + let count = 0 + for (const [num, diff] of values) { + count += num * diff + } + return [[count, 1]] + }), +) + +// Transform issues for joining with users +// We "key" the issues by user_id so that they can be joined with the users +const issuesForJoin = issuesInput.pipe( + map(([_key, issue]) => [issue.user_id, issue] as [string, Issue]), +) + +// Transform users for joining with issues +// "key" the users by id so that they can be joined with the issues +const usersForJoin = usersInput.pipe( + map(([_key, user]) => [user.id, user] as [string, User]), +) + +// Join issues with users +// We join the issues with the users so that we can get the users details for each issue +const issuesWithUsers = issuesForJoin.pipe( + join(usersForJoin), + map( + ([_key, [issue, user]]) => + [issue.id, { issue, user }] as [string, { issue: Issue; user: User }], + ), +) + +// Join with comment counts and map to final structure +// We join the issues with the comment counts so that we can get the comment count for +// each issue and then map to the final structure +const finalStream = issuesWithUsers.pipe( + join(commentCounts), + map(([_key, [data, commentCount]]) => { + const { issue, user } = data + return [ + issue.id, + { + id: issue.id, + title: issue.title, + description: issue.description, + priority: issue.priority, + status: issue.status, + modified: issue.modified, + created: issue.created, + user_id: user.id, + username: user.username, + user_email: user.email, + user_full_name: user.full_name, + comment_count: commentCount || 0, + }, + ] as [string, IssueData] + }), + consolidate(), + outputElectricMessages((msg) => { + // Output the messages in the pipeline as ElectricSQL change messages + console.log(msg) + console.log('--------------------------------') + }), +) + +// Finalize graph +graph.finalize() + +// Create Electric shape streams +// We are using the experimental MultiShapeStream to consume multiple shapes +// from the same Electric instance which ensures that we get an `up-to-date` on all +// shapes within the `checkForUpdatesAfter` interval. +const streams = new MultiShapeStream<{ + issue: Issue + user: User + comment: Comment +}>({ + checkForUpdatesAfterMs: 100, + shapes: { + issue: { + url: ELECTRIC_URL, + params: { + table: 'issue', + replica: 'full', + }, + }, + user: { + url: ELECTRIC_URL, + params: { + table: 'user', + replica: 'full', + }, + }, + comment: { + url: ELECTRIC_URL, + params: { + table: 'comment', + replica: 'full', + }, + }, + }, +}) + +// Connect Electric streams to D2 inputs +electricStreamToD2Input({ + graph, + stream: streams.shapes.issue, + input: issuesInput, + runOn: 'lsn-advance', +}) +electricStreamToD2Input({ + graph, + stream: streams.shapes.user, + input: usersInput, + runOn: 'lsn-advance', +}) +electricStreamToD2Input({ + graph, + stream: streams.shapes.comment, + input: commentsInput, + runOn: 'lsn-advance', +}) diff --git a/examples/electric/src/types.ts b/examples/electric/src/types.ts new file mode 100644 index 0000000..312bf88 --- /dev/null +++ b/examples/electric/src/types.ts @@ -0,0 +1,44 @@ +export interface User extends Record { + id: string // UUID + username: string + email: string + full_name: string +} + +export interface Issue extends Record { + id: string // UUID + title: string + description: string + priority: IssuePriority + status: IssueStatus + modified: Date + created: Date + user_id: string // UUID, foreign key to User +} + +export interface Comment extends Record { + id: string // UUID + body: string + user_id: string // UUID, foreign key to User + issue_id: string // UUID, foreign key to Issue + created_at: Date +} + +export const IssuePriority = { + none: 'none', + low: 'low', + medium: 'medium', + high: 'high', +} as const + +export type IssuePriority = (typeof IssuePriority)[keyof typeof IssuePriority] + +export const IssueStatus = { + backlog: 'backlog', + todo: 'todo', + in_progress: 'in_progress', + done: 'done', + canceled: 'canceled', +} as const + +export type IssueStatus = (typeof IssueStatus)[keyof typeof IssueStatus] diff --git a/packages/d2ts/package.json b/packages/d2ts/package.json index b11e0d6..93a2c97 100644 --- a/packages/d2ts/package.json +++ b/packages/d2ts/package.json @@ -29,6 +29,10 @@ "types": "./dist/sqlite/index.d.ts", "default": "./dist/sqlite/index.js" }, + "./electric": { + "types": "./dist/electric/index.d.ts", + "default": "./dist/electric/index.js" + }, "./store": { "types": "./dist/store.d.ts", "default": "./dist/store.js" @@ -48,23 +52,28 @@ "format:check": "prettier --check \"src/**/*.{ts,tsx,js,jsx,json}\" \"tests/**/*.{ts,tsx,js,jsx,json}\"" }, "devDependencies": { + "@electric-sql/client": ">=1.0.0-beta.4", "@types/better-sqlite3": "^7.6.12", "@types/node": "^22.10.2", "@typescript-eslint/eslint-plugin": "^8.18.0", "@typescript-eslint/parser": "^8.18.0", "better-sqlite3": "^11.7.0", + "eslint": "^9.16.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.1.3", - "eslint": "^9.16.0", "prettier": "^3.2.5", "tsx": "^4.7.0", "typescript": "^5.7.2", "vitest": "^2.1.8" }, "peerDependencies": { + "@electric-sql/client": ">=1.0.0-beta.4", "better-sqlite3": "^11.7.0" }, "peerDependenciesMeta": { + "@electric-sql/client": { + "optional": true + }, "better-sqlite3": { "optional": true } diff --git a/packages/d2ts/src/electric/index.ts b/packages/d2ts/src/electric/index.ts new file mode 100644 index 0000000..d439701 --- /dev/null +++ b/packages/d2ts/src/electric/index.ts @@ -0,0 +1,349 @@ +import { D2, RootStreamBuilder } from '../d2.js' +import { MultiSetArray } from '../multiset.js' +import { type Version, type Antichain } from '../order.js' +import { + IStreamBuilder, + Message, + DataMessage, + MessageType, + KeyValue, +} from '../types.js' +import { + DifferenceStreamReader, + DifferenceStreamWriter, + UnaryOperator, +} from '../graph.js' +import { StreamBuilder } from '../d2.js' +import { + type Row, + type ShapeStreamInterface, + type ChangeMessage, + type Operation, + isChangeMessage, + isControlMessage, +} from '@electric-sql/client' + +/* +Electric uses Postgres LSNs to track progress, each message is annotated with an LSN. +We need to keep track of these and use them to send as the version for each message to +the D2 input stream. +D2 also requires a a frontier message for be sent, this is the lower bound for all +future messages. +To do this we: +- Keep track of the last LSN we've seen +- Send the LSN as the version for each message +- When we receive an `up-to-date` message, we send the last LSN+1 as the frontier. The + addition of 1 is to account for the fact that the last LSN is the version of the last + message, and we need to send the version of the next message as the frontier. +*/ + +export interface ElectricStreamToD2InputOptions = Row> { + /** D2 Graph to send messages to */ + graph: D2 + /** The Electric ShapeStream to consume */ + stream: ShapeStreamInterface + /** The D2 input stream to send messages to */ + input: RootStreamBuilder<[key: string, T]> + /** Optional function to convert LSN to version number/Version */ + lsnToVersion?: (lsn: number) => number | Version + /** Optional function to convert LSN to frontier number/Antichain */ + lsnToFrontier?: (lsn: number) => number | Antichain + /** Initial LSN */ + initialLsn?: number + /** When to run the graph */ + runOn?: 'up-to-date' | 'lsn-advance' | false + /** Whether to log debug messages */ + debug?: boolean | typeof console.log +} + +/** + * Connects an Electric ShapeStream to a D2 input stream + * IMPORTANT: Requires the ShapeStream to be configured with `replica: 'full'` + * @param options Configuration options + * @param options.stream The Electric ShapeStream to consume + * @param options.input The D2 input stream to send messages to + * @param options.lsnToVersion Optional function to convert LSN to version number/Version + * @param options.lsnToFrontier Optional function to convert LSN to frontier number/Antichain + * @returns The input stream for chaining + * + * @example + * ```ts + * // Create D2 graph + * const graph = new D2({ initialFrontier: 0 }) + * + * // Create D2 input + * const input = graph.newInput() + * + * // Configure the pipeline + * input + * .pipe( + * map(([key, data]) => data.value), + * filter(value => value > 10) + * ) + * + * // Finalize graph + * graph.finalize() + * + * // Create Electric stream (example) + * const electricStream = new ShapeStream({ + * url: 'http://localhost:3000/v1/shape', + * params: { + * table: 'items', + * replica: 'full', + * } + * }) + * + * // Connect Electric stream to D2 input + * electricStreamToD2Input({ + * stream: electricStream, + * input, + * }) + * ``` + */ +export function electricStreamToD2Input = Row>({ + graph, + stream, + input, + lsnToVersion = (lsn: number) => lsn, + lsnToFrontier = (lsn: number) => lsn, + initialLsn = 0, + runOn = 'up-to-date', + debug = false, +}: ElectricStreamToD2InputOptions): RootStreamBuilder<[key: string, T]> { + let lastLsn: number = initialLsn + let changes: MultiSetArray<[key: string, T]> = [] + + const sendChanges = (lsn: number) => { + const version = lsnToVersion(lsn) + log?.(`sending ${changes.length} changes at version ${version}`) + if (changes.length > 0) { + input.sendData(version, [...changes]) + } + changes = [] + } + + const sendFrontier = (lsn: number) => { + const frontier = lsnToFrontier(lsn + 1) // +1 to account for the fact that the last LSN is the version of the last message + log?.(`sending frontier ${frontier}`) + input.sendFrontier(frontier) + } + + const log = + typeof debug === 'function' + ? debug + : debug === true + ? // eslint-disable-next-line no-console + console.log + : undefined + + log?.('subscribing to stream') + stream.subscribe((messages) => { + log?.(`received ${messages.length} messages`) + for (const message of messages) { + if (isControlMessage(message)) { + log?.(`- control message: ${message.headers.control}`) + // Handle control message + if (message.headers.control === 'up-to-date') { + log?.(`up-to-date ${JSON.stringify(message, null, 2)}`) + if (changes.length > 0) { + sendChanges(lastLsn) + } + if (typeof message.headers.global_last_seen_lsn !== `number`) { + throw new Error(`global_last_seen_lsn is not a number`) + } + const lsn = message.headers.global_last_seen_lsn + sendFrontier(lsn) + if (runOn === 'up-to-date' || runOn === 'lsn-advance') { + log?.('running graph on up-to-date') + graph.run() + } + } else if (message.headers.control === 'must-refetch') { + throw new Error( + 'The server sent a "must-refetch" request, this is incompatible with a D2 pipeline and unresolvable. To handle this you will have to remove all state and start the pipeline again.', + ) + } + } else if (isChangeMessage(message)) { + log?.(`- change message: ${message.headers.operation}`) + // Handle change message + if ( + message.headers.lsn !== undefined && + typeof message.headers.lsn !== `number` + ) { + throw new Error(`lsn is not a number`) + } + const lsn = message.headers.lsn ?? initialLsn // The LSN is not present on the initial snapshot + const last: boolean = + (message.headers.last as boolean | undefined) ?? false + switch (message.headers.operation) { + case 'insert': + changes.push([[message.key, message.value], 1]) + break + case 'update': { + // An update in D2 is a delete followed by an insert. + // `old_value` only holds the old values *that have changed* + // so we need to merge the old and new value to get a complete row + // that represents the row as it was before the update. + const oldValue = { + ...message.value, + ...(message.old_value ?? {}), + } + changes.push([[message.key, oldValue], -1]) + changes.push([[message.key, message.value], 1]) + break + } + case 'delete': + changes.push([[message.key, message.value], -1]) + break + } + if (last) { + sendChanges(lsn) + sendFrontier(lsn) + if (runOn === 'lsn-advance') { + log?.('running graph on lsn-advance') + graph.run() + } + } + if (lsn > lastLsn) { + lastLsn = lsn + } + } + } + }) + + return input +} + +/** + * Operator that outputs the messages from the stream in ElectricSQL format + * + * TODO: Have two modes `replica=default` and `replica=full` to match the two modes + * of core Electric. + */ +export class OutputElectricMessagesOperator extends UnaryOperator< + [K, V] +> { + #fn: (data: ChangeMessage>[]) => void + + constructor( + id: number, + inputA: DifferenceStreamReader<[K, V]>, + output: DifferenceStreamWriter<[K, V]>, + fn: (data: ChangeMessage>[]) => void, + initialFrontier: Antichain, + ) { + super(id, inputA, output, initialFrontier) + this.#fn = fn + } + + transformMessages(messages: Message<[K, V]>[]): ChangeMessage>[] { + const output: ChangeMessage>[] = [] + let lastLSN = -Infinity + for (const message of messages) { + if (message.type === MessageType.DATA) { + const { version, collection } = message.data as DataMessage<[K, V]> + // We use the first element of the D2version as the LSN as its what we used + // in the input + const lsn = version.getInner()[0] + if (lsn < lastLSN) { + throw new Error( + `Invalid LSN ${lsn} less than lastLSN ${lastLSN}, you must consolidate your stream before passing it to the OutputElectricMessagesOperator`, + ) + } + lastLSN = lsn + + const changesByKey = new Map< + K, + { deletes: number; inserts: number; value: V } + >() + + for (const [[key, value], multiplicity] of collection.getInner()) { + let changes = changesByKey.get(key) + if (!changes) { + changes = { deletes: 0, inserts: 0, value: value } + changesByKey.set(key, changes) + } + + if (multiplicity < 0) { + changes.deletes += Math.abs(multiplicity) + } else if (multiplicity > 0) { + changes.inserts += multiplicity + changes.value = value + } + } + + const newMessages = Array.from(changesByKey.entries()).map( + ([key, { deletes, inserts, value }]) => { + const operation: Operation = + deletes > inserts + ? 'delete' + : inserts > deletes + ? 'insert' + : 'update' + return { + key: (key as any).toString(), + value: value as Row, + headers: { lsn, operation }, + } + }, + ) + + output.push(...newMessages) + } + } + return output + } + + run(): void { + const messages = this.inputMessages() + const outputMessages = this.transformMessages(messages) + if (outputMessages.length > 0) { + this.#fn(outputMessages) + } + for (const message of messages) { + if (message.type === MessageType.DATA) { + const { version, collection } = message.data as DataMessage<[K, V]> + this.output.sendData(version, collection) + } else if (message.type === MessageType.FRONTIER) { + const frontier = message.data as Antichain + if (!this.inputFrontier().lessEqual(frontier)) { + throw new Error('Invalid frontier update') + } + this.setInputFrontier(frontier) + if (!this.outputFrontier.lessEqual(this.inputFrontier())) { + throw new Error('Invalid frontier state') + } + if (this.outputFrontier.lessThan(this.inputFrontier())) { + this.outputFrontier = this.inputFrontier() + this.output.sendFrontier(this.outputFrontier) + } + } + } + } +} + +/** + * Outputs the messages from the stream in ElectricSQL format + * @param fn - The function to call with a batch of messages + */ +export function outputElectricMessages< + K extends T extends KeyValue ? K : never, + V extends T extends KeyValue ? V : never, + T, +>(fn: (data: ChangeMessage>[]) => void) { + return (stream: IStreamBuilder): IStreamBuilder> => { + const output = new StreamBuilder>( + stream.graph, + new DifferenceStreamWriter>(), + ) + const operator = new OutputElectricMessagesOperator( + stream.graph.getNextOperatorId(), + stream.connectReader() as DifferenceStreamReader>, + output.writer, + fn, + stream.graph.frontier(), + ) + stream.graph.addOperator(operator) + stream.graph.addStream(output.connectReader()) + return output + } +} diff --git a/packages/d2ts/tests/electric.test.ts b/packages/d2ts/tests/electric.test.ts new file mode 100644 index 0000000..9534b7a --- /dev/null +++ b/packages/d2ts/tests/electric.test.ts @@ -0,0 +1,410 @@ +import { describe, it, expect, vi, beforeEach } from 'vitest' +import { electricStreamToD2Input } from '../src/electric' +import { D2 } from '../src/d2' +import type { + ShapeStreamInterface, + Message, + Offset, +} from '@electric-sql/client' + +describe('electricStreamToD2Input', () => { + let mockStream: ShapeStreamInterface + let mockSubscribeCallback: (messages: Message[]) => void + let d2: D2 + let input: any + + beforeEach(() => { + mockSubscribeCallback = vi.fn() + mockStream = { + subscribe: (callback) => { + mockSubscribeCallback = callback + return () => {} // Return unsubscribe function + }, + unsubscribeAll: vi.fn(), + isLoading: () => false, + lastSyncedAt: () => Date.now(), + lastSynced: () => 0, + isConnected: () => true, + isUpToDate: true, + lastOffset: '0_0', + shapeHandle: 'test-handle', + error: undefined, + hasStarted: () => true, + forceDisconnectAndRefresh: vi.fn(), + } + + d2 = new D2({ initialFrontier: 0 }) + input = d2.newInput() + vi.spyOn(input, 'sendData') + vi.spyOn(input, 'sendFrontier') + }) + + it('should handle insert operations correctly when message has last flag', () => { + electricStreamToD2Input({ + graph: d2, + stream: mockStream, + input, + }) + + const messages: Message[] = [ + { + headers: { + operation: 'insert', + lsn: 100, + op_position: 1, + last: true, + }, + key: 'test-1', + value: { id: 1, name: 'test' }, + }, + ] + + mockSubscribeCallback(messages) + + expect(input.sendData).toHaveBeenCalledWith( + 100, + expect.arrayContaining([[['test-1', { id: 1, name: 'test' }], 1]]), + ) + }) + + it('should handle update operations as delete + insert when message has last flag', () => { + electricStreamToD2Input({ + graph: d2, + stream: mockStream, + input, + }) + + const messages: Message[] = [ + { + headers: { + operation: 'update', + lsn: 100, + op_position: 1, + last: true, + }, + key: 'test-1', + value: { id: 1, name: 'updated' }, + }, + ] + + mockSubscribeCallback(messages) + + expect(input.sendData).toHaveBeenCalledWith( + 100, + expect.arrayContaining([ + [['test-1', { id: 1, name: 'updated' }], -1], + [['test-1', { id: 1, name: 'updated' }], 1], + ]), + ) + }) + + it('should handle delete operations correctly when message has last flag', () => { + electricStreamToD2Input({ + graph: d2, + stream: mockStream, + input, + }) + + const messages: Message[] = [ + { + headers: { + operation: 'delete', + lsn: 100, + op_position: 1, + last: true, + }, + key: 'test-1', + value: { id: 1, name: 'deleted' }, + }, + ] + + mockSubscribeCallback(messages) + + expect(input.sendData).toHaveBeenCalledWith( + 100, + expect.arrayContaining([[['test-1', { id: 1, name: 'deleted' }], -1]]), + ) + }) + + it('should handle operations with up-to-date control message', () => { + electricStreamToD2Input({ + graph: d2, + stream: mockStream, + input, + }) + + const messages: Message[] = [ + { + headers: { + operation: 'insert', + lsn: 100, + op_position: 1, + }, + key: 'test-1', + value: { id: 1, name: 'test' }, + }, + { + headers: { + control: 'up-to-date', + global_last_seen_lsn: 100, + }, + }, + ] + + mockSubscribeCallback(messages) + + expect(input.sendData).toHaveBeenCalledWith( + 100, + expect.arrayContaining([[['test-1', { id: 1, name: 'test' }], 1]]), + ) + expect(input.sendFrontier).toHaveBeenCalledWith(101) + }) + + it('should handle control messages and send frontier', () => { + electricStreamToD2Input({ + graph: d2, + stream: mockStream, + input, + }) + + const messages: Message[] = [ + { + headers: { + control: 'up-to-date', + global_last_seen_lsn: 100, + }, + }, + ] + + mockSubscribeCallback(messages) + + expect(input.sendFrontier).toHaveBeenCalledWith(101) + }) + + it('should use custom lsnToVersion and lsnToFrontier functions', () => { + const customLsnToVersion = (lsn: number) => lsn * 2 + const customLsnToFrontier = (lsn: number) => lsn * 3 + + electricStreamToD2Input({ + graph: d2, + stream: mockStream, + input, + lsnToVersion: customLsnToVersion, + lsnToFrontier: customLsnToFrontier, + }) + + const messages: Message[] = [ + { + headers: { + operation: 'insert', + lsn: 100, + op_position: 1, + last: true, + }, + key: 'test-1', + value: { id: 1 }, + }, + { + headers: { + control: 'up-to-date', + global_last_seen_lsn: 100, + }, + }, + ] + + mockSubscribeCallback(messages) + + expect(input.sendData).toHaveBeenCalledWith( + 200, // 100 * 2 + expect.arrayContaining([[['test-1', { id: 1 }], 1]]), + ) + expect(input.sendFrontier).toHaveBeenCalledWith(303) // (100 + 1) * 3 + }) + + it('should handle partial updates correctly by merging old and new values', () => { + electricStreamToD2Input({ + graph: d2, + stream: mockStream, + input, + }) + + const messages: Message[] = [ + { + headers: { + operation: 'update', + lsn: 100, + op_position: 1, + last: true, + }, + key: 'test-1', + value: { id: 1, name: 'updated', age: 30 }, + old_value: { name: 'old' }, // Only contains changed fields + }, + ] + + mockSubscribeCallback(messages) + + // Should send a delete with the complete old value (merged from value and old_value) + expect(input.sendData).toHaveBeenCalledWith( + 100, + expect.arrayContaining([ + [['test-1', { id: 1, name: 'old', age: 30 }], -1], + [['test-1', { id: 1, name: 'updated', age: 30 }], 1], + ]), + ) + }) + + it('should throw error on must-refetch control message', () => { + electricStreamToD2Input({ + graph: d2, + stream: mockStream, + input, + }) + + const messages: Message[] = [ + { + headers: { + control: 'must-refetch', + }, + }, + ] + + expect(() => mockSubscribeCallback(messages)).toThrow( + 'The server sent a "must-refetch" request, this is incompatible with a D2 pipeline and unresolvable. To handle this you will have to remove all state and start the pipeline again.', + ) + }) + + it('should run graph on up-to-date control message when runOn is up-to-date', () => { + const runSpy = vi.spyOn(d2, 'run') + + electricStreamToD2Input({ + graph: d2, + stream: mockStream, + input, + runOn: 'up-to-date', + }) + + const messages: Message[] = [ + { + headers: { + control: 'up-to-date', + global_last_seen_lsn: 100, + }, + }, + ] + + mockSubscribeCallback(messages) + expect(runSpy).toHaveBeenCalled() + }) + + it('should run graph on lsn advance when runOn is lsn-advance', () => { + const runSpy = vi.spyOn(d2, 'run') + + electricStreamToD2Input({ + graph: d2, + stream: mockStream, + input, + runOn: 'lsn-advance', + }) + + const messages: Message[] = [ + { + headers: { + operation: 'insert', + lsn: 100, + op_position: 1, + last: true, + }, + key: 'test-1', + value: { id: 1 }, + }, + ] + + mockSubscribeCallback(messages) + expect(runSpy).toHaveBeenCalled() + }) + + it('should use initialLsn when provided', () => { + electricStreamToD2Input({ + graph: d2, + stream: mockStream, + input, + initialLsn: 50, + }) + + const messages: Message[] = [ + { + headers: { + operation: 'insert', + lsn: 100, + op_position: 1, + last: true, + }, + key: 'test-1', + value: { id: 1 }, + }, + ] + + mockSubscribeCallback(messages) + expect(input.sendData).toHaveBeenCalledWith(100, expect.any(Array)) + expect(input.sendFrontier).toHaveBeenCalledWith(101) + }) + + it('should handle debug logging when enabled', () => { + const consoleSpy = vi.spyOn(console, 'log') + + electricStreamToD2Input({ + graph: d2, + stream: mockStream, + input, + debug: true, + }) + + const messages: Message[] = [ + { + headers: { + operation: 'insert', + lsn: 100, + op_position: 1, + last: true, + }, + key: 'test-1', + value: { id: 1 }, + }, + ] + + mockSubscribeCallback(messages) + expect(consoleSpy).toHaveBeenCalledWith('subscribing to stream') + expect(consoleSpy).toHaveBeenCalledWith('received 1 messages') + expect(consoleSpy).toHaveBeenCalledWith('- change message: insert') + }) + + it('should handle custom debug logging function', () => { + const customLogger = vi.fn() + + electricStreamToD2Input({ + graph: d2, + stream: mockStream, + input, + debug: customLogger, + }) + + const messages: Message[] = [ + { + headers: { + operation: 'insert', + lsn: 100, + op_position: 1, + last: true, + }, + key: 'test-1', + value: { id: 1 }, + }, + ] + + mockSubscribeCallback(messages) + expect(customLogger).toHaveBeenCalledWith('subscribing to stream') + expect(customLogger).toHaveBeenCalledWith('received 1 messages') + expect(customLogger).toHaveBeenCalledWith('- change message: insert') + }) +}) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ae08d7d..62b13b2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,16 +7,6 @@ settings: importers: .: - dependencies: - '@napi-rs/canvas': - specifier: ^0.1.67 - version: 0.1.67 - canvas: - specifier: ^3.1.0 - version: 3.1.0 - chart.js: - specifier: ^4.4.8 - version: 4.4.8 devDependencies: '@changesets/cli': specifier: ^2.28.1 @@ -52,8 +42,45 @@ importers: specifier: ^1.0.0 version: 1.6.0(@types/node@22.10.2) + examples/electric: + dependencies: + '@electric-sql/client': + specifier: '>=1.0.0-beta.4' + version: 1.0.0-beta.4 + '@electric-sql/d2ts': + specifier: workspace:* + version: link:../../packages/d2ts + '@electric-sql/experimental': + specifier: '>=0.1.2-beta.3' + version: 0.1.2-beta.3(@electric-sql/client@1.0.0-beta.4) + devDependencies: + '@databases/pg': + specifier: ^5.5.0 + version: 5.5.0(typescript@5.7.2) + '@databases/pg-migrations': + specifier: ^5.0.3 + version: 5.0.3(typescript@5.7.2) + '@faker-js/faker': + specifier: ^8.4.1 + version: 8.4.1 + prettier: + specifier: ^3.2.5 + version: 3.4.2 + tsx: + specifier: ^4.7.0 + version: 4.19.2 + typescript: + specifier: ^5.0.0 + version: 5.7.2 + uuid: + specifier: ^9.0.0 + version: 9.0.1 + packages/d2ts: devDependencies: + '@electric-sql/client': + specifier: '>=1.0.0-beta.4' + version: 1.0.0-beta.4 '@types/better-sqlite3': specifier: ^7.6.12 version: 7.6.12 @@ -121,6 +148,14 @@ importers: packages: + '@babel/code-frame@7.26.2': + resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.25.9': + resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} + engines: {node: '>=6.9.0'} + '@babel/runtime@7.26.9': resolution: {integrity: sha512-aA63XwOkcl4xxQa3HjPMqOP6LiK0ZDv3mUPYEFXkpHbaFjtGggE1A61FjFzJnB+p7/oy2gA8E+rcBNl/zC1tMg==} engines: {node: '>=6.9.0'} @@ -180,6 +215,65 @@ packages: '@changesets/write@0.4.0': resolution: {integrity: sha512-CdTLvIOPiCNuH71pyDu3rA+Q0n65cmAbXnwWH84rKGiFumFzkmHNT8KHTMEchcxN+Kl8I54xGUhJ7l3E7X396Q==} + '@databases/connection-pool@1.1.0': + resolution: {integrity: sha512-/12/SNgl0V77mJTo5SX3yGPz4c9XGQwAlCfA0vlfs/0HcaErNpYXpmhj0StET07w6TmTJTnaUgX2EPcQK9ez5A==} + + '@databases/escape-identifier@1.0.3': + resolution: {integrity: sha512-Su36iSVzaHxpVdISVMViUX/32sLvzxVgjZpYhzhotxZUuLo11GVWsiHwqkvUZijTLUxcDmUqEwGJO3O/soLuZA==} + + '@databases/lock@2.1.0': + resolution: {integrity: sha512-ReWnFE5qeCuO2SA5h5fDh/hE/vMolA+Epe6xkAQP1FL2nhnsTCYwN2JACk/kWctR4OQoh0njBjPZ0yfIptclcA==} + + '@databases/migrations-base@3.0.1': + resolution: {integrity: sha512-CutCQ1AjsEWqSuXInD8KwaZYa3/InYGFu3uZ/2pu0Ku4MHRab14+sKNXLk/dxHaJLplngLtCraBo8rL7/21Vhg==} + + '@databases/pg-config@3.2.0': + resolution: {integrity: sha512-hoPAK/F8gLcLgEJ8mLSnNvRlKqShwx5+GglDHIIfQhKF+Zz6M6QceiOefckS4WSjA0x2HClPvpercnXp9i24ag==} + + '@databases/pg-connection-string@1.0.0': + resolution: {integrity: sha512-8czOF9jlv7PlS7BPjnL82ynpDs1t8cu+C2jvdtMr37e8daPKMS7n1KfNE9xtr2Gq4QYKjynep097eYa5yIwcLA==} + + '@databases/pg-data-type-id@3.0.0': + resolution: {integrity: sha512-VqW1csN8pRsWJxjPsGIC9FQ8wyenfmGv0P//BaeDMAu/giM3IXKxKM8fkScUSQ00uqFK/L1iHS5g6dgodF3XzA==} + + '@databases/pg-errors@1.0.0': + resolution: {integrity: sha512-Yz3exbptZwOn4ZD/MSwY6z++XVyOFsMh5DERvSw3awRwJFnfdaqdeiIxxX0MVjM6KPihF0xxp8lPO7vTc5ydpw==} + + '@databases/pg-migrations@5.0.3': + resolution: {integrity: sha512-mUKbVYiACRZJOhE96Y5Fr2IIJ2iBNPVM6L3LgBypH9zIQMOLixGpJ6ZS0oabtNIFJhjncXl5FVEtYaa8x5KkoA==} + hasBin: true + + '@databases/pg@5.5.0': + resolution: {integrity: sha512-WIojK9AYIlNi5YRfc5YUOow3PQ82ClmwT9HG3nEsKLUERYieoVmHMYDQLS0ry6FjgJx+2yFs7LCw4kZpWu1TBw==} + + '@databases/push-to-async-iterable@3.0.0': + resolution: {integrity: sha512-xwu/yNgINdMU+fn6UwFsxh+pa6UrVPafY+0qm0RK0/nKyjllfDqSbwK4gSmdmLEwPYxKwch9CAE3P8NxN1hPSg==} + + '@databases/queue@1.0.1': + resolution: {integrity: sha512-dqRU+/aQ4lhFzjPIkIhjB0+UEKMb76FoBgHOJUTcEblgatr/IhdhHliT3VVwcImXh35Mz297PAXE4yFM4eYWUQ==} + + '@databases/shared@3.1.0': + resolution: {integrity: sha512-bO1DIYAYDiWOCqVPvBio1JqZQYh4dph2M1av2w/REeFT6WBd64mTrOFlcxKV0CUAYT0UiJsDfPqEfw0/APRzWg==} + + '@databases/split-sql-query@1.0.4': + resolution: {integrity: sha512-lDqDQvH34NNjLs0knaDvL6HKgPtishQlDYHfOkvbAd5VQOEhcDvvmG2zbBuFvS2HQAz5NsyLj5erGaxibkxhvQ==} + peerDependencies: + '@databases/sql': '*' + + '@databases/sql@3.3.0': + resolution: {integrity: sha512-vj9huEy4mjJ48GS1Z8yvtMm4BYAnFYACUds25ym6Gd/gsnngkJ17fo62a6mmbNNwCBS/8467PmZR01Zs/06TjA==} + + '@databases/validate-unicode@1.0.0': + resolution: {integrity: sha512-dLKqxGcymeVwEb/6c44KjOnzaAafFf0Wxa8xcfEjx/qOl3rdijsKYBAtIGhtVtOlpPf/PFKfgTuFurSPn/3B/g==} + + '@electric-sql/client@1.0.0-beta.4': + resolution: {integrity: sha512-UKiS0WJHVL91mvcZPPXuUGE9vSFB8zjNuYESUUNKqO+jhaebxwI6e8SHx4nHH1P4RD5hotGGvQNErz8ViB9b7Q==} + + '@electric-sql/experimental@0.1.2-beta.3': + resolution: {integrity: sha512-6NxfKojMD0jS5LGdbjVRdIVSX1Dk+1srUo1vL8Qh3krEz8Sz3YUqGFB2cb/Uqf6hyhOEOzUg+7TJt9RzaUAbiA==} + peerDependencies: + '@electric-sql/client': 1.0.0-beta.4 + '@esbuild/aix-ppc64@0.21.5': resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} engines: {node: '>=12'} @@ -500,6 +594,10 @@ packages: resolution: {integrity: sha512-zSkKow6H5Kdm0ZUQUB2kV5JIXqoG0+uH5YADhaEHswm664N9Db8dXSi0nMJpacpMf+MyyglF1vnZohpEg5yUtg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@faker-js/faker@8.4.1': + resolution: {integrity: sha512-XQ3cU+Q8Uqmrbf2e0cIC/QN43sTBSC8KF12u29Mb47tWrt2hAgBXSgpZMj4Ao8Uk0iJcU99QsOCaIL8934obCg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0, npm: '>=6.14.13'} + '@humanfs/core@0.19.1': resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} engines: {node: '>=18.18.0'} @@ -520,13 +618,36 @@ packages: resolution: {integrity: sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==} engines: {node: '>=18.18'} + '@inquirer/figures@1.0.9': + resolution: {integrity: sha512-BXvGj0ehzrngHTPTDqUoDT3NXL8U0RxUk2zJm2A66RhCEIWdtU1v6GuUqNAgArW4PQ9CinqIWyHdQgdwOj06zQ==} + engines: {node: '>=18'} + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + '@jest/schemas@29.6.3': resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jridgewell/gen-mapping@0.3.8': + resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} + engines: {node: '>=6.0.0'} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + '@jridgewell/sourcemap-codec@1.5.0': resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + '@kurkle/color@0.3.4': resolution: {integrity: sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w==} @@ -536,70 +657,6 @@ packages: '@manypkg/get-packages@1.1.3': resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} - '@napi-rs/canvas-android-arm64@0.1.67': - resolution: {integrity: sha512-W+3DFG5h0WU8Vqqb3W5fNmm5/TPH5ECZRinQDK4CAKFSUkc4iZcDwrmyFG9sB4KdHazf1mFVHCpEeVMO6Mk6Zg==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [android] - - '@napi-rs/canvas-darwin-arm64@0.1.67': - resolution: {integrity: sha512-xzrv7QboI47yhIHR5P5u/9KGswokuOKLiKSukr1Ku03RRJxP6lGuVtrAZAgdRg7F9FsuF2REf2yK53YVb6pMlA==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [darwin] - - '@napi-rs/canvas-darwin-x64@0.1.67': - resolution: {integrity: sha512-SNk9lYBr84N0gW8MZ2IrjygFtbFBILr3SEqMdHzHHuph20SQmssFvJGPZwSSCMEyKAvyqhogbmlew0te5Z4w9Q==} - engines: {node: '>= 10'} - cpu: [x64] - os: [darwin] - - '@napi-rs/canvas-linux-arm-gnueabihf@0.1.67': - resolution: {integrity: sha512-qmBlSvUpl567bzH8tNXi82u5FrL4d0qINqd6K9O7GWGGGFmKMJdrgi2/SW3wwCTxqHBasIDdVWc4KSJfwyaoDQ==} - engines: {node: '>= 10'} - cpu: [arm] - os: [linux] - - '@napi-rs/canvas-linux-arm64-gnu@0.1.67': - resolution: {integrity: sha512-k3nAPQefkMeFuJ65Rqdnx92KX1JXQhEKjjWeKsCJB+7sIBgQUWtHo9c3etfVLv5pkWJJDFi/Zc2soNkH3E8dRA==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - - '@napi-rs/canvas-linux-arm64-musl@0.1.67': - resolution: {integrity: sha512-lZwHWR1cCP408l86n3Qbs3X1oFeAYMjJIQvQl1VMZh6wo5PfI+jaZSKBUOd8x44TnVllX9yhLY9unNRztk/sUQ==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - - '@napi-rs/canvas-linux-riscv64-gnu@0.1.67': - resolution: {integrity: sha512-PdBC9p6bLHA1W3OdA0vTHj701SB/kioGQ1uCFBRMs5KBCaMLb/H4aNi8uaIUIEvBWnxeAjoNcLU7//q0FxEosw==} - engines: {node: '>= 10'} - cpu: [riscv64] - os: [linux] - - '@napi-rs/canvas-linux-x64-gnu@0.1.67': - resolution: {integrity: sha512-kJJX6eWzjipL/LdKOWCJctc88e5yzuXri8+s0V/lN06OwuLGW62TWS3lvi8qlUrGMOfRGabSWWlB4omhASSB8w==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - - '@napi-rs/canvas-linux-x64-musl@0.1.67': - resolution: {integrity: sha512-jLKiPWGeN6ZzhnaLG7ex7eexsiHJ1mdtPK1qKvETIcu45dApMXyUIHvdL6XWB5gFFtj5ScHzLUxv1vkfPZsoxA==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - - '@napi-rs/canvas-win32-x64-msvc@0.1.67': - resolution: {integrity: sha512-K/JmkOFbc4iRZYUqJhj0jwqfHA/wNQEmTiGNsgZ6d59yF/IBNp5T0D5eg3B8ghjI8GxDYCiSJ6DNX8mC3Oh2EQ==} - engines: {node: '>= 10'} - cpu: [x64] - os: [win32] - - '@napi-rs/canvas@0.1.67': - resolution: {integrity: sha512-VA4Khm/5Kg2bQGx3jXotTC4MloOG8b1Ung80exafUK0k5u6yJmIz3Q2iXeeWZs5weV+LQOEB+CPKsYwEYaGAjw==} - engines: {node: '>= 10'} - '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -612,6 +669,10 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + '@pkgr/core@0.1.1': resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} @@ -897,10 +958,18 @@ packages: resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} engines: {node: '>=6'} + ansi-escapes@4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} + ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} + ansi-regex@6.1.0: + resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} + engines: {node: '>=12'} + ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} @@ -909,16 +978,30 @@ packages: resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} engines: {node: '>=10'} + ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + + any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + argparse@1.0.10: resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + array-buffer-byte-length@1.0.2: + resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} + engines: {node: '>= 0.4'} + array-union@2.1.0: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} + assert-never@1.4.0: + resolution: {integrity: sha512-5oJg84os6NMQNl27T9LnZkvvqzvAnHu03ShCnoj6bsJwS7L8AO4lf+C/XjK/nvzEqQB744moC6V128RucQd1jA==} + assertion-error@1.1.0: resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} @@ -930,6 +1013,10 @@ packages: resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} engines: {node: '>=8'} + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -966,6 +1053,18 @@ packages: resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} engines: {node: '>=8'} + call-bind-apply-helpers@1.0.1: + resolution: {integrity: sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==} + engines: {node: '>= 0.4'} + + call-bind@1.0.8: + resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} + engines: {node: '>= 0.4'} + + call-bound@1.0.3: + resolution: {integrity: sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==} + engines: {node: '>= 0.4'} + callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} @@ -1007,6 +1106,22 @@ packages: resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} engines: {node: '>=8'} + cli-cursor@3.1.0: + resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} + engines: {node: '>=8'} + + cli-spinners@2.9.2: + resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} + engines: {node: '>=6'} + + cli-width@4.1.0: + resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} + engines: {node: '>= 12'} + + clone@1.0.4: + resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} + engines: {node: '>=0.8'} + color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} @@ -1014,12 +1129,25 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} confbox@0.1.8: resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} + cosmiconfig@8.3.6: + resolution: {integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==} + engines: {node: '>=14'} + peerDependencies: + typescript: '>=4.9.5' + peerDependenciesMeta: + typescript: + optional: true + cross-spawn@7.0.6: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} @@ -1045,6 +1173,10 @@ packages: resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} engines: {node: '>=6'} + deep-equal@2.2.3: + resolution: {integrity: sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==} + engines: {node: '>= 0.4'} + deep-extend@0.6.0: resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} engines: {node: '>=4.0.0'} @@ -1052,6 +1184,17 @@ packages: deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + defaults@1.0.4: + resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + detect-indent@6.1.0: resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} engines: {node: '>=8'} @@ -1068,9 +1211,19 @@ packages: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + end-of-stream@1.4.4: resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} @@ -1078,9 +1231,27 @@ packages: resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} engines: {node: '>=8.6'} + error-ex@1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-get-iterator@1.1.3: + resolution: {integrity: sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==} + es-module-lexer@1.5.4: resolution: {integrity: sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==} + es-object-atoms@1.0.0: + resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==} + engines: {node: '>= 0.4'} + esbuild@0.21.5: resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} engines: {node: '>=12'} @@ -1232,6 +1403,13 @@ packages: flatted@3.3.2: resolution: {integrity: sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==} + for-each@0.3.3: + resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + + foreground-child@3.3.0: + resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} + engines: {node: '>=14'} + fs-constants@1.0.0: resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} @@ -1248,9 +1426,22 @@ packages: engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + + funtypes@4.2.0: + resolution: {integrity: sha512-DvOtjiKvkeuXGV0O8LQh9quUP3bSOTEQPGv537Sao8kDq2rDbg48UsSJ7wlBLPzR2Mn0pV7cyAiq5pYG1oUyCQ==} + get-func-name@2.0.2: resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} + get-intrinsic@1.2.6: + resolution: {integrity: sha512-qxsEs+9A+u85HhllWJJFicJfPDhRmjzoYdl64aMWW9yRIJmSyxdn8IEkuIM530/7T+lv0TIHd8L6Q/ra0tEoeA==} + engines: {node: '>= 0.4'} + get-stream@8.0.1: resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} engines: {node: '>=16'} @@ -1269,6 +1460,10 @@ packages: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} + glob@10.4.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + hasBin: true + globals@14.0.0: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} @@ -1277,16 +1472,39 @@ packages: resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} engines: {node: '>=10'} + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + has-bigints@1.1.0: + resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} + engines: {node: '>= 0.4'} + has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + human-id@4.1.1: resolution: {integrity: sha512-3gKm/gCSUipeLsRYZbbdA1BD83lBoWUkZ7G9VFrhWPAU76KwYo5KR8V28bpoPm/ygy0x5/GCbpRQdY7VLYCoIg==} hasBin: true @@ -1320,6 +1538,44 @@ packages: ini@1.3.8: resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + inquirer@9.3.7: + resolution: {integrity: sha512-LJKFHCSeIRq9hanN14IlOtPSTe3lNES7TYDTE2xxdAy1LS5rYphajK1qtwvj3YmQXvvk0U2Vbmcni8P9EIQW9w==} + engines: {node: '>=18'} + + internal-slot@1.1.0: + resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} + engines: {node: '>= 0.4'} + + interrogator@2.0.1: + resolution: {integrity: sha512-HPilaDW0ZSPEKhhj6NcklQi7jhYyad1r8l6tS9hYCxvVnlrrJAUMZ7GuGa5PFK3RmquLSk+iml2geBJjC+Yc9g==} + + is-arguments@1.2.0: + resolution: {integrity: sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==} + engines: {node: '>= 0.4'} + + is-array-buffer@3.0.5: + resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} + engines: {node: '>= 0.4'} + + is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + + is-bigint@1.1.0: + resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} + engines: {node: '>= 0.4'} + + is-boolean-object@1.2.1: + resolution: {integrity: sha512-l9qO6eFlUETHtuihLcYOaLKByJ1f+N4kthcU9YjHy3N+B3hWv0y/2Nd0mu/7lTFnRQHTrSdXF50HQ3bl5fEnng==} + engines: {node: '>= 0.4'} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + is-date-object@1.1.0: + resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} + engines: {node: '>= 0.4'} + is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -1332,25 +1588,81 @@ packages: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} + is-interactive@1.0.0: + resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} + engines: {node: '>=8'} + + is-map@2.0.3: + resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} + engines: {node: '>= 0.4'} + + is-number-object@1.1.1: + resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} + engines: {node: '>= 0.4'} + is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} + is-promise@4.0.0: + resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} + + is-regex@1.2.1: + resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} + engines: {node: '>= 0.4'} + + is-set@2.0.3: + resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} + engines: {node: '>= 0.4'} + + is-shared-array-buffer@1.0.4: + resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} + engines: {node: '>= 0.4'} + is-stream@3.0.0: resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + is-string@1.1.1: + resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} + engines: {node: '>= 0.4'} + is-subdir@1.2.0: resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==} engines: {node: '>=4'} + is-symbol@1.1.1: + resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} + engines: {node: '>= 0.4'} + + is-unicode-supported@0.1.0: + resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} + engines: {node: '>=10'} + + is-weakmap@2.0.2: + resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} + engines: {node: '>= 0.4'} + + is-weakset@2.0.4: + resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} + engines: {node: '>= 0.4'} + is-windows@1.0.2: resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} engines: {node: '>=0.10.0'} + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + js-tokens@9.0.0: resolution: {integrity: sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ==} @@ -1365,6 +1677,9 @@ packages: json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} @@ -1384,6 +1699,9 @@ packages: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + local-pkg@0.5.0: resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==} engines: {node: '>=14'} @@ -1405,15 +1723,26 @@ packages: lodash.truncate@4.4.2: resolution: {integrity: sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==} + log-symbols@4.1.0: + resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} + engines: {node: '>=10'} + loupe@2.3.7: resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} loupe@3.1.2: resolution: {integrity: sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==} + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + magic-string@0.30.12: resolution: {integrity: sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==} + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} @@ -1425,6 +1754,10 @@ packages: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} + mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + mimic-fn@4.0.0: resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} engines: {node: '>=12'} @@ -1443,6 +1776,10 @@ packages: minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + mkdirp-classic@0.5.3: resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} @@ -1456,6 +1793,13 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + mute-stream@1.0.0: + resolution: {integrity: sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + nanoid@3.3.7: resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -1478,9 +1822,33 @@ packages: resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-inspect@1.13.3: + resolution: {integrity: sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==} + engines: {node: '>= 0.4'} + + object-is@1.1.6: + resolution: {integrity: sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==} + engines: {node: '>= 0.4'} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + object.assign@4.1.7: + resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} + engines: {node: '>= 0.4'} + once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + onetime@6.0.0: resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} engines: {node: '>=12'} @@ -1489,6 +1857,10 @@ packages: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} + ora@5.4.1: + resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} + engines: {node: '>=10'} + os-tmpdir@1.0.2: resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} engines: {node: '>=0.10.0'} @@ -1528,13 +1900,23 @@ packages: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + package-manager-detector@0.2.9: resolution: {integrity: sha512-+vYvA/Y31l8Zk8dwxHhL3JfTuHPm6tlxM2A3GeQyl7ovYnSp1+mzAxClxaOr0qO1TtPxbQxetI7v5XqKLJZk7Q==} + parameter-reducers@2.1.0: + resolution: {integrity: sha512-aj9V6DUnNbj4YEmVxloPLX9duhklIC+SIOVUrVdaT3WfgEownET+TYg/JsjANQUNGe46dmOCHEKiuycL36cOnw==} + parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} + parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} @@ -1547,6 +1929,10 @@ packages: resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} engines: {node: '>=12'} + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} @@ -1561,6 +1947,45 @@ packages: resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} engines: {node: '>= 14.16'} + pg-cloudflare@1.1.1: + resolution: {integrity: sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==} + + pg-connection-string@2.7.0: + resolution: {integrity: sha512-PI2W9mv53rXJQEOb8xNR8lH7Hr+EKa6oJa38zsK0S/ky2er16ios1wLKhZyxzD7jUReiWokc9WK5nxSnC7W1TA==} + + pg-cursor@2.12.1: + resolution: {integrity: sha512-V13tEaA9Oq1w+V6Q3UBIB/blxJrwbbr35/dY54r/86soBJ7xkP236bXaORUTVXUPt9B6Ql2BQu+uwQiuMfRVgg==} + peerDependencies: + pg: ^8 + + pg-int8@1.0.1: + resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==} + engines: {node: '>=4.0.0'} + + pg-pool@3.7.0: + resolution: {integrity: sha512-ZOBQForurqh4zZWjrgSwwAtzJ7QiRX0ovFkZr2klsen3Nm0aoh33Ls0fzfv3imeH/nw/O27cjdz5kzYJfeGp/g==} + peerDependencies: + pg: '>=8.0' + + pg-protocol@1.7.0: + resolution: {integrity: sha512-hTK/mE36i8fDDhgDFjy6xNOG+LCorxLG3WO17tku+ij6sVHXh1jQUJ8hYAnRhNla4QVD2H8er/FOjc/+EgC6yQ==} + + pg-types@2.2.0: + resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==} + engines: {node: '>=4'} + + pg@8.13.1: + resolution: {integrity: sha512-OUir1A0rPNZlX//c7ksiu7crsGZTKSOXJPgtNiHGIlC9H0lO+NC6ZDYksSgBYY/thSWhnSRBv8w1lieNNGATNQ==} + engines: {node: '>= 8.0.0'} + peerDependencies: + pg-native: '>=3.0.1' + peerDependenciesMeta: + pg-native: + optional: true + + pgpass@1.0.5: + resolution: {integrity: sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==} + picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -1572,13 +1997,37 @@ packages: resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} engines: {node: '>=6'} + pirates@4.0.6: + resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} + engines: {node: '>= 6'} + pkg-types@1.2.1: resolution: {integrity: sha512-sQoqa8alT3nHjGuTjuKgOnvjo4cljkufdtLMnO2LBP/wRwuDlo1tkaEdMxCRhyGRPacv/ztlZgDPm2b7FAmEvw==} + possible-typed-array-names@1.0.0: + resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} + engines: {node: '>= 0.4'} + postcss@8.4.49: resolution: {integrity: sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==} engines: {node: ^10 || ^12 || >=14} + postgres-array@2.0.0: + resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} + engines: {node: '>=4'} + + postgres-bytea@1.0.0: + resolution: {integrity: sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==} + engines: {node: '>=0.10.0'} + + postgres-date@1.0.7: + resolution: {integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==} + engines: {node: '>=0.10.0'} + + postgres-interval@1.2.0: + resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==} + engines: {node: '>=0.10.0'} + prebuild-install@7.1.2: resolution: {integrity: sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==} engines: {node: '>=10'} @@ -1634,6 +2083,10 @@ packages: regenerator-runtime@0.14.1: resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + regexp.prototype.flags@1.5.3: + resolution: {integrity: sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==} + engines: {node: '>= 0.4'} + require-from-string@2.0.2: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} @@ -1649,6 +2102,10 @@ packages: resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + restore-cursor@3.1.0: + resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} + engines: {node: '>=8'} + reusify@1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} @@ -1658,12 +2115,23 @@ packages: engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true + run-async@3.0.0: + resolution: {integrity: sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==} + engines: {node: '>=0.12.0'} + run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + rxjs@7.8.1: + resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==} + safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + safe-regex-test@1.1.0: + resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} + engines: {node: '>= 0.4'} + safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} @@ -1672,6 +2140,14 @@ packages: engines: {node: '>=10'} hasBin: true + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -1680,9 +2156,28 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} + side-channel-list@1.0.0: + resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + signal-exit@4.1.0: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} @@ -1708,6 +2203,10 @@ packages: spawndamnit@3.0.1: resolution: {integrity: sha512-MmnduQUuHCoFckZoWnXsTg7JaiLBJrKFj9UI2MbRPGaJeVpsLcVBu6P/IGZovziM/YBsellCmsprgNA+w0CzVg==} + split2@4.2.0: + resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} + engines: {node: '>= 10.x'} + sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} @@ -1717,10 +2216,18 @@ packages: std-env@3.8.0: resolution: {integrity: sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==} + stop-iteration-iterator@1.1.0: + resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} + engines: {node: '>= 0.4'} + string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} @@ -1728,6 +2235,10 @@ packages: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + strip-bom@3.0.0: resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} engines: {node: '>=4'} @@ -1747,6 +2258,11 @@ packages: strip-literal@2.1.0: resolution: {integrity: sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==} + sucrase@3.35.0: + resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} @@ -1770,6 +2286,13 @@ packages: resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} engines: {node: '>=8'} + thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + + thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + tinybench@2.9.0: resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} @@ -1810,6 +2333,9 @@ packages: peerDependencies: typescript: '>=4.2.0' + ts-interface-checker@0.1.13: + resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} @@ -1829,6 +2355,10 @@ packages: resolution: {integrity: sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==} engines: {node: '>=4'} + type-fest@0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + typescript@5.6.3: resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==} engines: {node: '>=14.17'} @@ -1855,6 +2385,10 @@ packages: util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + uuid@9.0.1: + resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} + hasBin: true + vite-node@1.6.0: resolution: {integrity: sha512-de6HJgzC+TFzOu0NTC4RAIsyf/DY/ibWDYQUcuEA84EMHhcefTUGkjFHKKEJhQN4A+6I0u++kr3l36ZF2d7XRw==} engines: {node: ^18.0.0 || >=20.0.0} @@ -1946,6 +2480,21 @@ packages: jsdom: optional: true + wcwidth@1.0.1: + resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} + + which-boxed-primitive@1.1.1: + resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} + engines: {node: '>= 0.4'} + + which-collection@1.0.2: + resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} + engines: {node: '>= 0.4'} + + which-typed-array@1.1.18: + resolution: {integrity: sha512-qEcY+KJYlWyLH9vNbsr6/5j59AXk5ni5aakf8ldzBvGde6Iz4sxZGkJyWSAueTG7QhOvNRYb1lDdFmL5Td0QKA==} + engines: {node: '>= 0.4'} + which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} @@ -1960,9 +2509,25 @@ packages: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} + wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} @@ -1971,8 +2536,20 @@ packages: resolution: {integrity: sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==} engines: {node: '>=12.20'} + yoctocolors-cjs@2.1.2: + resolution: {integrity: sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==} + engines: {node: '>=18'} + snapshots: + '@babel/code-frame@7.26.2': + dependencies: + '@babel/helper-validator-identifier': 7.25.9 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/helper-validator-identifier@7.25.9': {} + '@babel/runtime@7.26.9': dependencies: regenerator-runtime: 0.14.1 @@ -2119,6 +2696,109 @@ snapshots: human-id: 4.1.1 prettier: 2.8.8 + '@databases/connection-pool@1.1.0': + dependencies: + '@databases/queue': 1.0.1 + is-promise: 4.0.0 + + '@databases/escape-identifier@1.0.3': + dependencies: + '@databases/validate-unicode': 1.0.0 + + '@databases/lock@2.1.0': + dependencies: + '@databases/queue': 1.0.1 + + '@databases/migrations-base@3.0.1': + dependencies: + assert-never: 1.4.0 + chalk: 4.1.2 + deep-equal: 2.2.3 + interrogator: 2.0.1 + is-interactive: 1.0.0 + parameter-reducers: 2.1.0 + semver: 7.6.3 + + '@databases/pg-config@3.2.0(typescript@5.7.2)': + dependencies: + cosmiconfig: 8.3.6(typescript@5.7.2) + funtypes: 4.2.0 + transitivePeerDependencies: + - typescript + + '@databases/pg-connection-string@1.0.0': {} + + '@databases/pg-data-type-id@3.0.0': {} + + '@databases/pg-errors@1.0.0': {} + + '@databases/pg-migrations@5.0.3(typescript@5.7.2)': + dependencies: + '@databases/migrations-base': 3.0.1 + '@databases/pg': 5.5.0(typescript@5.7.2) + '@databases/pg-config': 3.2.0(typescript@5.7.2) + assert-never: 1.4.0 + chalk: 4.1.2 + interrogator: 2.0.1 + is-interactive: 1.0.0 + parameter-reducers: 2.1.0 + semver: 7.6.3 + sucrase: 3.35.0 + transitivePeerDependencies: + - pg-native + - typescript + + '@databases/pg@5.5.0(typescript@5.7.2)': + dependencies: + '@babel/code-frame': 7.26.2 + '@databases/escape-identifier': 1.0.3 + '@databases/pg-config': 3.2.0(typescript@5.7.2) + '@databases/pg-connection-string': 1.0.0 + '@databases/pg-data-type-id': 3.0.0 + '@databases/pg-errors': 1.0.0 + '@databases/push-to-async-iterable': 3.0.0 + '@databases/shared': 3.1.0 + '@databases/split-sql-query': 1.0.4(@databases/sql@3.3.0) + '@databases/sql': 3.3.0 + assert-never: 1.4.0 + pg: 8.13.1 + pg-cursor: 2.12.1(pg@8.13.1) + transitivePeerDependencies: + - pg-native + - typescript + + '@databases/push-to-async-iterable@3.0.0': + dependencies: + '@databases/queue': 1.0.1 + + '@databases/queue@1.0.1': {} + + '@databases/shared@3.1.0': + dependencies: + '@databases/connection-pool': 1.1.0 + '@databases/lock': 2.1.0 + '@databases/queue': 1.0.1 + '@databases/split-sql-query': 1.0.4(@databases/sql@3.3.0) + '@databases/sql': 3.3.0 + + '@databases/split-sql-query@1.0.4(@databases/sql@3.3.0)': + dependencies: + '@databases/sql': 3.3.0 + + '@databases/sql@3.3.0': {} + + '@databases/validate-unicode@1.0.0': {} + + '@electric-sql/client@1.0.0-beta.4': + optionalDependencies: + '@rollup/rollup-darwin-arm64': 4.27.3 + + '@electric-sql/experimental@0.1.2-beta.3(@electric-sql/client@1.0.0-beta.4)': + dependencies: + '@electric-sql/client': 1.0.0-beta.4 + optionalDependencies: + '@rollup/rollup-darwin-arm64': 4.27.3 + '@esbuild/aix-ppc64@0.21.5': optional: true @@ -2303,6 +2983,8 @@ snapshots: dependencies: levn: 0.4.1 + '@faker-js/faker@8.4.1': {} + '@humanfs/core@0.19.1': {} '@humanfs/node@0.16.6': @@ -2316,12 +2998,38 @@ snapshots: '@humanwhocodes/retry@0.4.1': {} + '@inquirer/figures@1.0.9': {} + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + '@jest/schemas@29.6.3': dependencies: '@sinclair/typebox': 0.27.8 + '@jridgewell/gen-mapping@0.3.8': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/set-array@1.2.1': {} + '@jridgewell/sourcemap-codec@1.5.0': {} + '@jridgewell/trace-mapping@0.3.25': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + '@kurkle/color@0.3.4': {} '@manypkg/find-root@1.1.0': @@ -2340,49 +3048,6 @@ snapshots: globby: 11.1.0 read-yaml-file: 1.1.0 - '@napi-rs/canvas-android-arm64@0.1.67': - optional: true - - '@napi-rs/canvas-darwin-arm64@0.1.67': - optional: true - - '@napi-rs/canvas-darwin-x64@0.1.67': - optional: true - - '@napi-rs/canvas-linux-arm-gnueabihf@0.1.67': - optional: true - - '@napi-rs/canvas-linux-arm64-gnu@0.1.67': - optional: true - - '@napi-rs/canvas-linux-arm64-musl@0.1.67': - optional: true - - '@napi-rs/canvas-linux-riscv64-gnu@0.1.67': - optional: true - - '@napi-rs/canvas-linux-x64-gnu@0.1.67': - optional: true - - '@napi-rs/canvas-linux-x64-musl@0.1.67': - optional: true - - '@napi-rs/canvas-win32-x64-msvc@0.1.67': - optional: true - - '@napi-rs/canvas@0.1.67': - optionalDependencies: - '@napi-rs/canvas-android-arm64': 0.1.67 - '@napi-rs/canvas-darwin-arm64': 0.1.67 - '@napi-rs/canvas-darwin-x64': 0.1.67 - '@napi-rs/canvas-linux-arm-gnueabihf': 0.1.67 - '@napi-rs/canvas-linux-arm64-gnu': 0.1.67 - '@napi-rs/canvas-linux-arm64-musl': 0.1.67 - '@napi-rs/canvas-linux-riscv64-gnu': 0.1.67 - '@napi-rs/canvas-linux-x64-gnu': 0.1.67 - '@napi-rs/canvas-linux-x64-musl': 0.1.67 - '@napi-rs/canvas-win32-x64-msvc': 0.1.67 - '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -2395,6 +3060,9 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.17.1 + '@pkgjs/parseargs@0.11.0': + optional: true + '@pkgr/core@0.1.1': {} '@rollup/rollup-android-arm-eabi@4.27.3': @@ -2720,28 +3388,49 @@ snapshots: ansi-colors@4.1.3: {} + ansi-escapes@4.3.2: + dependencies: + type-fest: 0.21.3 + ansi-regex@5.0.1: {} + ansi-regex@6.1.0: {} + ansi-styles@4.3.0: dependencies: color-convert: 2.0.1 ansi-styles@5.2.0: {} + ansi-styles@6.2.1: {} + + any-promise@1.3.0: {} + argparse@1.0.10: dependencies: sprintf-js: 1.0.3 argparse@2.0.1: {} + array-buffer-byte-length@1.0.2: + dependencies: + call-bound: 1.0.3 + is-array-buffer: 3.0.5 + array-union@2.1.0: {} + assert-never@1.4.0: {} + assertion-error@1.1.0: {} assertion-error@2.0.1: {} astral-regex@2.0.0: {} + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.0.0 + balanced-match@1.0.2: {} base64-js@1.5.1: {} @@ -2785,6 +3474,23 @@ snapshots: cac@6.7.14: {} + call-bind-apply-helpers@1.0.1: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bind@1.0.8: + dependencies: + call-bind-apply-helpers: 1.0.1 + es-define-property: 1.0.1 + get-intrinsic: 1.2.6 + set-function-length: 1.2.2 + + call-bound@1.0.3: + dependencies: + call-bind-apply-helpers: 1.0.1 + get-intrinsic: 1.2.6 + callsites@3.1.0: {} canvas@3.1.0: @@ -2831,16 +3537,37 @@ snapshots: ci-info@3.9.0: {} + cli-cursor@3.1.0: + dependencies: + restore-cursor: 3.1.0 + + cli-spinners@2.9.2: {} + + cli-width@4.1.0: {} + + clone@1.0.4: {} + color-convert@2.0.1: dependencies: color-name: 1.1.4 color-name@1.1.4: {} + commander@4.1.1: {} + concat-map@0.0.1: {} confbox@0.1.8: {} + cosmiconfig@8.3.6(typescript@5.7.2): + dependencies: + import-fresh: 3.3.0 + js-yaml: 4.1.0 + parse-json: 5.2.0 + path-type: 4.0.0 + optionalDependencies: + typescript: 5.7.2 + cross-spawn@7.0.6: dependencies: path-key: 3.1.1 @@ -2861,10 +3588,47 @@ snapshots: deep-eql@5.0.2: {} + deep-equal@2.2.3: + dependencies: + array-buffer-byte-length: 1.0.2 + call-bind: 1.0.8 + es-get-iterator: 1.1.3 + get-intrinsic: 1.2.6 + is-arguments: 1.2.0 + is-array-buffer: 3.0.5 + is-date-object: 1.1.0 + is-regex: 1.2.1 + is-shared-array-buffer: 1.0.4 + isarray: 2.0.5 + object-is: 1.1.6 + object-keys: 1.1.1 + object.assign: 4.1.7 + regexp.prototype.flags: 1.5.3 + side-channel: 1.1.0 + which-boxed-primitive: 1.1.1 + which-collection: 1.0.2 + which-typed-array: 1.1.18 + deep-extend@0.6.0: {} deep-is@0.1.4: {} + defaults@1.0.4: + dependencies: + clone: 1.0.4 + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + detect-indent@6.1.0: {} detect-libc@2.0.3: {} @@ -2875,8 +3639,18 @@ snapshots: dependencies: path-type: 4.0.0 + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + + eastasianwidth@0.2.0: {} + emoji-regex@8.0.0: {} + emoji-regex@9.2.2: {} + end-of-stream@1.4.4: dependencies: once: 1.4.0 @@ -2886,8 +3660,32 @@ snapshots: ansi-colors: 4.1.3 strip-ansi: 6.0.1 + error-ex@1.3.2: + dependencies: + is-arrayish: 0.2.1 + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-get-iterator@1.1.3: + dependencies: + call-bind: 1.0.8 + get-intrinsic: 1.2.6 + has-symbols: 1.1.0 + is-arguments: 1.2.0 + is-map: 2.0.3 + is-set: 2.0.3 + is-string: 1.1.1 + isarray: 2.0.5 + stop-iteration-iterator: 1.1.0 + es-module-lexer@1.5.4: {} + es-object-atoms@1.0.0: + dependencies: + es-errors: 1.3.0 + esbuild@0.21.5: optionalDependencies: '@esbuild/aix-ppc64': 0.21.5 @@ -3101,6 +3899,15 @@ snapshots: flatted@3.3.2: {} + for-each@0.3.3: + dependencies: + is-callable: 1.2.7 + + foreground-child@3.3.0: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + fs-constants@1.0.0: {} fs-extra@7.0.1: @@ -3118,8 +3925,27 @@ snapshots: fsevents@2.3.3: optional: true + function-bind@1.1.2: {} + + functions-have-names@1.2.3: {} + + funtypes@4.2.0: {} + get-func-name@2.0.2: {} + get-intrinsic@1.2.6: + dependencies: + call-bind-apply-helpers: 1.0.1 + dunder-proto: 1.0.1 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + function-bind: 1.1.2 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + get-stream@8.0.1: {} get-tsconfig@4.8.1: @@ -3136,6 +3962,15 @@ snapshots: dependencies: is-glob: 4.0.3 + glob@10.4.5: + dependencies: + foreground-child: 3.3.0 + jackspeak: 3.4.3 + minimatch: 9.0.5 + minipass: 7.1.2 + package-json-from-dist: 1.0.1 + path-scurry: 1.11.1 + globals@14.0.0: {} globby@11.1.0: @@ -3147,12 +3982,30 @@ snapshots: merge2: 1.4.1 slash: 3.0.0 + gopd@1.2.0: {} + graceful-fs@4.2.11: {} graphemer@1.4.0: {} + has-bigints@1.1.0: {} + has-flag@4.0.0: {} + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.1 + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + human-id@4.1.1: {} human-signals@5.0.0: {} @@ -3176,6 +4029,60 @@ snapshots: ini@1.3.8: {} + inquirer@9.3.7: + dependencies: + '@inquirer/figures': 1.0.9 + ansi-escapes: 4.3.2 + cli-width: 4.1.0 + external-editor: 3.1.0 + mute-stream: 1.0.0 + ora: 5.4.1 + run-async: 3.0.0 + rxjs: 7.8.1 + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + yoctocolors-cjs: 2.1.2 + + internal-slot@1.1.0: + dependencies: + es-errors: 1.3.0 + hasown: 2.0.2 + side-channel: 1.1.0 + + interrogator@2.0.1: + dependencies: + inquirer: 9.3.7 + + is-arguments@1.2.0: + dependencies: + call-bound: 1.0.3 + has-tostringtag: 1.0.2 + + is-array-buffer@3.0.5: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.3 + get-intrinsic: 1.2.6 + + is-arrayish@0.2.1: {} + + is-bigint@1.1.0: + dependencies: + has-bigints: 1.1.0 + + is-boolean-object@1.2.1: + dependencies: + call-bound: 1.0.3 + has-tostringtag: 1.0.2 + + is-callable@1.2.7: {} + + is-date-object@1.1.0: + dependencies: + call-bound: 1.0.3 + has-tostringtag: 1.0.2 + is-extglob@2.1.1: {} is-fullwidth-code-point@3.0.0: {} @@ -3184,18 +4091,72 @@ snapshots: dependencies: is-extglob: 2.1.1 + is-interactive@1.0.0: {} + + is-map@2.0.3: {} + + is-number-object@1.1.1: + dependencies: + call-bound: 1.0.3 + has-tostringtag: 1.0.2 + is-number@7.0.0: {} + is-promise@4.0.0: {} + + is-regex@1.2.1: + dependencies: + call-bound: 1.0.3 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + is-set@2.0.3: {} + + is-shared-array-buffer@1.0.4: + dependencies: + call-bound: 1.0.3 + is-stream@3.0.0: {} + is-string@1.1.1: + dependencies: + call-bound: 1.0.3 + has-tostringtag: 1.0.2 + is-subdir@1.2.0: dependencies: better-path-resolve: 1.0.0 + is-symbol@1.1.1: + dependencies: + call-bound: 1.0.3 + has-symbols: 1.1.0 + safe-regex-test: 1.1.0 + + is-unicode-supported@0.1.0: {} + + is-weakmap@2.0.2: {} + + is-weakset@2.0.4: + dependencies: + call-bound: 1.0.3 + get-intrinsic: 1.2.6 + is-windows@1.0.2: {} + isarray@2.0.5: {} + isexe@2.0.0: {} + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + js-tokens@4.0.0: {} + js-tokens@9.0.0: {} js-yaml@3.14.1: @@ -3209,6 +4170,8 @@ snapshots: json-buffer@3.0.1: {} + json-parse-even-better-errors@2.3.1: {} + json-schema-traverse@0.4.1: {} json-schema-traverse@1.0.0: {} @@ -3228,6 +4191,8 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 + lines-and-columns@1.2.4: {} + local-pkg@0.5.0: dependencies: mlly: 1.7.3 @@ -3247,16 +4212,25 @@ snapshots: lodash.truncate@4.4.2: {} + log-symbols@4.1.0: + dependencies: + chalk: 4.1.2 + is-unicode-supported: 0.1.0 + loupe@2.3.7: dependencies: get-func-name: 2.0.2 loupe@3.1.2: {} + lru-cache@10.4.3: {} + magic-string@0.30.12: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 + math-intrinsics@1.1.0: {} + merge-stream@2.0.0: {} merge2@1.4.1: {} @@ -3266,6 +4240,8 @@ snapshots: braces: 3.0.3 picomatch: 2.3.1 + mimic-fn@2.1.0: {} + mimic-fn@4.0.0: {} mimic-response@3.1.0: {} @@ -3280,6 +4256,8 @@ snapshots: minimist@1.2.8: {} + minipass@7.1.2: {} + mkdirp-classic@0.5.3: {} mlly@1.7.3: @@ -3293,6 +4271,14 @@ snapshots: ms@2.1.3: {} + mute-stream@1.0.0: {} + + mz@2.7.0: + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + nanoid@3.3.7: {} napi-build-utils@1.0.2: {} @@ -3309,10 +4295,34 @@ snapshots: dependencies: path-key: 4.0.0 + object-assign@4.1.1: {} + + object-inspect@1.13.3: {} + + object-is@1.1.6: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + + object-keys@1.1.1: {} + + object.assign@4.1.7: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.3 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + has-symbols: 1.1.0 + object-keys: 1.1.1 + once@1.4.0: dependencies: wrappy: 1.0.2 + onetime@5.1.2: + dependencies: + mimic-fn: 2.1.0 + onetime@6.0.0: dependencies: mimic-fn: 4.0.0 @@ -3326,6 +4336,18 @@ snapshots: type-check: 0.4.0 word-wrap: 1.2.5 + ora@5.4.1: + dependencies: + bl: 4.1.0 + chalk: 4.1.2 + cli-cursor: 3.1.0 + cli-spinners: 2.9.2 + is-interactive: 1.0.0 + is-unicode-supported: 0.1.0 + log-symbols: 4.1.0 + strip-ansi: 6.0.1 + wcwidth: 1.0.1 + os-tmpdir@1.0.2: {} outdent@0.5.0: {} @@ -3358,18 +4380,34 @@ snapshots: p-try@2.2.0: {} + package-json-from-dist@1.0.1: {} + package-manager-detector@0.2.9: {} + parameter-reducers@2.1.0: {} + parent-module@1.0.1: dependencies: callsites: 3.1.0 + parse-json@5.2.0: + dependencies: + '@babel/code-frame': 7.26.2 + error-ex: 1.3.2 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + path-exists@4.0.0: {} path-key@3.1.1: {} path-key@4.0.0: {} + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.2 + path-type@4.0.0: {} pathe@1.1.2: {} @@ -3378,24 +4416,77 @@ snapshots: pathval@2.0.0: {} + pg-cloudflare@1.1.1: + optional: true + + pg-connection-string@2.7.0: {} + + pg-cursor@2.12.1(pg@8.13.1): + dependencies: + pg: 8.13.1 + + pg-int8@1.0.1: {} + + pg-pool@3.7.0(pg@8.13.1): + dependencies: + pg: 8.13.1 + + pg-protocol@1.7.0: {} + + pg-types@2.2.0: + dependencies: + pg-int8: 1.0.1 + postgres-array: 2.0.0 + postgres-bytea: 1.0.0 + postgres-date: 1.0.7 + postgres-interval: 1.2.0 + + pg@8.13.1: + dependencies: + pg-connection-string: 2.7.0 + pg-pool: 3.7.0(pg@8.13.1) + pg-protocol: 1.7.0 + pg-types: 2.2.0 + pgpass: 1.0.5 + optionalDependencies: + pg-cloudflare: 1.1.1 + + pgpass@1.0.5: + dependencies: + split2: 4.2.0 + picocolors@1.1.1: {} picomatch@2.3.1: {} pify@4.0.1: {} + pirates@4.0.6: {} + pkg-types@1.2.1: dependencies: confbox: 0.1.8 mlly: 1.7.3 pathe: 1.1.2 + possible-typed-array-names@1.0.0: {} + postcss@8.4.49: dependencies: nanoid: 3.3.7 picocolors: 1.1.1 source-map-js: 1.2.1 + postgres-array@2.0.0: {} + + postgres-bytea@1.0.0: {} + + postgres-date@1.0.7: {} + + postgres-interval@1.2.0: + dependencies: + xtend: 4.0.2 + prebuild-install@7.1.2: dependencies: detect-libc: 2.0.3 @@ -3460,6 +4551,13 @@ snapshots: regenerator-runtime@0.14.1: {} + regexp.prototype.flags@1.5.3: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-errors: 1.3.0 + set-function-name: 2.0.2 + require-from-string@2.0.2: {} resolve-from@4.0.0: {} @@ -3468,6 +4566,11 @@ snapshots: resolve-pkg-maps@1.0.0: {} + restore-cursor@3.1.0: + dependencies: + onetime: 5.1.2 + signal-exit: 3.0.7 + reusify@1.0.4: {} rollup@4.27.3: @@ -3494,24 +4597,82 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.27.3 fsevents: 2.3.3 + run-async@3.0.0: {} + run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 + rxjs@7.8.1: + dependencies: + tslib: 2.8.1 + safe-buffer@5.2.1: {} + safe-regex-test@1.1.0: + dependencies: + call-bound: 1.0.3 + es-errors: 1.3.0 + is-regex: 1.2.1 + safer-buffer@2.1.2: {} semver@7.6.3: {} + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.6 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + + set-function-name@2.0.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 shebang-regex@3.0.0: {} + side-channel-list@1.0.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.3 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.3 + es-errors: 1.3.0 + get-intrinsic: 1.2.6 + object-inspect: 1.13.3 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.3 + es-errors: 1.3.0 + get-intrinsic: 1.2.6 + object-inspect: 1.13.3 + side-channel-map: 1.0.1 + + side-channel@1.1.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.3 + side-channel-list: 1.0.0 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + siginfo@2.0.0: {} + signal-exit@3.0.7: {} + signal-exit@4.1.0: {} simple-concat@1.0.1: {} @@ -3537,18 +4698,31 @@ snapshots: cross-spawn: 7.0.6 signal-exit: 4.1.0 + split2@4.2.0: {} + sprintf-js@1.0.3: {} stackback@0.0.2: {} std-env@3.8.0: {} + stop-iteration-iterator@1.1.0: + dependencies: + es-errors: 1.3.0 + internal-slot: 1.1.0 + string-width@4.2.3: dependencies: emoji-regex: 8.0.0 is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + string_decoder@1.3.0: dependencies: safe-buffer: 5.2.1 @@ -3557,6 +4731,10 @@ snapshots: dependencies: ansi-regex: 5.0.1 + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.1.0 + strip-bom@3.0.0: {} strip-final-newline@3.0.0: {} @@ -3569,6 +4747,16 @@ snapshots: dependencies: js-tokens: 9.0.0 + sucrase@3.35.0: + dependencies: + '@jridgewell/gen-mapping': 0.3.8 + commander: 4.1.1 + glob: 10.4.5 + lines-and-columns: 1.2.4 + mz: 2.7.0 + pirates: 4.0.6 + ts-interface-checker: 0.1.13 + supports-color@7.2.0: dependencies: has-flag: 4.0.0 @@ -3603,6 +4791,14 @@ snapshots: term-size@2.2.1: {} + thenify-all@1.6.0: + dependencies: + thenify: 3.3.1 + + thenify@3.3.1: + dependencies: + any-promise: 1.3.0 + tinybench@2.9.0: {} tinyexec@0.3.1: {} @@ -3633,6 +4829,8 @@ snapshots: dependencies: typescript: 5.7.2 + ts-interface-checker@0.1.13: {} + tslib@2.8.1: {} tsx@4.19.2: @@ -3652,6 +4850,8 @@ snapshots: type-detect@4.1.0: {} + type-fest@0.21.3: {} + typescript@5.6.3: {} typescript@5.7.2: {} @@ -3668,6 +4868,8 @@ snapshots: util-deprecate@1.0.2: {} + uuid@9.0.1: {} + vite-node@1.6.0(@types/node@22.10.2): dependencies: cac: 6.7.14 @@ -3782,6 +4984,34 @@ snapshots: - supports-color - terser + wcwidth@1.0.1: + dependencies: + defaults: 1.0.4 + + which-boxed-primitive@1.1.1: + dependencies: + is-bigint: 1.1.0 + is-boolean-object: 1.2.1 + is-number-object: 1.1.1 + is-string: 1.1.1 + is-symbol: 1.1.1 + + which-collection@1.0.2: + dependencies: + is-map: 2.0.3 + is-set: 2.0.3 + is-weakmap: 2.0.2 + is-weakset: 2.0.4 + + which-typed-array@1.1.18: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.3 + for-each: 0.3.3 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + which@2.0.2: dependencies: isexe: 2.0.0 @@ -3793,8 +5023,30 @@ snapshots: word-wrap@1.2.5: {} + wrap-ansi@6.2.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 + wrappy@1.0.2: {} + xtend@4.0.2: {} + yocto-queue@0.1.0: {} yocto-queue@1.1.1: {} + + yoctocolors-cjs@2.1.2: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index ca0f302..1598933 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,2 +1,3 @@ packages: - - 'packages/*' \ No newline at end of file + - 'packages/*' + - 'examples/*'