diff --git a/flake.lock b/flake.lock index 92423c8f..84caf4ca 100644 --- a/flake.lock +++ b/flake.lock @@ -11,11 +11,11 @@ "pre-commit-hooks": "pre-commit-hooks" }, "locked": { - "lastModified": 1706702107, - "narHash": "sha256-/W0lQqK46vzNz2X8A3H+iAYIYYohrxGCTda6jFftSrg=", + "lastModified": 1708704632, + "narHash": "sha256-w+dOIW60FKMaHI1q5714CSibk99JfYxm0CzTinYWr+Q=", "owner": "cachix", "repo": "devenv", - "rev": "3b06272eab2f0e1160074d99cef07260a9dec871", + "rev": "2ee4450b0f4b95a1b90f2eb5ffea98b90e48c196", "type": "github" }, "original": { @@ -98,11 +98,11 @@ "systems": "systems_3" }, "locked": { - "lastModified": 1705309234, - "narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=", + "lastModified": 1709126324, + "narHash": "sha256-q6EQdSeUZOG26WelxqkmR7kArjgWCdw5sfJVHPH/7j8=", "owner": "numtide", "repo": "flake-utils", - "rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26", + "rev": "d465f4819400de7c8d874d50b982301f28a84605", "type": "github" }, "original": { @@ -133,26 +133,9 @@ "type": "github" } }, - "lowdown-src": { - "flake": false, - "locked": { - "lastModified": 1633514407, - "narHash": "sha256-Dw32tiMjdK9t3ETl5fzGrutQTzh2rufgZV4A/BbxuD4=", - "owner": "kristapsdz", - "repo": "lowdown", - "rev": "d2c2b44ff6c27b936ec27358a2653caaef8f73b8", - "type": "github" - }, - "original": { - "owner": "kristapsdz", - "repo": "lowdown", - "type": "github" - } - }, "nix": { "inputs": { "flake-compat": "flake-compat_2", - "lowdown-src": "lowdown-src", "nixpkgs": [ "devenv", "nixpkgs" @@ -160,16 +143,16 @@ "nixpkgs-regression": "nixpkgs-regression" }, "locked": { - "lastModified": 1692895818, - "narHash": "sha256-lfIz37c24QpkwAHJCDHrDNtQyMBdxq7RWG5sojbtARU=", + "lastModified": 1708577783, + "narHash": "sha256-92xq7eXlxIT5zFNccLpjiP7sdQqQI30Gyui2p/PfKZM=", "owner": "domenkozar", "repo": "nix", - "rev": "ca8a41cfc176dc7adad02ab756f6faef6e90ff1f", + "rev": "ecd0af0c1f56de32cbad14daa1d82a132bf298f8", "type": "github" }, "original": { "owner": "domenkozar", - "ref": "devenv-2.17", + "ref": "devenv-2.21", "repo": "nix", "type": "github" } @@ -198,11 +181,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1706913249, - "narHash": "sha256-x3M7iV++CsvRXI1fpyFPduGELUckZEhSv0XWnUopAG8=", + "lastModified": 1709703039, + "narHash": "sha256-6hqgQ8OK6gsMu1VtcGKBxKQInRLHtzulDo9Z5jxHEFY=", "owner": "nixos", "repo": "nixpkgs", - "rev": "e92b6015881907e698782c77641aa49298330223", + "rev": "9df3e30ce24fd28c7b3e2de0d986769db5d6225d", "type": "github" }, "original": { diff --git a/package.json b/package.json index 65924cf4..23e51e77 100644 --- a/package.json +++ b/package.json @@ -8,12 +8,12 @@ "devDependencies": { "@snaplet/eslint-config": "workspace:*", "@snaplet/tsconfig": "workspace:*", - "eslint": "8.56.0", - "knip": "5.0.1", - "skott": "0.32.1", - "turbo": "1.12.4", - "typescript": "5.3.3", - "vitest": "1.2.2" + "eslint": "8.57.0", + "knip": "5.0.3", + "skott": "0.33.0", + "turbo": "1.12.5", + "typescript": "5.4.2", + "vitest": "1.3.1" }, "scripts": { "build": "turbo run build", diff --git a/packages/eslint-config/package.json b/packages/eslint-config/package.json index bf3a68be..d2c11c86 100644 --- a/packages/eslint-config/package.json +++ b/packages/eslint-config/package.json @@ -9,13 +9,13 @@ } }, "dependencies": { - "@typescript-eslint/eslint-plugin": "7.0.1", - "@typescript-eslint/parser": "7.0.1", - "eslint": "8.56.0", + "@typescript-eslint/eslint-plugin": "7.1.1", + "@typescript-eslint/parser": "7.1.1", + "eslint": "8.57.0", "eslint-config-prettier": "9.1.0", "eslint-plugin-i": "2.29.1", "eslint-plugin-node-import": "1.0.4", - "eslint-plugin-perfectionist": "2.5.0", + "eslint-plugin-perfectionist": "2.6.0", "eslint-plugin-prettier": "5.1.3", "eslint-plugin-unused-imports": "3.1.0", "eslint-plugin-vitest": "0.3.22", @@ -23,6 +23,6 @@ "prettier": "3.2.5" }, "devDependencies": { - "@types/eslint": "8.56.2" + "@types/eslint": "8.56.5" } } \ No newline at end of file diff --git a/packages/seed/package.json b/packages/seed/package.json index 0c8f12e2..1cac6c55 100644 --- a/packages/seed/package.json +++ b/packages/seed/package.json @@ -41,39 +41,39 @@ "@total-typescript/ts-reset": "0.5.1", "@types/better-sqlite3": "7.6.9", "@types/fs-extra": "11.0.4", - "@types/node": "20.11.18", - "@types/pg": "8.11.0", + "@types/node": "20.11.25", + "@types/pg": "8.11.2", "@types/tmp": "0.2.6", "@types/uuid": "9.0.8", "@types/yargs": "17.0.32", "better-sqlite3": "9.4.3", - "eslint": "8.56.0", + "eslint": "8.57.0", "execa": "8.0.1", "fs-extra": "11.2.0", "postgres": "3.4.3", "tmp-promise": "3.0.3", "tsx": "4.7.1", - "typescript": "5.3.3", + "typescript": "5.4.2", "uuid": "9.0.1", - "vitest": "1.2.2" + "vitest": "1.3.1" }, "peerDependencies": { "@snaplet/copycat": ">=2.0.0", "drizzle-orm": "^0.29.3" }, "dependencies": { - "@babel/types": "7.23.9", + "@babel/types": "7.24.0", "@scaleleap/pg-format": "^1.0.0", "@trpc/client": "10.45.1", "@trpc/server": "10.45.1", - "c12": "1.8.0", + "c12": "1.10.0", "find-up": "7.0.0", "inflection": "^3.0.0", "javascript-stringify": "2.1.0", "json-schema-library": "9.1.3", "ora": "8.0.1", - "quicktype-core": "^23.0.104", - "remeda": "^1.41.0", + "quicktype-core": "^23.0.105", + "remeda": "^1.47.0", "yargs": "^17.7.2", "zod": "3.22.4" }, diff --git a/packages/seed/src/core/codegen/codegen.ts b/packages/seed/src/core/codegen/codegen.ts index ba20b057..be0d19a2 100644 --- a/packages/seed/src/core/codegen/codegen.ts +++ b/packages/seed/src/core/codegen/codegen.ts @@ -2,10 +2,10 @@ import { findUp } from "find-up"; import { mkdirp } from "fs-extra/esm"; import { writeFile } from "node:fs/promises"; import path from "node:path"; -import { type DataModel } from "#core/dataModel/types.js"; -import { type Dialect } from "#core/dialect/types.js"; -import { type Fingerprint } from "#core/fingerprint/types.js"; import { type TableShapePredictions } from "#trpc/shapes.js"; +import { type DataModel } from "../dataModel/types.js"; +import { type Dialect } from "../dialect/types.js"; +import { type Fingerprint } from "../fingerprint/types.js"; import { generateUserModels } from "./userModels/generateUserModels.js"; export interface CodegenContext { diff --git a/packages/seed/src/core/codegen/userModels/generateUserModels.ts b/packages/seed/src/core/codegen/userModels/generateUserModels.ts index 6b52d231..7ea3210d 100644 --- a/packages/seed/src/core/codegen/userModels/generateUserModels.ts +++ b/packages/seed/src/core/codegen/userModels/generateUserModels.ts @@ -1,18 +1,18 @@ import { stringify } from "javascript-stringify"; -import { type CodegenContext } from "#core/codegen/codegen.js"; +import { type Shape, type TableShapePredictions } from "#trpc/shapes.js"; +import { type CodegenContext } from "../../codegen/codegen.js"; +import { shouldGenerateFieldValue } from "../../dataModel/shouldGenerateFieldValue.js"; import { type DataModel, type DataModelField, type DataModelModel, type DataModelScalarField, -} from "#core/dataModel/types.js"; -import { type Dialect } from "#core/dialect/types.js"; -import { isJsonField } from "#core/fingerprint/fingerprint.js"; -import { type Fingerprint } from "#core/fingerprint/types.js"; -import { generateCodeFromTemplate } from "#core/userModels/templates/codegen.js"; -import { type UserModels } from "#core/userModels/types.js"; -import { type Shape, type TableShapePredictions } from "#trpc/shapes.js"; -import { shouldGenerateFieldValue } from "../../dataModel/shouldGenerateFieldValue.js"; +} from "../../dataModel/types.js"; +import { type Dialect } from "../../dialect/types.js"; +import { isJsonField } from "../../fingerprint/fingerprint.js"; +import { type Fingerprint } from "../../fingerprint/types.js"; +import { generateCodeFromTemplate } from "../../userModels/templates/codegen.js"; +import { type UserModels } from "../../userModels/types.js"; import { generateJsonField } from "./generateJsonField.js"; export const SHAPE_PREDICTION_CONFIDENCE_THRESHOLD = 0.65; diff --git a/packages/seed/src/core/dialect/getDialect.ts b/packages/seed/src/core/dialect/getDialect.ts index a03da1c0..780a476f 100644 --- a/packages/seed/src/core/dialect/getDialect.ts +++ b/packages/seed/src/core/dialect/getDialect.ts @@ -1,4 +1,4 @@ -import { type DataModel } from "#core/dataModel/types.js"; +import { type DataModel } from "../dataModel/types.js"; import { type Dialect } from "./types.js"; export const getDialect = async ( diff --git a/packages/seed/src/core/dialect/types.ts b/packages/seed/src/core/dialect/types.ts index 988a7377..8c88b612 100644 --- a/packages/seed/src/core/dialect/types.ts +++ b/packages/seed/src/core/dialect/types.ts @@ -1,7 +1,7 @@ -import { type DataModel } from "#core/dataModel/types.js"; -import { type Fingerprint } from "#core/fingerprint/types.js"; -import { type Templates } from "#core/userModels/templates/types.js"; import { type Shape } from "#trpc/shapes.js"; +import { type DataModel } from "../dataModel/types.js"; +import { type Fingerprint } from "../fingerprint/types.js"; +import { type Templates } from "../userModels/templates/types.js"; export type NestedType = string; diff --git a/packages/seed/src/core/plan/plan.ts b/packages/seed/src/core/plan/plan.ts index 11e2779a..25eed63e 100644 --- a/packages/seed/src/core/plan/plan.ts +++ b/packages/seed/src/core/plan/plan.ts @@ -1,8 +1,8 @@ import { copycat } from "@snaplet/copycat"; -import { shouldGenerateFieldValue } from "#core/dataModel/shouldGenerateFieldValue.js"; import { type ClientState } from "../client/types.js"; import { serializeModelValues, serializeValue } from "../data/data.js"; import { type Json } from "../data/types.js"; +import { shouldGenerateFieldValue } from "../dataModel/shouldGenerateFieldValue.js"; import { type DataModel, type DataModelObjectField, diff --git a/packages/seed/src/core/sequences/updateDataModelSequences.ts b/packages/seed/src/core/sequences/updateDataModelSequences.ts index d83521f3..76af14c3 100644 --- a/packages/seed/src/core/sequences/updateDataModelSequences.ts +++ b/packages/seed/src/core/sequences/updateDataModelSequences.ts @@ -4,7 +4,7 @@ import { type DataModelField, type DataModelModel, type DataModelScalarField, -} from "#core/dataModel/types.js"; +} from "../dataModel/types.js"; export function updateDataModelSequences( currentDataModel: DataModel, diff --git a/packages/seed/src/core/store/store.ts b/packages/seed/src/core/store/store.ts index eb1faeda..fefaf8e4 100644 --- a/packages/seed/src/core/store/store.ts +++ b/packages/seed/src/core/store/store.ts @@ -1,5 +1,25 @@ -import { type DataModel } from "../dataModel/types.js"; +import { EOL } from "node:os"; +import { + type DataModel, + type DataModelModel, + type DataModelObjectField, + type DataModelScalarField, +} from "../dataModel/types.js"; +import { groupFields } from "../dataModel/utils.js"; import { type ModelData } from "../plan/types.js"; +import { sortModels } from "./topologicalSort.js"; + +type SerializeInsertStatement = (props: { + columns: Array; + model: DataModelModel; + values: Array; +}) => string; + +type SerializeUpdateStatement = (props: { + filterData: Array<[string, unknown]>; + model: DataModelModel; + updateData: Array<[string, unknown]>; +}) => string; export interface Store { _store: Record>; @@ -7,6 +27,8 @@ export interface Store { toSQL(): Array; } +export const SQL_DEFAULT_SYMBOL = "$$DEFAULT$$"; + export abstract class StoreBase implements Store { _store: Record>; public readonly dataModel: DataModel; @@ -18,9 +40,230 @@ export abstract class StoreBase implements Store { ); } + protected _toSQL(props: { + getEndStatements?: (model: DataModelModel) => Array; + serializeInsertStatement: SerializeInsertStatement; + serializeUpdateStatement: SerializeUpdateStatement; + }): Array { + const endStatements: Array = []; + const inserted: Record> = Object.fromEntries( + Object.keys(this.dataModel.models).map( + (modelName) => [modelName, []] as [string, Array], + ), + ); + const pending: Record> = Object.fromEntries( + Object.keys(this.dataModel.models).map( + (modelName) => [modelName, []] as [string, Array], + ), + ); + const insertStatements: Array = []; + const updateStatements: Array = []; + + const sortedModels = sortModels(this.dataModel); + for (const entry of sortedModels) { + const model = entry.node as DataModelModel & { modelName: string }; + const rows = this._store[model.modelName]; + if (rows.length === 0) { + continue; + } + + for (const [i] of rows.entries()) { + createStatements({ + serializeInsertStatement: props.serializeInsertStatement, + serializeUpdateStatement: props.serializeUpdateStatement, + modelName: model.modelName, + rowId: i, + row: rows[i], + dataModel: this.dataModel, + inserted, + pending, + insertStatements, + updateStatements, + store: this._store, + }); + } + + if (props.getEndStatements) { + endStatements.push(...props.getEndStatements(model)); + } + } + + return [...insertStatements, ...updateStatements, ...endStatements]; + } + add(model: string, value: ModelData) { this._store[model].push(value); } abstract toSQL(): Array; } + +function createStatements(ctx: { + dataModel: DataModel; + insertStatements: Array; + inserted: Record>; + modelName: string; + pending: Record>; + row: ModelData; + rowId: number; + serializeInsertStatement: SerializeInsertStatement; + serializeUpdateStatement: SerializeUpdateStatement; + store: Store["_store"]; + updateStatements: Array; +}) { + const model = ctx.dataModel.models[ctx.modelName]; + + // check if the row has already been inserted + const isRowInserted = ctx.inserted[ctx.modelName].includes(ctx.rowId); + if (isRowInserted) { + return; + } + + // mark the row as pending + ctx.pending[ctx.modelName].push(ctx.rowId); + + const { parents } = groupFields(model.fields); + + const updatableParents = [] as Array; + + for (const parent of parents) { + const parentIdFields = [] as Array<[string, ModelData]>; + for (const [i] of parent.relationFromFields.entries()) { + parentIdFields.push([ + parent.relationToFields[i], + ctx.row[parent.relationFromFields[i]], + ] as [string, ModelData]); + } + + // if the parent is not set or null, we can skip it + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + if (parentIdFields.every(([, v]) => v === null || v === undefined)) { + continue; + } + + const parentRowId = ctx.store[parent.type].findIndex((r) => + parentIdFields.every(([k, v]) => r[k] === v), + ); + + // external data, no need to create a statement + if (parentRowId === -1) { + continue; + } + + const parentRow = ctx.store[parent.type][parentRowId]; + // if the row is pending, we have a circular dependency + // we know that the parent will be created earlier in the pending chain, so we can skip this one + // and set the parent's id to NULL at insertion time + // do we need to keep track of the exact chain of parents? + if (ctx.pending[parent.type].includes(parentRowId)) { + if (parent.isRequired) { + throw new Error( + [ + `Circular dependency detected for model ${parent.type} for row ${JSON.stringify(parentRow)}`, + `Pending context:`, + JSON.stringify( + ctx.pending[parent.type].map( + () => ctx.store[parent.type][parentRowId], + ), + ), + ].join(EOL), + ); + } else { + updatableParents.push(parent); + continue; + } + } + + // create the parent statement + createStatements({ + ...ctx, + modelName: parent.type, + row: parentRow, + rowId: parentRowId, + }); + } + + // create the statements for the current model + const { insertStatement, updateStatement } = getStatements({ + model, + row: ctx.row, + updatableParents, + serializeInsertStatement: ctx.serializeInsertStatement, + serializeUpdateStatement: ctx.serializeUpdateStatement, + }); + + ctx.insertStatements.push(insertStatement); + if (updateStatement !== null) { + ctx.updateStatements.push(updateStatement); + } + + // remove the row from pending and add it to inserted + ctx.pending[ctx.modelName] = ctx.pending[ctx.modelName].filter( + (r) => r !== ctx.rowId, + ); + ctx.inserted[ctx.modelName].push(ctx.rowId); +} + +function getStatements(props: { + model: DataModelModel; + row: ModelData; + serializeInsertStatement: SerializeInsertStatement; + serializeUpdateStatement: SerializeUpdateStatement; + updatableParents: Array; +}) { + const insertableFields = props.model.fields.filter( + (f) => f.kind === "scalar" && !(f.isGenerated && !f.isId), + ) as Array; + + const insertStatement = props.serializeInsertStatement({ + model: props.model, + columns: insertableFields.map((f) => f.columnName), + values: insertableFields.map((f) => { + // check if the field is part of the updatable parents + if ( + props.updatableParents.some((p) => + p.relationFromFields.includes(f.name), + ) + ) { + return null; + } + if (f.hasDefaultValue && props.row[f.name] === undefined) { + return SQL_DEFAULT_SYMBOL; + } + return props.row[f.name]; + }), + }); + + let updateStatement = null; + if (props.updatableParents.length > 0) { + const updateData = props.updatableParents.flatMap((p) => { + return p.relationFromFields.map((f) => { + const column = ( + props.model.fields.find( + (field) => field.name === f, + ) as DataModelScalarField + ).columnName; + const value = props.row[f]; + return [column, value] as [string, unknown]; + }); + }); + const filterData = props.model.fields + .filter((f) => f.isId) + .map((f) => { + const idColumn = ( + props.model.fields.find( + (field) => field.name === f.name, + ) as DataModelScalarField + ).columnName; + const idValue = props.row[f.name]; + return [idColumn, idValue] as [string, unknown]; + }); + updateStatement = props.serializeUpdateStatement({ + model: props.model, + filterData, + updateData, + }); + } + + return { insertStatement, updateStatement }; +} diff --git a/packages/seed/src/core/userModels/templates/codegen.ts b/packages/seed/src/core/userModels/templates/codegen.ts index efdf1431..e4e1c573 100644 --- a/packages/seed/src/core/userModels/templates/codegen.ts +++ b/packages/seed/src/core/userModels/templates/codegen.ts @@ -1,6 +1,6 @@ -import { type NestedType } from "#core/dialect/types.js"; -import { unpackNestedType } from "#core/dialect/unpackNestedType.js"; import { type Shape } from "#trpc/shapes.js"; +import { type NestedType } from "../../dialect/types.js"; +import { unpackNestedType } from "../../dialect/unpackNestedType.js"; import { type TemplateContext, type TemplateFn, diff --git a/packages/seed/src/core/userModels/templates/copycat.ts b/packages/seed/src/core/userModels/templates/copycat.ts index 9e0cc547..93938153 100644 --- a/packages/seed/src/core/userModels/templates/copycat.ts +++ b/packages/seed/src/core/userModels/templates/copycat.ts @@ -1,5 +1,5 @@ import { type copycat } from "@snaplet/copycat"; -import { type Json } from "#core/data/types.js"; +import { type Json } from "../../data/types.js"; import { type TemplateContext, type TemplateFn } from "./types.js"; type Copycat = typeof copycat; diff --git a/packages/seed/src/dialects/postgres/store.test.ts b/packages/seed/src/dialects/postgres/store.test.ts index a4fc65fe..39626f3f 100644 --- a/packages/seed/src/dialects/postgres/store.test.ts +++ b/packages/seed/src/dialects/postgres/store.test.ts @@ -253,5 +253,539 @@ describe.each(["postgresJs"] as const)("store: %s", (adapter) => { ]), ); }); + test("should handle auto circular references", async () => { + const structure = ` + create table customer ( + id serial primary key, + name text not null, + referrer_id integer references customer(id) + ); + `; + + const db = await createTestDb(structure); + const orm = createDrizzleORMPgClient(drizzle(db.client)); + const dataModel = await getDatamodel(orm); + + const store = new PgStore(dataModel); + + store.add("customer", { + id: 1, + name: "John Doe", + referrer_id: 2, + }); + + store.add("customer", { + id: 2, + name: "Jane Doe", + referrer_id: 1, + }); + + await execQueries(orm, [...store.toSQL()]); + const results = await orm.query(`select * from customer order by id asc`); + + expect(results).toEqual( + expect.arrayContaining([ + { + id: 1, + name: "John Doe", + referrer_id: 2, + }, + { + id: 2, + name: "Jane Doe", + referrer_id: 1, + }, + ]), + ); + }); + test("should handle complex circular references", async () => { + const structure = ` + create table customer ( + id serial primary key, + name text not null, + last_order_id integer + ); + + create table product ( + id serial primary key, + name text not null, + first_order_id integer + ); + + create table "order" ( + id serial primary key, + customer_id integer not null, + product_id integer not null, + quantity integer not null, + CONSTRAINT fk_customer + FOREIGN KEY(customer_id) + REFERENCES customer(id), + CONSTRAINT fk_product + FOREIGN KEY(product_id) + REFERENCES product(id) + ); + -- Add constraints to customer and product tables + alter table customer add constraint fk_last_order + foreign key (last_order_id) references "order"(id); + + alter table product add constraint fk_first_order + foreign key (first_order_id) references "order"(id); + `; + + const db = await createTestDb(structure); + const orm = createDrizzleORMPgClient(drizzle(db.client)); + const dataModel = await getDatamodel(orm); + + const store = new PgStore(dataModel); + + // Assume IDs are auto-generated correctly and linked properly + store.add("product", { + id: 1, + name: "Gadget", + first_order_id: 1, // This will be updated later after creating the order + }); + + store.add("customer", { + id: 1, + name: "John Doe", + last_order_id: 1, // This will be updated later after creating the order + }); + + store.add("order", { + id: 1, + customer_id: 1, + product_id: 1, + quantity: 10, + }); + + await execQueries(orm, [...store.toSQL()]); + + const customerResults = await orm.query( + `select * from customer order by id asc`, + ); + const orderResults = await orm.query( + `select * from "order" order by id asc`, + ); + const productResults = await orm.query( + `select * from product order by id asc`, + ); + + expect(customerResults).toEqual( + expect.arrayContaining([ + { + id: 1, + name: "John Doe", + last_order_id: 1, + }, + ]), + ); + + expect(orderResults).toEqual( + expect.arrayContaining([ + { + id: 1, + customer_id: 1, + product_id: 1, + quantity: 10, + }, + ]), + ); + + expect(productResults).toEqual( + expect.arrayContaining([ + { + id: 1, + name: "Gadget", + first_order_id: 1, + }, + ]), + ); + }); + test("should handle circular references with bigger circular loop", async () => { + const structure = ` + -- Create tables without foreign keys that reference "order" + create table customer ( + id serial primary key, + name text not null, + last_order_id integer + ); + + create table product ( + id serial primary key, + name text not null, + first_order_id integer + ); + + create table supplier ( + id serial primary key, + name text not null, + first_shipment_id integer + ); + + -- Now create the order and shipment tables + create table "order" ( + id serial primary key, + customer_id integer not null, + product_id integer not null, + quantity integer not null, + shipment_id integer + ); + + create table shipment ( + id serial primary key, + order_id integer not null, + supplier_id integer not null + ); + + -- After all tables are created, add the foreign key constraints + ALTER TABLE customer ADD CONSTRAINT fk_customer_last_order FOREIGN KEY(last_order_id) REFERENCES "order"(id); + ALTER TABLE product ADD CONSTRAINT fk_product_first_order FOREIGN KEY(first_order_id) REFERENCES "order"(id); + ALTER TABLE supplier ADD CONSTRAINT fk_supplier_first_shipment FOREIGN KEY(first_shipment_id) REFERENCES shipment(id); + + ALTER TABLE "order" ADD CONSTRAINT fk_order_customer FOREIGN KEY(customer_id) REFERENCES customer(id); + ALTER TABLE "order" ADD CONSTRAINT fk_order_product FOREIGN KEY(product_id) REFERENCES product(id); + ALTER TABLE "order" ADD CONSTRAINT fk_order_shipment FOREIGN KEY(shipment_id) REFERENCES shipment(id); + + ALTER TABLE shipment ADD CONSTRAINT fk_shipment_order FOREIGN KEY(order_id) REFERENCES "order"(id); + ALTER TABLE shipment ADD CONSTRAINT fk_shipment_supplier FOREIGN KEY(supplier_id) REFERENCES supplier(id); + `; + + const db = await createTestDb(structure); + const orm = createDrizzleORMPgClient(drizzle(db.client)); + const dataModel = await getDatamodel(orm); + + const store = new PgStore(dataModel); + const customerId = 1; + const productId = 1; + const orderId = 1; + const shipmentId = 1; + const supplierId = 1; + + // Insert suppliers and products, which don't depend on the orders or shipments initially. + store.add("supplier", { + name: "GizmoCorp", + first_shipment_id: shipmentId, + }); + store.add("product", { name: "Gadget", first_order_id: orderId }); + + // Insert a customer, which initially doesn't depend on an order. + store.add("customer", { name: "John Doe", last_order_id: orderId }); + + // Insert an order linking it to the customer and product, but without shipment_id. + store.add("order", { + customer_id: customerId, + product_id: productId, + quantity: 10, + shipment_id: shipmentId, + }); + + // Insert a shipment linking it to the order and supplier. + store.add("shipment", { + order_id: orderId, + supplier_id: supplierId, + }); + + await execQueries(orm, [...store.toSQL()]); + + // Verify the circular dependencies + const customerResult = await orm.query(`SELECT * FROM customer`); + const productResult = await orm.query(`SELECT * FROM product`); + const orderResult = await orm.query(`SELECT * FROM "order"`); + const shipmentResult = await orm.query(`SELECT * FROM shipment`); + const supplierResult = await orm.query(`SELECT * FROM supplier`); + + // Assertions + expect(customerResult).toEqual( + expect.arrayContaining([ + { + id: customerId, + name: "John Doe", + last_order_id: orderId, + }, + ]), + ); + + expect(productResult).toEqual( + expect.arrayContaining([ + { + id: productId, + name: "Gadget", + first_order_id: orderId, + }, + ]), + ); + + expect(orderResult).toEqual( + expect.arrayContaining([ + { + id: orderId, + customer_id: customerId, + product_id: productId, + quantity: 10, + shipment_id: shipmentId, + }, + ]), + ); + + expect(shipmentResult).toEqual( + expect.arrayContaining([ + { + id: shipmentId, + order_id: orderId, + supplier_id: supplierId, + }, + ]), + ); + + expect(supplierResult).toEqual( + expect.arrayContaining([ + { + id: supplierId, + name: "GizmoCorp", + first_shipment_id: shipmentId, + }, + ]), + ); + }); + test("should work with one single nullable FK table in the circular loop", async () => { + const structure = ` + create table customer ( + id serial primary key, + name text not null, + last_order_id integer NOT NULL + ); + + create table product ( + id serial primary key, + name text not null, + first_order_id integer NOT NULL + ); + + create table "order" ( + id serial primary key, + customer_id integer, + product_id integer, + quantity integer not null, + CONSTRAINT fk_customer + FOREIGN KEY(customer_id) + REFERENCES customer(id), + CONSTRAINT fk_product + FOREIGN KEY(product_id) + REFERENCES product(id) + ); + -- Add constraints to customer and product tables + alter table customer add constraint fk_last_order + foreign key (last_order_id) references "order"(id); + + alter table product add constraint fk_first_order + foreign key (first_order_id) references "order"(id); + `; + + const db = await createTestDb(structure); + const orm = createDrizzleORMPgClient(drizzle(db.client)); + const dataModel = await getDatamodel(orm); + + const store = new PgStore(dataModel); + + store.add("product", { + id: 1, + name: "Gadget", + first_order_id: 1, // This will be updated later after creating the order + }); + + store.add("customer", { + id: 1, + name: "John Doe", + last_order_id: 1, // This will be updated later after creating the order + }); + + store.add("order", { + id: 1, + customer_id: 1, + product_id: 1, + quantity: 10, + }); + + await execQueries(orm, [...store.toSQL()]); + + const customerResults = await orm.query( + `select * from customer order by id asc`, + ); + const orderResults = await orm.query( + `select * from "order" order by id asc`, + ); + const productResults = await orm.query( + `select * from product order by id asc`, + ); + + expect(customerResults).toEqual( + expect.arrayContaining([ + { + id: 1, + name: "John Doe", + last_order_id: 1, + }, + ]), + ); + + expect(orderResults).toEqual( + expect.arrayContaining([ + { + id: 1, + customer_id: 1, + product_id: 1, + quantity: 10, + }, + ]), + ); + + expect(productResults).toEqual( + expect.arrayContaining([ + { + id: 1, + name: "Gadget", + first_order_id: 1, + }, + ]), + ); + }); + test("should handle join table relationships", async () => { + const structure = ` + CREATE TABLE authors ( + id SERIAL PRIMARY KEY, + name TEXT NOT NULL + ); + + CREATE TABLE books ( + id SERIAL PRIMARY KEY, + title TEXT NOT NULL + ); + + CREATE TABLE author_books ( + author_id INTEGER NOT NULL, + book_id INTEGER NOT NULL, + PRIMARY KEY (author_id, book_id), + FOREIGN KEY (author_id) REFERENCES authors(id), + FOREIGN KEY (book_id) REFERENCES books(id) + ); + `; + + const db = await createTestDb(structure); + const orm = createDrizzleORMPgClient(drizzle(db.client)); + const dataModel = await getDatamodel(orm); + + const store = new PgStore(dataModel); + + const authorId1 = 1; + const authorId2 = 2; + const bookId1 = 1; + const bookId2 = 2; + // Insert authors + store.add("authors", { name: "Author One" }); + store.add("authors", { name: "Author Two" }); + + // Insert books + store.add("books", { title: "Book One" }); + store.add("books", { title: "Book Two" }); + + // Establish many-to-many relationships through author_books + store.add("author_books", { + author_id: authorId1, + book_id: bookId1, + }); + store.add("author_books", { + author_id: authorId1, + book_id: bookId2, + }); + store.add("author_books", { + author_id: authorId2, + book_id: bookId1, + }); + + await execQueries(orm, [...store.toSQL()]); + + // Verify the relationships + const results = await orm.query(` + SELECT a.name, b.title + FROM author_books ab + JOIN authors a ON ab.author_id = a.id + JOIN books b ON ab.book_id = b.id + `); + + // Assertions to verify the join table relationships + // This assumes your testing framework has an expect function and that + // you're familiar with its assertion syntax. Adjust accordingly. + expect(results).toEqual( + expect.arrayContaining([ + { name: "Author One", title: "Book One" }, + { name: "Author One", title: "Book Two" }, + { name: "Author Two", title: "Book One" }, + ]), + ); + }); + test("should error on non nullables complex circular references", async () => { + const structure = ` + create table customer ( + id serial primary key, + name text not null, + last_order_id integer NOT NULL + ); + + create table product ( + id serial primary key, + name text not null, + first_order_id integer NOT NULL + ); + + create table "order" ( + id serial primary key, + customer_id integer not null, + product_id integer not null, + quantity integer not null, + CONSTRAINT fk_customer + FOREIGN KEY(customer_id) + REFERENCES customer(id), + CONSTRAINT fk_product + FOREIGN KEY(product_id) + REFERENCES product(id) + ); + -- Add constraints to customer and product tables + alter table customer add constraint fk_last_order + foreign key (last_order_id) references "order"(id); + + alter table product add constraint fk_first_order + foreign key (first_order_id) references "order"(id); + `; + + const db = await createTestDb(structure); + const orm = createDrizzleORMPgClient(drizzle(db.client)); + const dataModel = await getDatamodel(orm); + + const store = new PgStore(dataModel); + + // Assume IDs are auto-generated correctly and linked properly + store.add("product", { + id: 1, + name: "Gadget", + first_order_id: 1, + }); + + store.add("customer", { + id: 1, + name: "John Doe", + last_order_id: 1, + }); + + store.add("order", { + id: 1, + customer_id: 1, + product_id: 1, + quantity: 10, + }); + + expect(() => store.toSQL()).toThrowError( + `Node order forms circular dependency: product -> order -> customer -> order`, + ); + }); }); }); diff --git a/packages/seed/src/dialects/postgres/store.ts b/packages/seed/src/dialects/postgres/store.ts index 367fa023..b045e6ea 100644 --- a/packages/seed/src/dialects/postgres/store.ts +++ b/packages/seed/src/dialects/postgres/store.ts @@ -1,212 +1,104 @@ import { format, ident, literal } from "@scaleleap/pg-format"; import { type Json } from "#core/data/types.js"; -import { isNullableParent as checkIsNullableParent } from "#core/dataModel/dataModel.js"; import { type DataModelModel, type DataModelScalarField, } from "#core/dataModel/types.js"; -import { StoreBase } from "#core/store/store.js"; -import { sortModels } from "#core/store/topologicalSort.js"; -import { escapeIdentifier, escapeLiteral, serializeToSQL } from "./utils.js"; - -interface MissingPKForUpdateError { - modelName: string; - type: "missingPKForUpdateError"; -} -type ToSQLErrors = MissingPKForUpdateError; - -function logToSqlErrors(errors: Array) { - if (errors.length === 0) { - return; - } - const missingPKForUpdateErrorsMap = new Map(); - for (const error of errors) { - // Set a unique map per model with the number of affected rows - // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition - if (error.type === "missingPKForUpdateError") { - missingPKForUpdateErrorsMap.set( - error.modelName, - (missingPKForUpdateErrorsMap.get(error.modelName) ?? 1) + 1, - ); - } - } - for (const [modelName, affectedRows] of missingPKForUpdateErrorsMap) { - console.log( - `Warning: skipping UPDATE on model ${modelName} for ${affectedRows} rows as it has no id fields (no PRIMARY KEYS or UNIQUE NON NULL columns found)`, - ); - } -} +import { SQL_DEFAULT_SYMBOL, StoreBase } from "#core/store/store.js"; +import { serializeToSQL } from "./utils.js"; export class PgStore extends StoreBase { toSQL() { - const SQL_DEFAULT_SYMBOL = "$$DEFAULT$$"; - - const sortedModels = sortModels(this.dataModel); - // we need to maintain an update map to store the ids of nullable parents - // we will use this map to create the links between the parent and the child once all the models have been inserted - const insertStatements: Array = []; - const updateStatements: Array = []; - const sequenceFixerStatements: Array = []; - const errorsData: Array = []; - - for (const entry of sortedModels) { - const model = entry.node as DataModelModel & { modelName: string }; - const idFieldNames = this.dataModel.models[model.modelName].fields - .filter((f) => f.kind === "scalar" && f.isId) - .map((f) => f.name); - const rows = this._store[model.modelName]; - - if (!rows.length) { - continue; - } - - const fieldMap = new Map( - model.fields - .filter((f) => f.kind === "scalar" && !(f.isGenerated && !f.isId)) - .map((f) => [f.name, f as DataModelScalarField]), - ); - const fieldToColumnMap = new Map( - Array.from(fieldMap.values()).map((f) => [f.name, f.columnName]), - ); - const sequenceFields = model.fields.filter((f) => f.sequence); - // If we inserted new rows with sequences, we need to update the database sequence value to the max value of the inserted rows - for (const sequenceField of sequenceFields) { - const tableName = model.tableName; - const schemaName = model.schemaName; - const fieldColumn = fieldToColumnMap.get(sequenceField.name); - if ( - fieldColumn && - sequenceField.sequence && - schemaName && - tableName && - sequenceField.sequence.identifier - ) { - const sequenceIdentifier = sequenceField.sequence.identifier; - const sequenceFixerStatement = `SELECT setval(${escapeLiteral( - sequenceIdentifier, - )}::regclass, (SELECT MAX(${escapeIdentifier( - fieldColumn, - )}) FROM ${escapeIdentifier(schemaName)}.${escapeIdentifier( - tableName, - )}))`; - sequenceFixerStatements.push(sequenceFixerStatement); - } - } - const insertRowsValues: Array> = []; - for (const row of rows) { - const insertRowValues: Array = []; - let updateRow: - | { - filter: Record; - values: Record; - } - | undefined; + return this._toSQL({ + serializeInsertStatement, + serializeUpdateStatement, + getEndStatements, + }); + } +} - for (const fieldName of fieldMap.keys()) { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const field = fieldMap.get(fieldName)!; +function serializeInsertStatement(props: { + columns: Array; + model: DataModelModel; + values: Array; +}) { + const isGeneratedId = + props.model.fields.filter((f) => f.isGenerated && f.isId).length > 0; - const value = row[fieldName]; + const insertStatementTemplate = [ + "INSERT INTO %I.%I (%I)", + isGeneratedId ? "OVERRIDING SYSTEM VALUE" : undefined, + "VALUES (%L)", + ] + .filter((s) => Boolean(s)) + .join(" "); - if (value === undefined && field.hasDefaultValue) { - // we use this weird syntax to replace the value in the final sql statements - insertRowValues.push(SQL_DEFAULT_SYMBOL); - continue; - } + return format( + insertStatementTemplate, + props.model.schemaName, + props.model.tableName, + props.columns, + Array.from(props.values.entries()).map(([i, v]) => { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const field = props.model.fields.find( + (f) => f.kind === "scalar" && f.columnName === props.columns[i], + )!; + return serializeToSQL(field.type, v as Json); + }), + ).replaceAll(`'${SQL_DEFAULT_SYMBOL}'`, "DEFAULT"); +} - // We check if the column is part of a nullable parent relation - const isNullableParent = checkIsNullableParent( - this.dataModel, - model.modelName, - fieldName, - ); - // If it is, and the value is not null, we store the id of the parent in the update map - if (isNullableParent && value !== null) { - if (idFieldNames.length > 0) { - if (!updateRow) { - updateRow = { - filter: idFieldNames.reduce( - (acc, idFieldName) => ({ - ...acc, - [idFieldName]: serializeToSQL( - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - fieldMap.get(idFieldName)!.type, - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - row[idFieldName]!, - ), - }), - {}, - ), - values: {}, - }; - } - updateRow.values[fieldName] = serializeToSQL( - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - fieldMap.get(fieldName)!.type, - value as Json, - ); - } else { - errorsData.push({ - modelName: model.modelName, - type: "missingPKForUpdateError", - }); - } - } - insertRowValues.push( - serializeToSQL( - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - fieldMap.get(fieldName)!.type, - // if the field is a nullable parent, we defer the insert of its parent id for later to avoid fk constraint errors - isNullableParent ? null : (value as Json), - ), - ); - } - if (updateRow) { - const updateStatement = [ - `UPDATE ${ident(model.schemaName)}.${ident(model.tableName)}`, - `SET ${Object.entries(updateRow.values) - .map( - ([c, v]) => `${ident(fieldToColumnMap.get(c))} = ${literal(v)}`, - ) - .join(", ")}`, - `WHERE ${Object.entries(updateRow.filter) - .map( - ([c, v]) => `${ident(fieldToColumnMap.get(c))} = ${literal(v)}`, - ) - .join(" AND ")}`, - ].join(" "); - updateStatements.push(updateStatement); - } - insertRowsValues.push(insertRowValues); - } +function serializeUpdateStatement(props: { + filterData: Array<[string, unknown]>; + model: DataModelModel; + updateData: Array<[string, unknown]>; +}) { + return [ + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + `UPDATE ${ident(props.model.schemaName!)}.${ident(props.model.tableName)}`, + `SET ${props.updateData + .map(([c, v]) => `${ident(c)} = ${literal(v)}`) + .join(", ")}`, + `WHERE ${props.filterData + .map(([c, v]) => `${ident(c)} = ${literal(v)}`) + .join(" AND ")}`, + ].join(" "); +} - const isGeneratedId = - model.fields.filter((f) => f.isGenerated && f.isId).length > 0; +function getEndStatements(model: DataModelModel) { + const statements: Array = []; - const insertStatementTemplate = [ - "INSERT INTO %I.%I (%I)", - isGeneratedId ? "OVERRIDING SYSTEM VALUE" : undefined, - "VALUES %L", - ] - .filter((s) => Boolean(s)) - .join(" "); + const fieldMap = new Map( + model.fields + .filter((f) => f.kind === "scalar" && !(f.isGenerated && !f.isId)) + .map((f) => [f.name, f as DataModelScalarField]), + ); + const fieldToColumnMap = new Map( + Array.from(fieldMap.values()).map((f) => [f.name, f.columnName]), + ); + const sequenceFields = model.fields.filter((f) => f.sequence); + // If we inserted new rows with sequences, we need to update the database sequence value to the max value of the inserted rows + for (const sequenceField of sequenceFields) { + const tableName = model.tableName; + const schemaName = model.schemaName; + const fieldColumn = fieldToColumnMap.get(sequenceField.name); - const insertStatement = format( - insertStatementTemplate, - model.schemaName, - model.tableName, - Array.from(fieldToColumnMap.values()), - insertRowsValues, - ) - // We patch the "DEFAULT" values as it's a reserved keyword and we don't want to escape it - .replaceAll(`'${SQL_DEFAULT_SYMBOL}'`, "DEFAULT"); - insertStatements.push(insertStatement); + if ( + fieldColumn && + sequenceField.sequence && + schemaName && + tableName && + sequenceField.sequence.identifier + ) { + const sequenceIdentifier = sequenceField.sequence.identifier; + const sequenceFixerStatement = `SELECT setval(${literal( + sequenceIdentifier, + )}::regclass, (SELECT MAX(${ident( + fieldColumn, + )}) FROM ${ident(schemaName)}.${ident(tableName)}))`; + statements.push(sequenceFixerStatement); } - logToSqlErrors(errorsData); - return [ - ...insertStatements, - ...updateStatements, - ...sequenceFixerStatements, - ]; } + + return statements; } diff --git a/packages/seed/src/dialects/sqlite/introspect/queries/fetchSequences.ts b/packages/seed/src/dialects/sqlite/introspect/queries/fetchSequences.ts index 42221a22..7ddcbb37 100644 --- a/packages/seed/src/dialects/sqlite/introspect/queries/fetchSequences.ts +++ b/packages/seed/src/dialects/sqlite/introspect/queries/fetchSequences.ts @@ -1,4 +1,5 @@ import { type DrizzleDbClient } from "#core/adapters.js"; +import { escapeIdentifier } from "#dialects/sqlite/utils.js"; import { FETCH_TABLE_COLUMNS_LIST, type FetchTableAndColumnsResultRaw, @@ -42,7 +43,7 @@ export async function fetchSequences(client: DrizzleDbClient) { const pkKey = tablePk && tablePk.affinity === "integer" ? tablePk.colName : "rowid"; const maxSeqRes = await client.query<{ currentSequenceValue: number }>( - `SELECT MAX(${pkKey}) + 1 as currentSequenceValue FROM ${tableId}`, + `SELECT MAX(${escapeIdentifier(pkKey)}) + 1 as currentSequenceValue FROM ${escapeIdentifier(tableId)}`, ); const maxSeqNo = maxSeqRes[0]; results.push({ diff --git a/packages/seed/src/dialects/sqlite/store.test.ts b/packages/seed/src/dialects/sqlite/store.test.ts index e4e1435c..58541cc5 100644 --- a/packages/seed/src/dialects/sqlite/store.test.ts +++ b/packages/seed/src/dialects/sqlite/store.test.ts @@ -254,5 +254,205 @@ describe.each(["betterSqlite3"] as const)("store: %s", (adapter) => { ]), ); }); + test("should handle circular references", async () => { + const structure = ` + create table customer ( + id integer primary key autoincrement not null, + name text not null, + referrer_id integer references customer(id) + ); + `; + + const db = await createTestDb(structure); + const orm = createDrizzleORMSqliteClient(drizzle(db.client)); + const dataModel = await getDatamodel(orm); + + const store = new SqliteStore(dataModel); + + store.add("customer", { + id: 1, + name: "John Doe", + referrer_id: 2, + }); + + store.add("customer", { + id: 2, + name: "Jane Doe", + referrer_id: 1, + }); + + await execQueries(orm, [...store.toSQL()]); + const results = await orm.query(`select * from customer order by id asc`); + + expect(results).toEqual( + expect.arrayContaining([ + { + id: 1, + name: "John Doe", + referrer_id: 2, + }, + { + id: 2, + name: "Jane Doe", + referrer_id: 1, + }, + ]), + ); + }); + test("should handle complex circular references", async () => { + const structure = ` + create table customer ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name TEXT NOT NULL, + last_order_id INTEGER, + FOREIGN KEY(last_order_id) REFERENCES "order"(id) + ); + + create table product ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name TEXT NOT NULL, + first_order_id INTEGER, + FOREIGN KEY(first_order_id) REFERENCES "order"(id) + ); + + create table "order" ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + customer_id INTEGER NOT NULL, + product_id INTEGER NOT NULL, + quantity INTEGER NOT NULL, + FOREIGN KEY(customer_id) REFERENCES customer(id), + FOREIGN KEY(product_id) REFERENCES product(id) + ); + + PRAGMA foreign_keys = ON; + `; + + const db = await createTestDb(structure); + const orm = createDrizzleORMSqliteClient(drizzle(db.client)); + const dataModel = await getDatamodel(orm); + + const store = new SqliteStore(dataModel); + + // Assume IDs are auto-generated correctly and linked properly + store.add("product", { + id: 1, + name: "Gadget", + first_order_id: 1, // This will be updated later after creating the order + }); + + store.add("customer", { + id: 1, + name: "John Doe", + last_order_id: 1, // This will be updated later after creating the order + }); + + store.add("order", { + id: 1, + customer_id: 1, + product_id: 1, + quantity: 10, + }); + + await execQueries(orm, [...store.toSQL()]); + + const customerResults = await orm.query( + `select * from customer order by id asc`, + ); + const orderResults = await orm.query( + `select * from "order" order by id asc`, + ); + const productResults = await orm.query( + `select * from product order by id asc`, + ); + + expect(customerResults).toEqual( + expect.arrayContaining([ + { + id: 1, + name: "John Doe", + last_order_id: 1, + }, + ]), + ); + + expect(orderResults).toEqual( + expect.arrayContaining([ + { + id: 1, + customer_id: 1, + product_id: 1, + quantity: 10, + }, + ]), + ); + + expect(productResults).toEqual( + expect.arrayContaining([ + { + id: 1, + name: "Gadget", + first_order_id: 1, + }, + ]), + ); + }); + test("should error on non nullables complex circular references", async () => { + const structure = ` + create table customer ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name TEXT NOT NULL, + last_order_id INTEGER NOT NULL, + FOREIGN KEY(last_order_id) REFERENCES "order"(id) + ); + + create table product ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name TEXT NOT NULL, + first_order_id INTEGER NOT NULL, + FOREIGN KEY(first_order_id) REFERENCES "order"(id) + ); + + create table "order" ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + customer_id INTEGER NOT NULL, + product_id INTEGER NOT NULL, + quantity INTEGER NOT NULL, + FOREIGN KEY(customer_id) REFERENCES customer(id), + FOREIGN KEY(product_id) REFERENCES product(id) + ); + + PRAGMA foreign_keys = ON; + `; + + const db = await createTestDb(structure); + const orm = createDrizzleORMSqliteClient(drizzle(db.client)); + const dataModel = await getDatamodel(orm); + + const store = new SqliteStore(dataModel); + + // Assume IDs are auto-generated correctly and linked properly + store.add("product", { + id: 1, + name: "Gadget", + first_order_id: 1, + }); + + store.add("customer", { + id: 1, + name: "John Doe", + last_order_id: 1, + }); + + store.add("order", { + id: 1, + customer_id: 1, + product_id: 1, + quantity: 10, + }); + + expect(() => store.toSQL()).toThrowError( + `Node product forms circular dependency: product -> order -> product`, + ); + }); }); }); diff --git a/packages/seed/src/dialects/sqlite/store.ts b/packages/seed/src/dialects/sqlite/store.ts index d6dc0d35..62cceadd 100644 --- a/packages/seed/src/dialects/sqlite/store.ts +++ b/packages/seed/src/dialects/sqlite/store.ts @@ -1,175 +1,53 @@ import { format, ident, literal } from "@scaleleap/pg-format"; import { type Json } from "#core/data/types.js"; -import { isNullableParent as checkIsNullableParent } from "#core/dataModel/dataModel.js"; -import { - type DataModelModel, - type DataModelScalarField, -} from "#core/dataModel/types.js"; -import { StoreBase } from "#core/store/store.js"; -import { sortModels } from "#core/store/topologicalSort.js"; +import { type DataModelModel } from "#core/dataModel/types.js"; +import { SQL_DEFAULT_SYMBOL, StoreBase } from "#core/store/store.js"; import { serializeToSQL } from "./utils.js"; -interface MissingPKForUpdateError { - modelName: string; - type: "missingPKForUpdateError"; -} -type ToSQLErrors = MissingPKForUpdateError; - -function logToSqlErrors(errors: Array) { - if (errors.length === 0) { - return; - } - const missingPKForUpdateErrorsMap = new Map(); - for (const error of errors) { - // Set a unique map per model with the number of affected rows - // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition - if (error.type === "missingPKForUpdateError") { - missingPKForUpdateErrorsMap.set( - error.modelName, - (missingPKForUpdateErrorsMap.get(error.modelName) ?? 1) + 1, - ); - } - } - for (const [modelName, affectedRows] of missingPKForUpdateErrorsMap) { - console.log( - `Warning: skipping UPDATE on model ${modelName} for ${affectedRows} rows as it has no id fields (no PRIMARY KEYS or UNIQUE NON NULL columns found)`, - ); - } -} - export class SqliteStore extends StoreBase { toSQL() { - const SQL_DEFAULT_SYMBOL = "$$DEFAULT$$"; - - const sortedModels = sortModels(this.dataModel); - // we need to maintain an update map to store the ids of nullable parents - // we will use this map to create the links between the parent and the child once all the models have been inserted - const insertStatements: Array = []; - const updateStatements: Array = []; - const errorsData: Array = []; - - for (const entry of sortedModels) { - const model = entry.node as DataModelModel & { modelName: string }; - const idFieldNames = this.dataModel.models[model.modelName].fields - .filter((f) => f.kind === "scalar" && f.isId) - .map((f) => f.name); - const rows = this._store[model.modelName]; - - if (!rows.length) { - continue; - } - const fieldMap = new Map( - model.fields - .filter((f) => f.kind === "scalar" && !(f.isGenerated && !f.isId)) - .map((f) => [f.name, f as DataModelScalarField]), - ); - const fieldToColumnMap = new Map( - Array.from(fieldMap.values()).map((f) => [f.name, f.columnName]), - ); - const insertRowsValues: Array> = []; - for (const row of rows) { - const insertRowValues: Array = []; - let updateRow: - | { filter: Record; values: Record } - | undefined; - - for (const fieldName of fieldMap.keys()) { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const field = fieldMap.get(fieldName)!; - - const value = row[fieldName]; - - if (value === undefined && field.hasDefaultValue) { - // we use this weird syntax to replace the value in the final sql statements - insertRowValues.push(SQL_DEFAULT_SYMBOL); - continue; - } + return this._toSQL({ + serializeInsertStatement, + serializeUpdateStatement, + }); + } +} - // We check if the column is part of a nullable parent relation - const isNullableParent = checkIsNullableParent( - this.dataModel, - model.modelName, - fieldName, - ); - // If it is, and the value is not null, we store the id of the parent in the update map - if (isNullableParent && value !== null) { - if (idFieldNames.length > 0) { - if (!updateRow) { - updateRow = { - filter: idFieldNames.reduce( - (acc, idFieldName) => ({ - ...acc, - [idFieldName]: serializeToSQL( - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - fieldMap.get(idFieldName)!.type, - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - row[idFieldName]!, - ), - }), - {}, - ), - values: {}, - }; - } - updateRow.values[fieldName] = serializeToSQL( - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - fieldMap.get(fieldName)!.type, - value as Json, - ); - } else { - errorsData.push({ - modelName: model.modelName, - type: "missingPKForUpdateError", - }); - } - } - insertRowValues.push( - serializeToSQL( - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - fieldMap.get(fieldName)!.type, - // if the field is a nullable parent, we defer the insert of its parent id for later to avoid fk constraint errors - isNullableParent ? null : (value as Json), - ), - ); - } - if (updateRow) { - const updateStatement = [ - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - `UPDATE ${ident(model.schemaName!)}.${ident(model.tableName)}`, - `SET ${Object.entries(updateRow.values) - .map( - ([c, v]) => `${ident(fieldToColumnMap.get(c))} = ${literal(v)}`, - ) - .join(", ")}`, - `WHERE ${Object.entries(updateRow.filter) - .map( - ([c, v]) => `${ident(fieldToColumnMap.get(c))} = ${literal(v)}`, - ) - .join(" AND ")}`, - ].join(" "); - updateStatements.push(updateStatement); - } - insertRowsValues.push(insertRowValues); - } +function serializeInsertStatement(props: { + columns: Array; + model: DataModelModel; + values: Array; +}) { + const insertStatementTemplate = "INSERT INTO %I (%I) VALUES (%L)"; + + return format( + insertStatementTemplate, + props.model.tableName, + props.columns.filter((_, i) => props.values[i] !== SQL_DEFAULT_SYMBOL), + props.values + .filter((v) => v !== SQL_DEFAULT_SYMBOL) + .map((v, i) => { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const field = props.model.fields.find( + (f) => f.kind === "scalar" && f.columnName === props.columns[i], + )!; + return serializeToSQL(field.type, v as Json); + }), + ); +} - const insertStatementTemplate = "INSERT INTO %I (%I) VALUES %L"; - const columnsMap = Array.from(fieldToColumnMap.values()); - const inserts = insertRowsValues.map((row) => { - // Exclude columns with default values and not provided value from the insert statement - const columnsToFills = columnsMap.filter( - (_, i) => row[i] !== SQL_DEFAULT_SYMBOL, - ); - const values = row.filter((v) => v !== SQL_DEFAULT_SYMBOL); - return format( - insertStatementTemplate, - model.tableName, - columnsToFills, - [values], - ); - }); - insertStatements.push(...inserts); - } - logToSqlErrors(errorsData); - return [...insertStatements, ...updateStatements]; - } +function serializeUpdateStatement(props: { + filterData: Array<[string, unknown]>; + model: DataModelModel; + updateData: Array<[string, unknown]>; +}) { + return [ + `UPDATE ${ident(props.model.tableName)}`, + `SET ${props.updateData + .map(([c, v]) => `${ident(c)} = ${literal(v)}`) + .join(", ")}`, + `WHERE ${props.filterData + .map(([c, v]) => `${ident(c)} = ${literal(v)}`) + .join(" AND ")}`, + ].join(" "); } diff --git a/packages/tsconfig/package.json b/packages/tsconfig/package.json index 6a1cecd3..83ec3e65 100644 --- a/packages/tsconfig/package.json +++ b/packages/tsconfig/package.json @@ -9,6 +9,6 @@ "dependencies": { "@tsconfig/node18": "18.2.2", "@tsconfig/strictest": "2.0.3", - "@tsconfig/vite-react": "3.0.0" + "@tsconfig/vite-react": "3.0.1" } } \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 459efc56..f4cf8be5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15,56 +15,56 @@ importers: specifier: workspace:* version: link:packages/tsconfig eslint: - specifier: 8.56.0 - version: 8.56.0 + specifier: 8.57.0 + version: 8.57.0 knip: - specifier: 5.0.1 - version: 5.0.1(@types/node@20.11.18)(typescript@5.3.3) + specifier: 5.0.3 + version: 5.0.3(@types/node@20.11.25)(typescript@5.4.2) skott: - specifier: 0.32.1 - version: 0.32.1 + specifier: 0.33.0 + version: 0.33.0 turbo: - specifier: 1.12.4 - version: 1.12.4 + specifier: 1.12.5 + version: 1.12.5 typescript: - specifier: 5.3.3 - version: 5.3.3 + specifier: 5.4.2 + version: 5.4.2 vitest: - specifier: 1.2.2 - version: 1.2.2(@types/node@20.11.18) + specifier: 1.3.1 + version: 1.3.1(@types/node@20.11.25) packages/eslint-config: dependencies: '@typescript-eslint/eslint-plugin': - specifier: 7.0.1 - version: 7.0.1(@typescript-eslint/parser@7.0.1)(eslint@8.56.0)(typescript@5.3.3) + specifier: 7.1.1 + version: 7.1.1(@typescript-eslint/parser@7.1.1)(eslint@8.57.0)(typescript@5.4.2) '@typescript-eslint/parser': - specifier: 7.0.1 - version: 7.0.1(eslint@8.56.0)(typescript@5.3.3) + specifier: 7.1.1 + version: 7.1.1(eslint@8.57.0)(typescript@5.4.2) eslint: - specifier: 8.56.0 - version: 8.56.0 + specifier: 8.57.0 + version: 8.57.0 eslint-config-prettier: specifier: 9.1.0 - version: 9.1.0(eslint@8.56.0) + version: 9.1.0(eslint@8.57.0) eslint-plugin-i: specifier: 2.29.1 - version: 2.29.1(@typescript-eslint/parser@7.0.1)(eslint@8.56.0) + version: 2.29.1(@typescript-eslint/parser@7.1.1)(eslint@8.57.0) eslint-plugin-node-import: specifier: 1.0.4 - version: 1.0.4(eslint@8.56.0) + version: 1.0.4(eslint@8.57.0) eslint-plugin-perfectionist: - specifier: 2.5.0 - version: 2.5.0(eslint@8.56.0)(typescript@5.3.3) + specifier: 2.6.0 + version: 2.6.0(eslint@8.57.0)(typescript@5.4.2) eslint-plugin-prettier: specifier: 5.1.3 - version: 5.1.3(@types/eslint@8.56.2)(eslint-config-prettier@9.1.0)(eslint@8.56.0)(prettier@3.2.5) + version: 5.1.3(@types/eslint@8.56.5)(eslint-config-prettier@9.1.0)(eslint@8.57.0)(prettier@3.2.5) eslint-plugin-unused-imports: specifier: 3.1.0 - version: 3.1.0(@typescript-eslint/eslint-plugin@7.0.1)(eslint@8.56.0) + version: 3.1.0(@typescript-eslint/eslint-plugin@7.1.1)(eslint@8.57.0) eslint-plugin-vitest: specifier: 0.3.22 - version: 0.3.22(@typescript-eslint/eslint-plugin@7.0.1)(eslint@8.56.0)(typescript@5.3.3)(vitest@1.2.2) + version: 0.3.22(@typescript-eslint/eslint-plugin@7.1.1)(eslint@8.57.0)(typescript@5.4.2)(vitest@1.3.1) globals: specifier: 14.0.0 version: 14.0.0 @@ -73,14 +73,14 @@ importers: version: 3.2.5 devDependencies: '@types/eslint': - specifier: 8.56.2 - version: 8.56.2 + specifier: 8.56.5 + version: 8.56.5 packages/seed: dependencies: '@babel/types': - specifier: 7.23.9 - version: 7.23.9 + specifier: 7.24.0 + version: 7.24.0 '@scaleleap/pg-format': specifier: ^1.0.0 version: 1.0.0 @@ -91,8 +91,8 @@ importers: specifier: 10.45.1 version: 10.45.1 c12: - specifier: 1.8.0 - version: 1.8.0 + specifier: 1.10.0 + version: 1.10.0 drizzle-orm: specifier: ^0.29.3 version: 0.29.3(@types/better-sqlite3@7.6.9)(@types/pg@8.11.0)(better-sqlite3@9.4.3)(postgres@3.4.3) @@ -112,11 +112,11 @@ importers: specifier: 8.0.1 version: 8.0.1 quicktype-core: - specifier: ^23.0.104 - version: 23.0.104 + specifier: ^23.0.105 + version: 23.0.105 remeda: - specifier: ^1.41.0 - version: 1.41.0 + specifier: ^1.47.0 + version: 1.47.0 yargs: specifier: ^17.7.2 version: 17.7.2 @@ -143,11 +143,11 @@ importers: specifier: 11.0.4 version: 11.0.4 '@types/node': - specifier: 20.11.18 - version: 20.11.18 + specifier: 20.11.25 + version: 20.11.25 '@types/pg': - specifier: 8.11.0 - version: 8.11.0 + specifier: 8.11.2 + version: 8.11.2 '@types/tmp': specifier: 0.2.6 version: 0.2.6 @@ -161,8 +161,8 @@ importers: specifier: 9.4.3 version: 9.4.3 eslint: - specifier: 8.56.0 - version: 8.56.0 + specifier: 8.57.0 + version: 8.57.0 execa: specifier: 8.0.1 version: 8.0.1 @@ -179,14 +179,14 @@ importers: specifier: 4.7.1 version: 4.7.1 typescript: - specifier: 5.3.3 - version: 5.3.3 + specifier: 5.4.2 + version: 5.4.2 uuid: specifier: 9.0.1 version: 9.0.1 vitest: - specifier: 1.2.2 - version: 1.2.2(@types/node@20.11.18) + specifier: 1.3.1 + version: 1.3.1(@types/node@20.11.25) packages/tsconfig: dependencies: @@ -197,8 +197,8 @@ importers: specifier: 2.0.3 version: 2.0.3 '@tsconfig/vite-react': - specifier: 3.0.0 - version: 3.0.0 + specifier: 3.0.1 + version: 3.0.1 packages: @@ -223,9 +223,9 @@ packages: resolution: {integrity: sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.9 - '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.22 + '@babel/types': 7.24.0 + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 jsesc: 2.5.2 dev: true @@ -238,22 +238,22 @@ packages: resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/template': 7.23.9 - '@babel/types': 7.23.9 + '@babel/template': 7.24.0 + '@babel/types': 7.24.0 dev: true /@babel/helper-hoist-variables@7.22.5: resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.9 + '@babel/types': 7.24.0 dev: true /@babel/helper-split-export-declaration@7.22.6: resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.9 + '@babel/types': 7.24.0 dev: true /@babel/helper-string-parser@7.23.4: @@ -273,25 +273,25 @@ packages: js-tokens: 4.0.0 dev: true - /@babel/parser@7.23.9: - resolution: {integrity: sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==} + /@babel/parser@7.24.0: + resolution: {integrity: sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==} engines: {node: '>=6.0.0'} hasBin: true dependencies: - '@babel/types': 7.23.9 + '@babel/types': 7.24.0 dev: true - /@babel/template@7.23.9: - resolution: {integrity: sha512-+xrD2BWLpvHKNmX2QbpdpsBaWnRxahMwJjO+KZk2JOElj5nSmKezyS1B4u+QbHMTX69t4ukm6hh9lsYQ7GHCKA==} + /@babel/template@7.24.0: + resolution: {integrity: sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==} engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.23.5 - '@babel/parser': 7.23.9 - '@babel/types': 7.23.9 + '@babel/parser': 7.24.0 + '@babel/types': 7.24.0 dev: true - /@babel/traverse@7.23.9: - resolution: {integrity: sha512-I/4UJ9vs90OkBtY6iiiTORVMyIhJ4kAVmsKo9KFc8UOxMeUfi2hvtIBsET5u9GizXE6/GFSuKCTNfgCswuEjRg==} + /@babel/traverse@7.24.0: + resolution: {integrity: sha512-HfuJlI8qq3dEDmNU5ChzzpZRWq+oxCZQyMzIMEqLho+AQnhMnKQUzH6ydo3RBl/YjPCuk68Y6s0Gx0AeyULiWw==} engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.23.5 @@ -300,32 +300,22 @@ packages: '@babel/helper-function-name': 7.23.0 '@babel/helper-hoist-variables': 7.22.5 '@babel/helper-split-export-declaration': 7.22.6 - '@babel/parser': 7.23.9 - '@babel/types': 7.23.9 + '@babel/parser': 7.24.0 + '@babel/types': 7.24.0 debug: 4.3.4 globals: 11.12.0 transitivePeerDependencies: - supports-color dev: true - /@babel/types@7.23.9: - resolution: {integrity: sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q==} + /@babel/types@7.24.0: + resolution: {integrity: sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==} engines: {node: '>=6.9.0'} dependencies: '@babel/helper-string-parser': 7.23.4 '@babel/helper-validator-identifier': 7.22.20 to-fast-properties: 2.0.0 - /@effect/data@0.4.1: - resolution: {integrity: sha512-FdQ0qbYL7t+GP5eWdAPC+oeN2w3zqnujrdDLp/sj58UtMxFSHg21crprmbmiAJAWsL5EdB9aZzcisBGn382xHg==} - dev: true - - /@effect/io@0.8.0: - resolution: {integrity: sha512-JJUs05oiHzh/Eupf5mgeLRFA4RXJAJo2DNxPC4ZVXwhvgJeqJ/G0ftYo3znOO0vKLzXjw8WYrnXPBM1nYLPnfQ==} - dependencies: - '@effect/data': 0.4.1 - dev: true - /@ericcornelissen/bash-parser@0.5.2: resolution: {integrity: sha512-4pIMTa1nEFfMXitv7oaNEWOdM+zpOZavesa5GaiWTgda6Zk32CFGxjUp/iIaN0PwgUW1yTq/fztSjbpE8SLGZQ==} engines: {node: '>=4'} @@ -535,13 +525,13 @@ packages: requiresBuild: true optional: true - /@eslint-community/eslint-utils@4.4.0(eslint@8.56.0): + /@eslint-community/eslint-utils@4.4.0(eslint@8.57.0): resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 dependencies: - eslint: 8.56.0 + eslint: 8.57.0 eslint-visitor-keys: 3.4.3 /@eslint-community/regexpp@4.10.0: @@ -564,8 +554,8 @@ packages: transitivePeerDependencies: - supports-color - /@eslint/js@8.56.0: - resolution: {integrity: sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==} + /@eslint/js@8.57.0: + resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} /@faker-js/faker@8.4.0: @@ -612,32 +602,32 @@ packages: dependencies: '@sinclair/typebox': 0.27.8 - /@jridgewell/gen-mapping@0.3.3: - resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==} + /@jridgewell/gen-mapping@0.3.5: + resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} engines: {node: '>=6.0.0'} dependencies: - '@jridgewell/set-array': 1.1.2 + '@jridgewell/set-array': 1.2.1 '@jridgewell/sourcemap-codec': 1.4.15 - '@jridgewell/trace-mapping': 0.3.22 + '@jridgewell/trace-mapping': 0.3.25 dev: true - /@jridgewell/resolve-uri@3.1.1: - resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} + /@jridgewell/resolve-uri@3.1.2: + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} dev: true - /@jridgewell/set-array@1.1.2: - resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} + /@jridgewell/set-array@1.2.1: + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} engines: {node: '>=6.0.0'} dev: true /@jridgewell/sourcemap-codec@1.4.15: resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} - /@jridgewell/trace-mapping@0.3.22: - resolution: {integrity: sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==} + /@jridgewell/trace-mapping@0.3.25: + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} dependencies: - '@jridgewell/resolve-uri': 3.1.1 + '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.4.15 dev: true @@ -733,8 +723,8 @@ packages: which: 4.0.0 dev: true - /@parcel/watcher-android-arm64@2.4.0: - resolution: {integrity: sha512-+fPtO/GsbYX1LJnCYCaDVT3EOBjvSFdQN9Mrzh9zWAOOfvidPWyScTrHIZHHfJBvlHzNA0Gy0U3NXFA/M7PHUA==} + /@parcel/watcher-android-arm64@2.4.1: + resolution: {integrity: sha512-LOi/WTbbh3aTn2RYddrO8pnapixAziFl6SMxHM69r3tvdSm94JtCenaKgk1GRg5FJ5wpMCpHeW+7yqPlvZv7kg==} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [android] @@ -742,8 +732,8 @@ packages: dev: true optional: true - /@parcel/watcher-darwin-arm64@2.4.0: - resolution: {integrity: sha512-T/At5pansFuQ8VJLRx0C6C87cgfqIYhW2N/kBfLCUvDhCah0EnLLwaD/6MW3ux+rpgkpQAnMELOCTKlbwncwiA==} + /@parcel/watcher-darwin-arm64@2.4.1: + resolution: {integrity: sha512-ln41eihm5YXIY043vBrrHfn94SIBlqOWmoROhsMVTSXGh0QahKGy77tfEywQ7v3NywyxBBkGIfrWRHm0hsKtzA==} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [darwin] @@ -751,8 +741,8 @@ packages: dev: true optional: true - /@parcel/watcher-darwin-x64@2.4.0: - resolution: {integrity: sha512-vZMv9jl+szz5YLsSqEGCMSllBl1gU1snfbRL5ysJU03MEa6gkVy9OMcvXV1j4g0++jHEcvzhs3Z3LpeEbVmY6Q==} + /@parcel/watcher-darwin-x64@2.4.1: + resolution: {integrity: sha512-yrw81BRLjjtHyDu7J61oPuSoeYWR3lDElcPGJyOvIXmor6DEo7/G2u1o7I38cwlcoBHQFULqF6nesIX3tsEXMg==} engines: {node: '>= 10.0.0'} cpu: [x64] os: [darwin] @@ -760,8 +750,8 @@ packages: dev: true optional: true - /@parcel/watcher-freebsd-x64@2.4.0: - resolution: {integrity: sha512-dHTRMIplPDT1M0+BkXjtMN+qLtqq24sLDUhmU+UxxLP2TEY2k8GIoqIJiVrGWGomdWsy5IO27aDV1vWyQ6gfHA==} + /@parcel/watcher-freebsd-x64@2.4.1: + resolution: {integrity: sha512-TJa3Pex/gX3CWIx/Co8k+ykNdDCLx+TuZj3f3h7eOjgpdKM+Mnix37RYsYU4LHhiYJz3DK5nFCCra81p6g050w==} engines: {node: '>= 10.0.0'} cpu: [x64] os: [freebsd] @@ -769,8 +759,8 @@ packages: dev: true optional: true - /@parcel/watcher-linux-arm-glibc@2.4.0: - resolution: {integrity: sha512-9NQXD+qk46RwATNC3/UB7HWurscY18CnAPMTFcI9Y8CTbtm63/eex1SNt+BHFinEQuLBjaZwR2Lp+n7pmEJPpQ==} + /@parcel/watcher-linux-arm-glibc@2.4.1: + resolution: {integrity: sha512-4rVYDlsMEYfa537BRXxJ5UF4ddNwnr2/1O4MHM5PjI9cvV2qymvhwZSFgXqbS8YoTk5i/JR0L0JDs69BUn45YA==} engines: {node: '>= 10.0.0'} cpu: [arm] os: [linux] @@ -778,8 +768,8 @@ packages: dev: true optional: true - /@parcel/watcher-linux-arm64-glibc@2.4.0: - resolution: {integrity: sha512-QuJTAQdsd7PFW9jNGaV9Pw+ZMWV9wKThEzzlY3Lhnnwy7iW23qtQFPql8iEaSFMCVI5StNNmONUopk+MFKpiKg==} + /@parcel/watcher-linux-arm64-glibc@2.4.1: + resolution: {integrity: sha512-BJ7mH985OADVLpbrzCLgrJ3TOpiZggE9FMblfO65PlOCdG++xJpKUJ0Aol74ZUIYfb8WsRlUdgrZxKkz3zXWYA==} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [linux] @@ -787,8 +777,8 @@ packages: dev: true optional: true - /@parcel/watcher-linux-arm64-musl@2.4.0: - resolution: {integrity: sha512-oyN+uA9xcTDo/45bwsd6TFHa7Lc7hKujyMlvwrCLvSckvWogndCEoVYFNfZ6JJ2KNL/6fFiGPcbjp8jJmEh5Ng==} + /@parcel/watcher-linux-arm64-musl@2.4.1: + resolution: {integrity: sha512-p4Xb7JGq3MLgAfYhslU2SjoV9G0kI0Xry0kuxeG/41UfpjHGOhv7UoUDAz/jb1u2elbhazy4rRBL8PegPJFBhA==} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [linux] @@ -796,8 +786,8 @@ packages: dev: true optional: true - /@parcel/watcher-linux-x64-glibc@2.4.0: - resolution: {integrity: sha512-KphV8awJmxU3q52JQvJot0QMu07CIyEjV+2Tb2ZtbucEgqyRcxOBDMsqp1JNq5nuDXtcCC0uHQICeiEz38dPBQ==} + /@parcel/watcher-linux-x64-glibc@2.4.1: + resolution: {integrity: sha512-s9O3fByZ/2pyYDPoLM6zt92yu6P4E39a03zvO0qCHOTjxmt3GHRMLuRZEWhWLASTMSrrnVNWdVI/+pUElJBBBg==} engines: {node: '>= 10.0.0'} cpu: [x64] os: [linux] @@ -805,8 +795,8 @@ packages: dev: true optional: true - /@parcel/watcher-linux-x64-musl@2.4.0: - resolution: {integrity: sha512-7jzcOonpXNWcSijPpKD5IbC6xC7yTibjJw9jviVzZostYLGxbz8LDJLUnLzLzhASPlPGgpeKLtFUMjAAzM+gSA==} + /@parcel/watcher-linux-x64-musl@2.4.1: + resolution: {integrity: sha512-L2nZTYR1myLNST0O632g0Dx9LyMNHrn6TOt76sYxWLdff3cB22/GZX2UPtJnaqQPdCRoszoY5rcOj4oMTtp5fQ==} engines: {node: '>= 10.0.0'} cpu: [x64] os: [linux] @@ -814,8 +804,8 @@ packages: dev: true optional: true - /@parcel/watcher-win32-arm64@2.4.0: - resolution: {integrity: sha512-NOej2lqlq8bQNYhUMnOD0nwvNql8ToQF+1Zhi9ULZoG+XTtJ9hNnCFfyICxoZLXor4bBPTOnzs/aVVoefYnjIg==} + /@parcel/watcher-win32-arm64@2.4.1: + resolution: {integrity: sha512-Uq2BPp5GWhrq/lcuItCHoqxjULU1QYEcyjSO5jqqOK8RNFDBQnenMMx4gAl3v8GiWa59E9+uDM7yZ6LxwUIfRg==} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [win32] @@ -823,8 +813,8 @@ packages: dev: true optional: true - /@parcel/watcher-win32-ia32@2.4.0: - resolution: {integrity: sha512-IO/nM+K2YD/iwjWAfHFMBPz4Zqn6qBDqZxY4j2n9s+4+OuTSRM/y/irksnuqcspom5DjkSeF9d0YbO+qpys+JA==} + /@parcel/watcher-win32-ia32@2.4.1: + resolution: {integrity: sha512-maNRit5QQV2kgHFSYwftmPBxiuK5u4DXjbXx7q6eKjq5dsLXZ4FJiVvlcw35QXzk0KrUecJmuVFbj4uV9oYrcw==} engines: {node: '>= 10.0.0'} cpu: [ia32] os: [win32] @@ -832,8 +822,8 @@ packages: dev: true optional: true - /@parcel/watcher-win32-x64@2.4.0: - resolution: {integrity: sha512-pAUyUVjfFjWaf/pShmJpJmNxZhbMvJASUpdes9jL6bTEJ+gDxPRSpXTIemNyNsb9AtbiGXs9XduP1reThmd+dA==} + /@parcel/watcher-win32-x64@2.4.1: + resolution: {integrity: sha512-+DvS92F9ezicfswqrvIRM2njcYJbd5mb9CUgtrHCHmvn7pPPa+nMDRu1o1bYYz/l5IB2NVGNJWiH7h1E58IF2A==} engines: {node: '>= 10.0.0'} cpu: [x64] os: [win32] @@ -841,8 +831,8 @@ packages: dev: true optional: true - /@parcel/watcher@2.4.0: - resolution: {integrity: sha512-XJLGVL0DEclX5pcWa2N9SX1jCGTDd8l972biNooLFtjneuGqodupPQh6XseXIBBeVIMaaJ7bTcs3qGvXwsp4vg==} + /@parcel/watcher@2.4.1: + resolution: {integrity: sha512-HNjmfLQEVRZmHRET336f20H/8kOozUGwk7yajvsonjNxbj2wBTK1WsQuHkD5yYh9RxFGL2EyDHryOihOwUoKDA==} engines: {node: '>= 10.0.0'} dependencies: detect-libc: 1.0.3 @@ -850,18 +840,18 @@ packages: micromatch: 4.0.5 node-addon-api: 7.1.0 optionalDependencies: - '@parcel/watcher-android-arm64': 2.4.0 - '@parcel/watcher-darwin-arm64': 2.4.0 - '@parcel/watcher-darwin-x64': 2.4.0 - '@parcel/watcher-freebsd-x64': 2.4.0 - '@parcel/watcher-linux-arm-glibc': 2.4.0 - '@parcel/watcher-linux-arm64-glibc': 2.4.0 - '@parcel/watcher-linux-arm64-musl': 2.4.0 - '@parcel/watcher-linux-x64-glibc': 2.4.0 - '@parcel/watcher-linux-x64-musl': 2.4.0 - '@parcel/watcher-win32-arm64': 2.4.0 - '@parcel/watcher-win32-ia32': 2.4.0 - '@parcel/watcher-win32-x64': 2.4.0 + '@parcel/watcher-android-arm64': 2.4.1 + '@parcel/watcher-darwin-arm64': 2.4.1 + '@parcel/watcher-darwin-x64': 2.4.1 + '@parcel/watcher-freebsd-x64': 2.4.1 + '@parcel/watcher-linux-arm-glibc': 2.4.1 + '@parcel/watcher-linux-arm64-glibc': 2.4.1 + '@parcel/watcher-linux-arm64-musl': 2.4.1 + '@parcel/watcher-linux-x64-glibc': 2.4.1 + '@parcel/watcher-linux-x64-musl': 2.4.1 + '@parcel/watcher-win32-arm64': 2.4.1 + '@parcel/watcher-win32-ia32': 2.4.1 + '@parcel/watcher-win32-x64': 2.4.1 dev: true /@pkgjs/parseargs@0.11.0: @@ -891,8 +881,8 @@ packages: '@pnpm/types': 9.4.2 dev: true - /@pnpm/error@5.0.2: - resolution: {integrity: sha512-0TEm+tWNYm+9uh6DSKyRbv8pv/6b4NL0PastLvMxIoqZbBZ5Zj1cYi332R9xsSUi31ZOsu2wpgn/bC7DA9hrjg==} + /@pnpm/error@5.0.3: + resolution: {integrity: sha512-ONJU5cUeoeJSy50qOYsMZQHTA/9QKmGgh1ATfEpCLgtbdwqUiwD9MxHNeXUYYI/pocBCz6r1ZCFqiQvO+8SUKA==} engines: {node: '>=16.14'} dependencies: '@pnpm/constants': 7.1.1 @@ -932,14 +922,14 @@ packages: validate-npm-package-name: 4.0.0 dev: true - /@pnpm/npm-resolver@18.1.0(@pnpm/logger@5.0.0): - resolution: {integrity: sha512-fUYKX/iHiHldL0VRVvkQI35YK2jWhZEkPO6rrGke8309+LKAo12v833nBttMDpQrtHefmqhB4mhCzQq6L2Xqmg==} + /@pnpm/npm-resolver@18.1.1(@pnpm/logger@5.0.0): + resolution: {integrity: sha512-NptzncmMD5ZMimbjWkGpMzuBRhlCY+sh7mzypPdBOTNlh5hmEQe/VaRKjNK4V9/b0C/llElkvIePL6acybu86w==} engines: {node: '>=16.14'} peerDependencies: '@pnpm/logger': ^5.0.0 dependencies: '@pnpm/core-loggers': 9.0.6(@pnpm/logger@5.0.0) - '@pnpm/error': 5.0.2 + '@pnpm/error': 5.0.3 '@pnpm/fetching-types': 5.0.0 '@pnpm/graceful-fs': 3.2.0 '@pnpm/logger': 5.0.0 @@ -987,12 +977,12 @@ packages: engines: {node: '>=16.14'} dev: true - /@pnpm/workspace.pkgs-graph@2.0.14(@pnpm/logger@5.0.0): - resolution: {integrity: sha512-SBXXyWDkPEoaLTjLRyQzRHoBYH+P0NLcIjX1yPUxuJiMTvGOMzjpLWTuxYNVe/P0V0VQMrjpJFaJPjlViNLhzg==} + /@pnpm/workspace.pkgs-graph@2.0.15(@pnpm/logger@5.0.0): + resolution: {integrity: sha512-Txxd5FzzVfBfGCTngISaxFlJzZhzdS8BUrCEtAWJfZOFbQzpWy27rzkaS7TaWW2dHiFcCVYzPI/2vgxfeRansA==} engines: {node: '>=16.14'} dependencies: '@pnpm/npm-package-arg': 1.0.0 - '@pnpm/npm-resolver': 18.1.0(@pnpm/logger@5.0.0) + '@pnpm/npm-resolver': 18.1.1(@pnpm/logger@5.0.0) '@pnpm/resolve-workspace-range': 5.0.1 ramda: /@pnpm/ramda@0.28.1 transitivePeerDependencies: @@ -1008,92 +998,92 @@ packages: resolution: {integrity: sha512-2LuNTFBIO0m7kKIQvvPHN6UE63VjpmL9rnEEaOOaiSPbZK+zUOYIzBAWcED+3XYzhYsd/0mD57VdxAEqqV52CQ==} dev: true - /@rollup/rollup-android-arm-eabi@4.9.6: - resolution: {integrity: sha512-MVNXSSYN6QXOulbHpLMKYi60ppyO13W9my1qogeiAqtjb2yR4LSmfU2+POvDkLzhjYLXz9Rf9+9a3zFHW1Lecg==} + /@rollup/rollup-android-arm-eabi@4.12.1: + resolution: {integrity: sha512-iU2Sya8hNn1LhsYyf0N+L4Gf9Qc+9eBTJJJsaOGUp+7x4n2M9dxTt8UvhJl3oeftSjblSlpCfvjA/IfP3g5VjQ==} cpu: [arm] os: [android] requiresBuild: true optional: true - /@rollup/rollup-android-arm64@4.9.6: - resolution: {integrity: sha512-T14aNLpqJ5wzKNf5jEDpv5zgyIqcpn1MlwCrUXLrwoADr2RkWA0vOWP4XxbO9aiO3dvMCQICZdKeDrFl7UMClw==} + /@rollup/rollup-android-arm64@4.12.1: + resolution: {integrity: sha512-wlzcWiH2Ir7rdMELxFE5vuM7D6TsOcJ2Yw0c3vaBR3VOsJFVTx9xvwnAvhgU5Ii8Gd6+I11qNHwndDscIm0HXg==} cpu: [arm64] os: [android] requiresBuild: true optional: true - /@rollup/rollup-darwin-arm64@4.9.6: - resolution: {integrity: sha512-CqNNAyhRkTbo8VVZ5R85X73H3R5NX9ONnKbXuHisGWC0qRbTTxnF1U4V9NafzJbgGM0sHZpdO83pLPzq8uOZFw==} + /@rollup/rollup-darwin-arm64@4.12.1: + resolution: {integrity: sha512-YRXa1+aZIFN5BaImK+84B3uNK8C6+ynKLPgvn29X9s0LTVCByp54TB7tdSMHDR7GTV39bz1lOmlLDuedgTwwHg==} cpu: [arm64] os: [darwin] requiresBuild: true optional: true - /@rollup/rollup-darwin-x64@4.9.6: - resolution: {integrity: sha512-zRDtdJuRvA1dc9Mp6BWYqAsU5oeLixdfUvkTHuiYOHwqYuQ4YgSmi6+/lPvSsqc/I0Omw3DdICx4Tfacdzmhog==} + /@rollup/rollup-darwin-x64@4.12.1: + resolution: {integrity: sha512-opjWJ4MevxeA8FhlngQWPBOvVWYNPFkq6/25rGgG+KOy0r8clYwL1CFd+PGwRqqMFVQ4/Qd3sQu5t7ucP7C/Uw==} cpu: [x64] os: [darwin] requiresBuild: true optional: true - /@rollup/rollup-linux-arm-gnueabihf@4.9.6: - resolution: {integrity: sha512-oNk8YXDDnNyG4qlNb6is1ojTOGL/tRhbbKeE/YuccItzerEZT68Z9gHrY3ROh7axDc974+zYAPxK5SH0j/G+QQ==} + /@rollup/rollup-linux-arm-gnueabihf@4.12.1: + resolution: {integrity: sha512-uBkwaI+gBUlIe+EfbNnY5xNyXuhZbDSx2nzzW8tRMjUmpScd6lCQYKY2V9BATHtv5Ef2OBq6SChEP8h+/cxifQ==} cpu: [arm] os: [linux] requiresBuild: true optional: true - /@rollup/rollup-linux-arm64-gnu@4.9.6: - resolution: {integrity: sha512-Z3O60yxPtuCYobrtzjo0wlmvDdx2qZfeAWTyfOjEDqd08kthDKexLpV97KfAeUXPosENKd8uyJMRDfFMxcYkDQ==} + /@rollup/rollup-linux-arm64-gnu@4.12.1: + resolution: {integrity: sha512-0bK9aG1kIg0Su7OcFTlexkVeNZ5IzEsnz1ept87a0TUgZ6HplSgkJAnFpEVRW7GRcikT4GlPV0pbtVedOaXHQQ==} cpu: [arm64] os: [linux] requiresBuild: true optional: true - /@rollup/rollup-linux-arm64-musl@4.9.6: - resolution: {integrity: sha512-gpiG0qQJNdYEVad+1iAsGAbgAnZ8j07FapmnIAQgODKcOTjLEWM9sRb+MbQyVsYCnA0Im6M6QIq6ax7liws6eQ==} + /@rollup/rollup-linux-arm64-musl@4.12.1: + resolution: {integrity: sha512-qB6AFRXuP8bdkBI4D7UPUbE7OQf7u5OL+R94JE42Z2Qjmyj74FtDdLGeriRyBDhm4rQSvqAGCGC01b8Fu2LthQ==} cpu: [arm64] os: [linux] requiresBuild: true optional: true - /@rollup/rollup-linux-riscv64-gnu@4.9.6: - resolution: {integrity: sha512-+uCOcvVmFUYvVDr27aiyun9WgZk0tXe7ThuzoUTAukZJOwS5MrGbmSlNOhx1j80GdpqbOty05XqSl5w4dQvcOA==} + /@rollup/rollup-linux-riscv64-gnu@4.12.1: + resolution: {integrity: sha512-sHig3LaGlpNgDj5o8uPEoGs98RII8HpNIqFtAI8/pYABO8i0nb1QzT0JDoXF/pxzqO+FkxvwkHZo9k0NJYDedg==} cpu: [riscv64] os: [linux] requiresBuild: true optional: true - /@rollup/rollup-linux-x64-gnu@4.9.6: - resolution: {integrity: sha512-HUNqM32dGzfBKuaDUBqFB7tP6VMN74eLZ33Q9Y1TBqRDn+qDonkAUyKWwF9BR9unV7QUzffLnz9GrnKvMqC/fw==} + /@rollup/rollup-linux-x64-gnu@4.12.1: + resolution: {integrity: sha512-nD3YcUv6jBJbBNFvSbp0IV66+ba/1teuBcu+fBBPZ33sidxitc6ErhON3JNavaH8HlswhWMC3s5rgZpM4MtPqQ==} cpu: [x64] os: [linux] requiresBuild: true optional: true - /@rollup/rollup-linux-x64-musl@4.9.6: - resolution: {integrity: sha512-ch7M+9Tr5R4FK40FHQk8VnML0Szi2KRujUgHXd/HjuH9ifH72GUmw6lStZBo3c3GB82vHa0ZoUfjfcM7JiiMrQ==} + /@rollup/rollup-linux-x64-musl@4.12.1: + resolution: {integrity: sha512-7/XVZqgBby2qp/cO0TQ8uJK+9xnSdJ9ct6gSDdEr4MfABrjTyrW6Bau7HQ73a2a5tPB7hno49A0y1jhWGDN9OQ==} cpu: [x64] os: [linux] requiresBuild: true optional: true - /@rollup/rollup-win32-arm64-msvc@4.9.6: - resolution: {integrity: sha512-VD6qnR99dhmTQ1mJhIzXsRcTBvTjbfbGGwKAHcu+52cVl15AC/kplkhxzW/uT0Xl62Y/meBKDZvoJSJN+vTeGA==} + /@rollup/rollup-win32-arm64-msvc@4.12.1: + resolution: {integrity: sha512-CYc64bnICG42UPL7TrhIwsJW4QcKkIt9gGlj21gq3VV0LL6XNb1yAdHVp1pIi9gkts9gGcT3OfUYHjGP7ETAiw==} cpu: [arm64] os: [win32] requiresBuild: true optional: true - /@rollup/rollup-win32-ia32-msvc@4.9.6: - resolution: {integrity: sha512-J9AFDq/xiRI58eR2NIDfyVmTYGyIZmRcvcAoJ48oDld/NTR8wyiPUu2X/v1navJ+N/FGg68LEbX3Ejd6l8B7MQ==} + /@rollup/rollup-win32-ia32-msvc@4.12.1: + resolution: {integrity: sha512-LN+vnlZ9g0qlHGlS920GR4zFCqAwbv2lULrR29yGaWP9u7wF5L7GqWu9Ah6/kFZPXPUkpdZwd//TNR+9XC9hvA==} cpu: [ia32] os: [win32] requiresBuild: true optional: true - /@rollup/rollup-win32-x64-msvc@4.9.6: - resolution: {integrity: sha512-jqzNLhNDvIZOrt69Ce4UjGRpXJBzhUBzawMwnaDAwyHriki3XollsewxWzOzz+4yOFDkuJHtTsZFwMxhYJWmLQ==} + /@rollup/rollup-win32-x64-msvc@4.12.1: + resolution: {integrity: sha512-n+vkrSyphvmU0qkQ6QBNXCGr2mKjhP08mPRM/Xp5Ck2FV4NrHU+y6axzDeixUrCBHVUS51TZhjqrKBBsHLKb2Q==} cpu: [x64] os: [win32] requiresBuild: true @@ -1160,17 +1150,17 @@ packages: resolution: {integrity: sha512-MroLvRhMbqtXI5WBSwoomro6OQS4xnCoudUrMb20JO0vLKUs0bAaCEcvM/immEBSJjFAK1l6jW1oAO8q3Ancrg==} dev: false - /@tsconfig/vite-react@3.0.0: - resolution: {integrity: sha512-haOFbphpavQ1+eyQjeqvlz7sRkQue/bS0GvFmraHml31Ufhv+7juUSc8PVe0In7sly+n+5zTLmzc287KciiGXg==} + /@tsconfig/vite-react@3.0.1: + resolution: {integrity: sha512-yrAEQWgWZdbfNt/11TrvUPkh0AJrJy+DP9qc4c5zPt8POGwYfEp8dB2LnBC9DBm/zpycsasRJh8Z9uVB17yxCw==} dev: false /@types/better-sqlite3@7.6.9: resolution: {integrity: sha512-FvktcujPDj9XKMJQWFcl2vVl7OdRIqsSRX9b0acWwTmwLK9CF2eqo/FRcmMLNpugKoX/avA6pb7TorDLmpgTnQ==} dependencies: - '@types/node': 20.11.18 + '@types/node': 20.11.25 - /@types/eslint@8.56.2: - resolution: {integrity: sha512-uQDwm1wFHmbBbCZCqAlq6Do9LYwByNZHWzXppSnay9SuwJ+VRbjkbLABer54kcPnMSlG6Fdiy2yaFXm/z9Z5gw==} + /@types/eslint@8.56.5: + resolution: {integrity: sha512-u5/YPJHo1tvkSF2CE0USEkxon82Z5DBy2xR+qfyYNszpX9qcs4sT6uq2kBbj4BXY1+DBGDPnrhMZV3pKWGNukw==} dependencies: '@types/estree': 1.0.5 '@types/json-schema': 7.0.15 @@ -1182,7 +1172,7 @@ packages: resolution: {integrity: sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==} dependencies: '@types/jsonfile': 6.1.4 - '@types/node': 20.11.18 + '@types/node': 20.11.25 dev: true /@types/json-schema@7.0.15: @@ -1191,7 +1181,7 @@ packages: /@types/jsonfile@6.1.4: resolution: {integrity: sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==} dependencies: - '@types/node': 20.11.18 + '@types/node': 20.11.25 dev: true /@types/minimatch@3.0.5: @@ -1202,6 +1192,12 @@ packages: resolution: {integrity: sha512-ABT5VWnnYneSBcNWYSCuR05M826RoMyMSGiFivXGx6ZUIsXb9vn4643IEwkg2zbEOSgAiSogtapN2fgc4mAPlw==} dependencies: undici-types: 5.26.5 + dev: false + + /@types/node@20.11.25: + resolution: {integrity: sha512-TBHyJxk2b7HceLVGFcpAUjsa5zIdsPWlR6XHfyGzd0SFu+/NFgQgMAl96MSDZgQDvJAvV6BKsFOrt6zIL09JDw==} + dependencies: + undici-types: 5.26.5 /@types/parse-json@4.0.2: resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} @@ -1213,6 +1209,15 @@ packages: '@types/node': 20.11.18 pg-protocol: 1.6.0 pg-types: 4.0.2 + dev: false + + /@types/pg@8.11.2: + resolution: {integrity: sha512-G2Mjygf2jFMU/9hCaTYxJrwdObdcnuQde1gndooZSOHsNSaCehAuwc7EIuSA34Do8Jx2yZ19KtvW8P0j4EuUXw==} + dependencies: + '@types/node': 20.11.25 + pg-protocol: 1.6.0 + pg-types: 4.0.2 + dev: true /@types/picomatch@2.3.3: resolution: {integrity: sha512-Yll76ZHikRFCyz/pffKGjrCwe/le2CDwOP5F210KQo27kpRE46U2rDnzikNlVn6/ezH3Mhn46bJMTfeVTtcYMg==} @@ -1222,8 +1227,8 @@ packages: resolution: {integrity: sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==} dev: false - /@types/semver@7.5.7: - resolution: {integrity: sha512-/wdoPq1QqkSj9/QOeKkFquEuPzQbHTWAMPH/PaUMB+JuR31lXhlWXRZ52IpfDYVlDOUBvX09uBrPwxGT1hjNBg==} + /@types/semver@7.5.8: + resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} dev: false /@types/tmp@0.2.6: @@ -1248,8 +1253,8 @@ packages: '@types/yargs-parser': 21.0.3 dev: true - /@typescript-eslint/eslint-plugin@7.0.1(@typescript-eslint/parser@7.0.1)(eslint@8.56.0)(typescript@5.3.3): - resolution: {integrity: sha512-OLvgeBv3vXlnnJGIAgCLYKjgMEU+wBGj07MQ/nxAaON+3mLzX7mJbhRYrVGiVvFiXtwFlkcBa/TtmglHy0UbzQ==} + /@typescript-eslint/eslint-plugin@7.1.1(@typescript-eslint/parser@7.1.1)(eslint@8.57.0)(typescript@5.4.2): + resolution: {integrity: sha512-zioDz623d0RHNhvx0eesUmGfIjzrk18nSBC8xewepKXbBvN/7c1qImV7Hg8TI1URTxKax7/zxfxj3Uph8Chcuw==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: '@typescript-eslint/parser': ^7.0.0 @@ -1260,25 +1265,25 @@ packages: optional: true dependencies: '@eslint-community/regexpp': 4.10.0 - '@typescript-eslint/parser': 7.0.1(eslint@8.56.0)(typescript@5.3.3) - '@typescript-eslint/scope-manager': 7.0.1 - '@typescript-eslint/type-utils': 7.0.1(eslint@8.56.0)(typescript@5.3.3) - '@typescript-eslint/utils': 7.0.1(eslint@8.56.0)(typescript@5.3.3) - '@typescript-eslint/visitor-keys': 7.0.1 + '@typescript-eslint/parser': 7.1.1(eslint@8.57.0)(typescript@5.4.2) + '@typescript-eslint/scope-manager': 7.1.1 + '@typescript-eslint/type-utils': 7.1.1(eslint@8.57.0)(typescript@5.4.2) + '@typescript-eslint/utils': 7.1.1(eslint@8.57.0)(typescript@5.4.2) + '@typescript-eslint/visitor-keys': 7.1.1 debug: 4.3.4 - eslint: 8.56.0 + eslint: 8.57.0 graphemer: 1.4.0 ignore: 5.3.1 natural-compare: 1.4.0 semver: 7.6.0 - ts-api-utils: 1.2.1(typescript@5.3.3) - typescript: 5.3.3 + ts-api-utils: 1.2.1(typescript@5.4.2) + typescript: 5.4.2 transitivePeerDependencies: - supports-color dev: false - /@typescript-eslint/parser@7.0.1(eslint@8.56.0)(typescript@5.3.3): - resolution: {integrity: sha512-8GcRRZNzaHxKzBPU3tKtFNing571/GwPBeCvmAUw0yBtfE2XVd0zFKJIMSWkHJcPQi0ekxjIts6L/rrZq5cxGQ==} + /@typescript-eslint/parser@7.1.1(eslint@8.57.0)(typescript@5.4.2): + resolution: {integrity: sha512-ZWUFyL0z04R1nAEgr9e79YtV5LbafdOtN7yapNbn1ansMyaegl2D4bL7vHoJ4HPSc4CaLwuCVas8CVuneKzplQ==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^8.56.0 @@ -1287,25 +1292,17 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/scope-manager': 7.0.1 - '@typescript-eslint/types': 7.0.1 - '@typescript-eslint/typescript-estree': 7.0.1(typescript@5.3.3) - '@typescript-eslint/visitor-keys': 7.0.1 + '@typescript-eslint/scope-manager': 7.1.1 + '@typescript-eslint/types': 7.1.1 + '@typescript-eslint/typescript-estree': 7.1.1(typescript@5.4.2) + '@typescript-eslint/visitor-keys': 7.1.1 debug: 4.3.4 - eslint: 8.56.0 - typescript: 5.3.3 + eslint: 8.57.0 + typescript: 5.4.2 transitivePeerDependencies: - supports-color dev: false - /@typescript-eslint/scope-manager@6.20.0: - resolution: {integrity: sha512-p4rvHQRDTI1tGGMDFQm+GtxP1ZHyAh64WANVoyEcNMpaTFn3ox/3CcgtIlELnRfKzSs/DwYlDccJEtr3O6qBvA==} - engines: {node: ^16.0.0 || >=18.0.0} - dependencies: - '@typescript-eslint/types': 6.20.0 - '@typescript-eslint/visitor-keys': 6.20.0 - dev: false - /@typescript-eslint/scope-manager@6.21.0: resolution: {integrity: sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==} engines: {node: ^16.0.0 || >=18.0.0} @@ -1314,16 +1311,16 @@ packages: '@typescript-eslint/visitor-keys': 6.21.0 dev: false - /@typescript-eslint/scope-manager@7.0.1: - resolution: {integrity: sha512-v7/T7As10g3bcWOOPAcbnMDuvctHzCFYCG/8R4bK4iYzdFqsZTbXGln0cZNVcwQcwewsYU2BJLay8j0/4zOk4w==} + /@typescript-eslint/scope-manager@7.1.1: + resolution: {integrity: sha512-cirZpA8bJMRb4WZ+rO6+mnOJrGFDd38WoXCEI57+CYBqta8Yc8aJym2i7vyqLL1vVYljgw0X27axkUXz32T8TA==} engines: {node: ^16.0.0 || >=18.0.0} dependencies: - '@typescript-eslint/types': 7.0.1 - '@typescript-eslint/visitor-keys': 7.0.1 + '@typescript-eslint/types': 7.1.1 + '@typescript-eslint/visitor-keys': 7.1.1 dev: false - /@typescript-eslint/type-utils@7.0.1(eslint@8.56.0)(typescript@5.3.3): - resolution: {integrity: sha512-YtT9UcstTG5Yqy4xtLiClm1ZpM/pWVGFnkAa90UfdkkZsR1eP2mR/1jbHeYp8Ay1l1JHPyGvoUYR6o3On5Nhmw==} + /@typescript-eslint/type-utils@7.1.1(eslint@8.57.0)(typescript@5.4.2): + resolution: {integrity: sha512-5r4RKze6XHEEhlZnJtR3GYeCh1IueUHdbrukV2KSlLXaTjuSfeVF8mZUVPLovidCuZfbVjfhi4c0DNSa/Rdg5g==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^8.56.0 @@ -1332,52 +1329,26 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 7.0.1(typescript@5.3.3) - '@typescript-eslint/utils': 7.0.1(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/typescript-estree': 7.1.1(typescript@5.4.2) + '@typescript-eslint/utils': 7.1.1(eslint@8.57.0)(typescript@5.4.2) debug: 4.3.4 - eslint: 8.56.0 - ts-api-utils: 1.2.1(typescript@5.3.3) - typescript: 5.3.3 + eslint: 8.57.0 + ts-api-utils: 1.2.1(typescript@5.4.2) + typescript: 5.4.2 transitivePeerDependencies: - supports-color dev: false - /@typescript-eslint/types@6.20.0: - resolution: {integrity: sha512-MM9mfZMAhiN4cOEcUOEx+0HmuaW3WBfukBZPCfwSqFnQy0grXYtngKCqpQN339X3RrwtzspWJrpbrupKYUSBXQ==} - engines: {node: ^16.0.0 || >=18.0.0} - /@typescript-eslint/types@6.21.0: resolution: {integrity: sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==} engines: {node: ^16.0.0 || >=18.0.0} - dev: false - /@typescript-eslint/types@7.0.1: - resolution: {integrity: sha512-uJDfmirz4FHib6ENju/7cz9SdMSkeVvJDK3VcMFvf/hAShg8C74FW+06MaQPODHfDJp/z/zHfgawIJRjlu0RLg==} + /@typescript-eslint/types@7.1.1: + resolution: {integrity: sha512-KhewzrlRMrgeKm1U9bh2z5aoL4s7K3tK5DwHDn8MHv0yQfWFz/0ZR6trrIHHa5CsF83j/GgHqzdbzCXJ3crx0Q==} engines: {node: ^16.0.0 || >=18.0.0} dev: false - /@typescript-eslint/typescript-estree@6.20.0(typescript@5.3.3): - resolution: {integrity: sha512-RnRya9q5m6YYSpBN7IzKu9FmLcYtErkDkc8/dKv81I9QiLLtVBHrjz+Ev/crAqgMNW2FCsoZF4g2QUylMnJz+g==} - engines: {node: ^16.0.0 || >=18.0.0} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/types': 6.20.0 - '@typescript-eslint/visitor-keys': 6.20.0 - debug: 4.3.4 - globby: 11.1.0 - is-glob: 4.0.3 - minimatch: 9.0.3 - semver: 7.5.4 - ts-api-utils: 1.0.3(typescript@5.3.3) - typescript: 5.3.3 - transitivePeerDependencies: - - supports-color - - /@typescript-eslint/typescript-estree@6.21.0(typescript@5.3.3): + /@typescript-eslint/typescript-estree@6.21.0(typescript@5.4.2): resolution: {integrity: sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: @@ -1393,14 +1364,13 @@ packages: is-glob: 4.0.3 minimatch: 9.0.3 semver: 7.6.0 - ts-api-utils: 1.2.1(typescript@5.3.3) - typescript: 5.3.3 + ts-api-utils: 1.2.1(typescript@5.4.2) + typescript: 5.4.2 transitivePeerDependencies: - supports-color - dev: false - /@typescript-eslint/typescript-estree@7.0.1(typescript@5.3.3): - resolution: {integrity: sha512-SO9wHb6ph0/FN5OJxH4MiPscGah5wjOd0RRpaLvuBv9g8565Fgu0uMySFEPqwPHiQU90yzJ2FjRYKGrAhS1xig==} + /@typescript-eslint/typescript-estree@7.1.1(typescript@5.4.2): + resolution: {integrity: sha512-9ZOncVSfr+sMXVxxca2OJOPagRwT0u/UHikM2Rd6L/aB+kL/QAuTnsv6MeXtjzCJYb8PzrXarypSGIPx3Jemxw==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: typescript: '*' @@ -1408,176 +1378,149 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/types': 7.0.1 - '@typescript-eslint/visitor-keys': 7.0.1 + '@typescript-eslint/types': 7.1.1 + '@typescript-eslint/visitor-keys': 7.1.1 debug: 4.3.4 globby: 11.1.0 is-glob: 4.0.3 minimatch: 9.0.3 semver: 7.6.0 - ts-api-utils: 1.2.1(typescript@5.3.3) - typescript: 5.3.3 - transitivePeerDependencies: - - supports-color - dev: false - - /@typescript-eslint/utils@6.20.0(eslint@8.56.0)(typescript@5.3.3): - resolution: {integrity: sha512-/EKuw+kRu2vAqCoDwDCBtDRU6CTKbUmwwI7SH7AashZ+W+7o8eiyy6V2cdOqN49KsTcASWsC5QeghYuRDTyOOg==} - engines: {node: ^16.0.0 || >=18.0.0} - peerDependencies: - eslint: ^7.0.0 || ^8.0.0 - dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0) - '@types/json-schema': 7.0.15 - '@types/semver': 7.5.6 - '@typescript-eslint/scope-manager': 6.20.0 - '@typescript-eslint/types': 6.20.0 - '@typescript-eslint/typescript-estree': 6.20.0(typescript@5.3.3) - eslint: 8.56.0 - semver: 7.5.4 + ts-api-utils: 1.2.1(typescript@5.4.2) + typescript: 5.4.2 transitivePeerDependencies: - supports-color - - typescript dev: false - /@typescript-eslint/utils@6.21.0(eslint@8.56.0)(typescript@5.3.3): + /@typescript-eslint/utils@6.21.0(eslint@8.57.0)(typescript@5.4.2): resolution: {integrity: sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) '@types/json-schema': 7.0.15 '@types/semver': 7.5.6 '@typescript-eslint/scope-manager': 6.21.0 '@typescript-eslint/types': 6.21.0 - '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.3.3) - eslint: 8.56.0 + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.4.2) + eslint: 8.57.0 semver: 7.6.0 transitivePeerDependencies: - supports-color - typescript dev: false - /@typescript-eslint/utils@7.0.1(eslint@8.56.0)(typescript@5.3.3): - resolution: {integrity: sha512-oe4his30JgPbnv+9Vef1h48jm0S6ft4mNwi9wj7bX10joGn07QRfqIqFHoMiajrtoU88cIhXf8ahwgrcbNLgPA==} + /@typescript-eslint/utils@7.1.1(eslint@8.57.0)(typescript@5.4.2): + resolution: {integrity: sha512-thOXM89xA03xAE0lW7alstvnyoBUbBX38YtY+zAUcpRPcq9EIhXPuJ0YTv948MbzmKh6e1AUszn5cBFK49Umqg==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^8.56.0 dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) '@types/json-schema': 7.0.15 - '@types/semver': 7.5.7 - '@typescript-eslint/scope-manager': 7.0.1 - '@typescript-eslint/types': 7.0.1 - '@typescript-eslint/typescript-estree': 7.0.1(typescript@5.3.3) - eslint: 8.56.0 + '@types/semver': 7.5.8 + '@typescript-eslint/scope-manager': 7.1.1 + '@typescript-eslint/types': 7.1.1 + '@typescript-eslint/typescript-estree': 7.1.1(typescript@5.4.2) + eslint: 8.57.0 semver: 7.6.0 transitivePeerDependencies: - supports-color - typescript dev: false - /@typescript-eslint/visitor-keys@6.20.0: - resolution: {integrity: sha512-E8Cp98kRe4gKHjJD4NExXKz/zOJ1A2hhZc+IMVD6i7w4yjIvh6VyuRI0gRtxAsXtoC35uGMaQ9rjI2zJaXDEAw==} - engines: {node: ^16.0.0 || >=18.0.0} - dependencies: - '@typescript-eslint/types': 6.20.0 - eslint-visitor-keys: 3.4.3 - /@typescript-eslint/visitor-keys@6.21.0: resolution: {integrity: sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==} engines: {node: ^16.0.0 || >=18.0.0} dependencies: '@typescript-eslint/types': 6.21.0 eslint-visitor-keys: 3.4.3 - dev: false - /@typescript-eslint/visitor-keys@7.0.1: - resolution: {integrity: sha512-hwAgrOyk++RTXrP4KzCg7zB2U0xt7RUU0ZdMSCsqF3eKUwkdXUMyTb0qdCuji7VIbcpG62kKTU9M1J1c9UpFBw==} + /@typescript-eslint/visitor-keys@7.1.1: + resolution: {integrity: sha512-yTdHDQxY7cSoCcAtiBzVzxleJhkGB9NncSIyMYe2+OGON1ZsP9zOPws/Pqgopa65jvknOjlk/w7ulPlZ78PiLQ==} engines: {node: ^16.0.0 || >=18.0.0} dependencies: - '@typescript-eslint/types': 7.0.1 + '@typescript-eslint/types': 7.1.1 eslint-visitor-keys: 3.4.3 dev: false /@ungap/structured-clone@1.2.0: resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} - /@vitest/expect@1.2.2: - resolution: {integrity: sha512-3jpcdPAD7LwHUUiT2pZTj2U82I2Tcgg2oVPvKxhn6mDI2On6tfvPQTjAI4628GUGDZrCm4Zna9iQHm5cEexOAg==} + /@vitest/expect@1.3.1: + resolution: {integrity: sha512-xofQFwIzfdmLLlHa6ag0dPV8YsnKOCP1KdAeVVh34vSjN2dcUiXYCD9htu/9eM7t8Xln4v03U9HLxLpPlsXdZw==} dependencies: - '@vitest/spy': 1.2.2 - '@vitest/utils': 1.2.2 + '@vitest/spy': 1.3.1 + '@vitest/utils': 1.3.1 chai: 4.4.1 - /@vitest/runner@1.2.2: - resolution: {integrity: sha512-JctG7QZ4LSDXr5CsUweFgcpEvrcxOV1Gft7uHrvkQ+fsAVylmWQvnaAr/HDp3LAH1fztGMQZugIheTWjaGzYIg==} + /@vitest/runner@1.3.1: + resolution: {integrity: sha512-5FzF9c3jG/z5bgCnjr8j9LNq/9OxV2uEBAITOXfoe3rdZJTdO7jzThth7FXv/6b+kdY65tpRQB7WaKhNZwX+Kg==} dependencies: - '@vitest/utils': 1.2.2 + '@vitest/utils': 1.3.1 p-limit: 5.0.0 pathe: 1.1.2 - /@vitest/snapshot@1.2.2: - resolution: {integrity: sha512-SmGY4saEw1+bwE1th6S/cZmPxz/Q4JWsl7LvbQIky2tKE35US4gd0Mjzqfr84/4OD0tikGWaWdMja/nWL5NIPA==} + /@vitest/snapshot@1.3.1: + resolution: {integrity: sha512-EF++BZbt6RZmOlE3SuTPu/NfwBF6q4ABS37HHXzs2LUVPBLx2QoY/K0fKpRChSo8eLiuxcbCVfqKgx/dplCDuQ==} dependencies: - magic-string: 0.30.6 + magic-string: 0.30.8 pathe: 1.1.2 pretty-format: 29.7.0 - /@vitest/spy@1.2.2: - resolution: {integrity: sha512-k9Gcahssw8d7X3pSLq3e3XEu/0L78mUkCjivUqCQeXJm9clfXR/Td8+AP+VC1O6fKPIDLcHDTAmBOINVuv6+7g==} + /@vitest/spy@1.3.1: + resolution: {integrity: sha512-xAcW+S099ylC9VLU7eZfdT9myV67Nor9w9zhf0mGCYJSO+zM2839tOeROTdikOi/8Qeusffvxb/MyBSOja1Uig==} dependencies: - tinyspy: 2.2.0 + tinyspy: 2.2.1 - /@vitest/utils@1.2.2: - resolution: {integrity: sha512-WKITBHLsBHlpjnDQahr+XK6RE7MiAsgrIkr0pGhQ9ygoxBfUeG0lUG5iLlzqjmKSlBv3+j5EGsriBzh+C3Tq9g==} + /@vitest/utils@1.3.1: + resolution: {integrity: sha512-d3Waie/299qqRyHTm2DjADeTaNdNSVsnwHPWrs20JMpjh6eiVq7ggggweO8rc4arhf6rRkWuHKwvxGvejUXZZQ==} dependencies: diff-sequences: 29.6.3 estree-walker: 3.0.3 loupe: 2.3.7 pretty-format: 29.7.0 - /@vue/compiler-core@3.4.15: - resolution: {integrity: sha512-XcJQVOaxTKCnth1vCxEChteGuwG6wqnUHxAm1DO3gCz0+uXKaJNx8/digSz4dLALCy8n2lKq24jSUs8segoqIw==} + /@vue/compiler-core@3.4.21: + resolution: {integrity: sha512-MjXawxZf2SbZszLPYxaFCjxfibYrzr3eYbKxwpLR9EQN+oaziSu3qKVbwBERj1IFIB8OLUewxB5m/BFzi613og==} dependencies: - '@babel/parser': 7.23.9 - '@vue/shared': 3.4.15 + '@babel/parser': 7.24.0 + '@vue/shared': 3.4.21 entities: 4.5.0 estree-walker: 2.0.2 source-map-js: 1.0.2 dev: true - /@vue/compiler-dom@3.4.15: - resolution: {integrity: sha512-wox0aasVV74zoXyblarOM3AZQz/Z+OunYcIHe1OsGclCHt8RsRm04DObjefaI82u6XDzv+qGWZ24tIsRAIi5MQ==} + /@vue/compiler-dom@3.4.21: + resolution: {integrity: sha512-IZC6FKowtT1sl0CR5DpXSiEB5ayw75oT2bma1BEhV7RRR1+cfwLrxc2Z8Zq/RGFzJ8w5r9QtCOvTjQgdn0IKmA==} dependencies: - '@vue/compiler-core': 3.4.15 - '@vue/shared': 3.4.15 + '@vue/compiler-core': 3.4.21 + '@vue/shared': 3.4.21 dev: true - /@vue/compiler-sfc@3.4.15: - resolution: {integrity: sha512-LCn5M6QpkpFsh3GQvs2mJUOAlBQcCco8D60Bcqmf3O3w5a+KWS5GvYbrrJBkgvL1BDnTp+e8q0lXCLgHhKguBA==} + /@vue/compiler-sfc@3.4.21: + resolution: {integrity: sha512-me7epoTxYlY+2CUM7hy9PCDdpMPfIwrOvAXud2Upk10g4YLv9UBW7kL798TvMeDhPthkZ0CONNrK2GoeI1ODiQ==} dependencies: - '@babel/parser': 7.23.9 - '@vue/compiler-core': 3.4.15 - '@vue/compiler-dom': 3.4.15 - '@vue/compiler-ssr': 3.4.15 - '@vue/shared': 3.4.15 + '@babel/parser': 7.24.0 + '@vue/compiler-core': 3.4.21 + '@vue/compiler-dom': 3.4.21 + '@vue/compiler-ssr': 3.4.21 + '@vue/shared': 3.4.21 estree-walker: 2.0.2 - magic-string: 0.30.6 - postcss: 8.4.33 + magic-string: 0.30.8 + postcss: 8.4.35 source-map-js: 1.0.2 dev: true - /@vue/compiler-ssr@3.4.15: - resolution: {integrity: sha512-1jdeQyiGznr8gjFDadVmOJqZiLNSsMa5ZgqavkPZ8O2wjHv0tVuAEsw5hTdUoUW4232vpBbL/wJhzVW/JwY1Uw==} + /@vue/compiler-ssr@3.4.21: + resolution: {integrity: sha512-M5+9nI2lPpAsgXOGQobnIueVqc9sisBFexh5yMIMRAPYLa7+5wEJs8iqOZc1WAa9WQbx9GR2twgznU8LTIiZ4Q==} dependencies: - '@vue/compiler-dom': 3.4.15 - '@vue/shared': 3.4.15 + '@vue/compiler-dom': 3.4.21 + '@vue/shared': 3.4.21 dev: true - /@vue/shared@3.4.15: - resolution: {integrity: sha512-KzfPTxVaWfB+eGcGdbSf4CWdaXcGDqckoeXUh7SB3fZdEtzPCK2Vq9B/lRRL3yutax/LWITz+SwvgyOxz5V75g==} + /@vue/shared@3.4.21: + resolution: {integrity: sha512-PuJe7vDIi6VYSinuEbUIQgMIRZGgM8e4R+G+/dQTk0X1NEdvgvvgv7m+rfmDH1gZzyA1OjjoWskvHlfRNfQf3g==} dev: true /@zkochan/retry@0.2.0: @@ -1808,17 +1751,16 @@ packages: engines: {node: '>= 0.8'} dev: true - /c12@1.8.0: - resolution: {integrity: sha512-93U6RndoaAwFQPBcS9F/6lwtgBfrWh4695sQ/ChILkbj0C7zOZVptOU3Sxp0I/9xvfW/lzBWD90AXDQz4muSkA==} + /c12@1.10.0: + resolution: {integrity: sha512-0SsG7UDhoRWcuSvKWHaXmu5uNjDCDN3nkQLRL4Q42IlFy+ze58FcCoI3uPwINXinkz7ZinbhEgyzYFw9u9ZV8g==} dependencies: chokidar: 3.6.0 + confbox: 0.1.3 defu: 6.1.4 - dotenv: 16.4.4 + dotenv: 16.4.5 giget: 1.2.1 jiti: 1.21.0 - json5: 2.2.3 - jsonc-parser: 3.2.1 - mlly: 1.5.0 + mlly: 1.6.1 ohash: 1.1.3 pathe: 1.1.2 perfect-debounce: 1.0.0 @@ -2015,6 +1957,10 @@ packages: /concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + /confbox@0.1.3: + resolution: {integrity: sha512-eH3ZxAihl1PhKfpr4VfEN6/vUd87fmgb6JkldHgg/YR6aEBhW63qUDgzP2Y6WM0UumdsYp5H3kibalXAdHfbgg==} + dev: false + /consola@3.2.3: resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==} engines: {node: ^14.18.0 || >=16.10.0} @@ -2138,9 +2084,9 @@ packages: engines: {node: '>=10'} hasBin: true dependencies: - '@babel/parser': 7.23.9 - '@babel/traverse': 7.23.9 - '@vue/compiler-sfc': 3.4.15 + '@babel/parser': 7.24.0 + '@babel/traverse': 7.24.0 + '@vue/compiler-sfc': 3.4.21 callsite: 1.0.0 camelcase: 6.3.0 cosmiconfig: 7.1.0 @@ -2159,7 +2105,7 @@ packages: require-package-name: 2.0.1 resolve: 1.22.8 resolve-from: 5.0.0 - semver: 7.5.4 + semver: 7.6.0 yargs: 16.2.0 transitivePeerDependencies: - supports-color @@ -2169,8 +2115,8 @@ packages: resolution: {integrity: sha512-PwuBojGMQAYbWkMXOY9Pd/NWCDNHVH12pnS7WHqZkTSeMESe4hwnKKRp0yR87g37113x4JPbo/oIvXY+s/f56Q==} dev: true - /destr@2.0.2: - resolution: {integrity: sha512-65AlobnZMiCET00KaFFjUefxDX0khFA/E4myqZ7a6Sq1yZtR8+FVIvilVX66vF2uobSumxooYZChiRPCKNqhmg==} + /destr@2.0.3: + resolution: {integrity: sha512-2N3BOUU4gYMpTP24s5rF5iP7BDr7uNTCs4ozw3kf/eKfvWSIu93GEBi5m427YoyJoeOzQ5smuu4nNAPGb8idSQ==} dev: false /detect-file@1.0.0: @@ -2216,8 +2162,8 @@ packages: dependencies: esutils: 2.0.3 - /dotenv@16.4.4: - resolution: {integrity: sha512-XvPXc8XAQThSjAbY6cQ/9PcBXmFoWuw1sQ3b8HqUCR6ziGXjkTi//kB9SWa2UwqlgdAIuRqAa/9hVljzPehbYg==} + /dotenv@16.4.5: + resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} engines: {node: '>=12'} dev: false @@ -2315,6 +2261,10 @@ packages: hasBin: true dev: false + /effect@2.4.0: + resolution: {integrity: sha512-HAtFVAbAGYDzfGbrSrX1gzMzXym15zk1+ps72X8W1wdZY0vxq+u23w8u9DhAZjiJPHT4W9ZYL7QWQqpP4t+dSg==} + dev: true + /emoji-regex@10.3.0: resolution: {integrity: sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==} dev: false @@ -2386,6 +2336,12 @@ packages: /escalade@3.1.1: resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} engines: {node: '>=6'} + dev: false + + /escalade@3.1.2: + resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} + engines: {node: '>=6'} + dev: true /escape-string-regexp@1.0.5: resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} @@ -2396,13 +2352,13 @@ packages: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} - /eslint-config-prettier@9.1.0(eslint@8.56.0): + /eslint-config-prettier@9.1.0(eslint@8.57.0): resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} hasBin: true peerDependencies: eslint: '>=7.0.0' dependencies: - eslint: 8.56.0 + eslint: 8.57.0 dev: false /eslint-import-resolver-node@0.3.9: @@ -2415,7 +2371,7 @@ packages: - supports-color dev: false - /eslint-module-utils@2.8.0(@typescript-eslint/parser@7.0.1)(eslint-import-resolver-node@0.3.9)(eslint@8.56.0): + /eslint-module-utils@2.8.0(@typescript-eslint/parser@7.1.1)(eslint-import-resolver-node@0.3.9)(eslint@8.57.0): resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==} engines: {node: '>=4'} peerDependencies: @@ -2436,15 +2392,15 @@ packages: eslint-import-resolver-webpack: optional: true dependencies: - '@typescript-eslint/parser': 7.0.1(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/parser': 7.1.1(eslint@8.57.0)(typescript@5.4.2) debug: 3.2.7 - eslint: 8.56.0 + eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 transitivePeerDependencies: - supports-color dev: false - /eslint-plugin-i@2.29.1(@typescript-eslint/parser@7.0.1)(eslint@8.56.0): + /eslint-plugin-i@2.29.1(@typescript-eslint/parser@7.1.1)(eslint@8.57.0): resolution: {integrity: sha512-ORizX37MelIWLbMyqI7hi8VJMf7A0CskMmYkB+lkCX3aF4pkGV7kwx5bSEb4qx7Yce2rAf9s34HqDRPjGRZPNQ==} engines: {node: '>=12'} peerDependencies: @@ -2452,9 +2408,9 @@ packages: dependencies: debug: 4.3.4 doctrine: 3.0.0 - eslint: 8.56.0 + eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@7.0.1)(eslint-import-resolver-node@0.3.9)(eslint@8.56.0) + eslint-module-utils: 2.8.0(@typescript-eslint/parser@7.1.1)(eslint-import-resolver-node@0.3.9)(eslint@8.57.0) get-tsconfig: 4.7.2 is-glob: 4.0.3 minimatch: 3.1.2 @@ -2466,17 +2422,17 @@ packages: - supports-color dev: false - /eslint-plugin-node-import@1.0.4(eslint@8.56.0): + /eslint-plugin-node-import@1.0.4(eslint@8.57.0): resolution: {integrity: sha512-nn6EkM7+vJCDCXZiM0FDpYSekbhlk5LNoHJm9DlVSucGrsT9WoK+qOxIEm+SwoFBeH73cMHMavioDaHsu22b0Q==} engines: {node: ^14.18.0 || ^16.0.0 || >= 18.0.0} peerDependencies: eslint: '>=7' dependencies: - eslint: 8.56.0 + eslint: 8.57.0 dev: false - /eslint-plugin-perfectionist@2.5.0(eslint@8.56.0)(typescript@5.3.3): - resolution: {integrity: sha512-F6XXcq4mKKUe/SREoMGQqzgw6cgCgf3pFzkFfQVIGtqD1yXVpQjnhTepzhBeZfxZwgMzR9HO4yH4CUhIQ2WBcQ==} + /eslint-plugin-perfectionist@2.6.0(eslint@8.57.0)(typescript@5.4.2): + resolution: {integrity: sha512-hee0Fu5825v+WTIhrRIJdWO8biUgm9O+c4Q1AEXIIGsXDHrLv5cdXfVUdnQcYgGtI/4X+tdFu69iVofHCIkvtw==} peerDependencies: astro-eslint-parser: ^0.16.0 eslint: '>=8.0.0' @@ -2493,8 +2449,8 @@ packages: vue-eslint-parser: optional: true dependencies: - '@typescript-eslint/utils': 6.20.0(eslint@8.56.0)(typescript@5.3.3) - eslint: 8.56.0 + '@typescript-eslint/utils': 6.21.0(eslint@8.57.0)(typescript@5.4.2) + eslint: 8.57.0 minimatch: 9.0.3 natural-compare-lite: 1.4.0 transitivePeerDependencies: @@ -2502,7 +2458,7 @@ packages: - typescript dev: false - /eslint-plugin-prettier@5.1.3(@types/eslint@8.56.2)(eslint-config-prettier@9.1.0)(eslint@8.56.0)(prettier@3.2.5): + /eslint-plugin-prettier@5.1.3(@types/eslint@8.56.5)(eslint-config-prettier@9.1.0)(eslint@8.57.0)(prettier@3.2.5): resolution: {integrity: sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: @@ -2516,15 +2472,15 @@ packages: eslint-config-prettier: optional: true dependencies: - '@types/eslint': 8.56.2 - eslint: 8.56.0 - eslint-config-prettier: 9.1.0(eslint@8.56.0) + '@types/eslint': 8.56.5 + eslint: 8.57.0 + eslint-config-prettier: 9.1.0(eslint@8.57.0) prettier: 3.2.5 prettier-linter-helpers: 1.0.0 synckit: 0.8.8 dev: false - /eslint-plugin-unused-imports@3.1.0(@typescript-eslint/eslint-plugin@7.0.1)(eslint@8.56.0): + /eslint-plugin-unused-imports@3.1.0(@typescript-eslint/eslint-plugin@7.1.1)(eslint@8.57.0): resolution: {integrity: sha512-9l1YFCzXKkw1qtAru1RWUtG2EVDZY0a0eChKXcL+EZ5jitG7qxdctu4RnvhOJHv4xfmUf7h+JJPINlVpGhZMrw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -2534,12 +2490,12 @@ packages: '@typescript-eslint/eslint-plugin': optional: true dependencies: - '@typescript-eslint/eslint-plugin': 7.0.1(@typescript-eslint/parser@7.0.1)(eslint@8.56.0)(typescript@5.3.3) - eslint: 8.56.0 + '@typescript-eslint/eslint-plugin': 7.1.1(@typescript-eslint/parser@7.1.1)(eslint@8.57.0)(typescript@5.4.2) + eslint: 8.57.0 eslint-rule-composer: 0.3.0 dev: false - /eslint-plugin-vitest@0.3.22(@typescript-eslint/eslint-plugin@7.0.1)(eslint@8.56.0)(typescript@5.3.3)(vitest@1.2.2): + /eslint-plugin-vitest@0.3.22(@typescript-eslint/eslint-plugin@7.1.1)(eslint@8.57.0)(typescript@5.4.2)(vitest@1.3.1): resolution: {integrity: sha512-atkFGQ7aVgcuSeSMDqnyevIyUpfBPMnosksgEPrKE7Y8xQlqG/5z2IQ6UDau05zXaaFv7Iz8uzqvIuKshjZ0Zw==} engines: {node: ^18.0.0 || >= 20.0.0} peerDependencies: @@ -2552,10 +2508,10 @@ packages: vitest: optional: true dependencies: - '@typescript-eslint/eslint-plugin': 7.0.1(@typescript-eslint/parser@7.0.1)(eslint@8.56.0)(typescript@5.3.3) - '@typescript-eslint/utils': 6.21.0(eslint@8.56.0)(typescript@5.3.3) - eslint: 8.56.0 - vitest: 1.2.2(@types/node@20.11.18) + '@typescript-eslint/eslint-plugin': 7.1.1(@typescript-eslint/parser@7.1.1)(eslint@8.57.0)(typescript@5.4.2) + '@typescript-eslint/utils': 6.21.0(eslint@8.57.0)(typescript@5.4.2) + eslint: 8.57.0 + vitest: 1.3.1(@types/node@20.11.25) transitivePeerDependencies: - supports-color - typescript @@ -2577,15 +2533,15 @@ packages: resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - /eslint@8.56.0: - resolution: {integrity: sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==} + /eslint@8.57.0: + resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) '@eslint-community/regexpp': 4.10.0 '@eslint/eslintrc': 2.1.4 - '@eslint/js': 8.56.0 + '@eslint/js': 8.57.0 '@humanwhocodes/config-array': 0.11.14 '@humanwhocodes/module-importer': 1.0.1 '@nodelib/fs.walk': 1.2.8 @@ -2816,7 +2772,7 @@ packages: resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} engines: {node: ^10.12.0 || >=12.0.0} dependencies: - flatted: 3.2.9 + flatted: 3.3.1 keyv: 4.5.4 rimraf: 3.0.2 @@ -2825,8 +2781,8 @@ packages: hasBin: true dev: false - /flatted@3.2.9: - resolution: {integrity: sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==} + /flatted@3.3.1: + resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} /fnv-plus@1.3.1: resolution: {integrity: sha512-Gz1EvfOneuFfk4yG458dJ3TLJ7gV19q3OM/vVvvHf7eT02Hm1DleB4edsia6ahbKgAYxO9gvyQ1ioWZR+a00Yw==} @@ -2920,7 +2876,7 @@ packages: consola: 3.2.3 defu: 6.1.4 node-fetch-native: 1.6.2 - nypm: 0.3.6 + nypm: 0.3.8 ohash: 1.1.3 pathe: 1.1.2 tar: 6.2.0 @@ -3249,14 +3205,17 @@ packages: resolution: {integrity: sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==} hasBin: true - /js-base64@3.7.6: - resolution: {integrity: sha512-NPrWuHFxFUknr1KqJRDgUQPexQF0uIJWjeT+2KjEePhitQxQEx5EJBG1lVn5/hc8aLycTpXrDOgPQ6Zq+EDiTA==} + /js-base64@3.7.7: + resolution: {integrity: sha512-7rCnleh0z2CkXhH67J8K1Ytz0b2Y+yxTPL+/KOJoa20hfnVQ/3/T6W/KflYI4bRHRagNeXeU2bkNGI3v1oS/lw==} dev: false /js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} dev: true + /js-tokens@8.0.3: + resolution: {integrity: sha512-UfJMcSJc+SEXEl9lH/VLHSZbThQyLpw1vLO1Lb+j4RWDvG3N2f7yj3PVQA3cmkTBNldJ9eFnM+xEXxHIXrYiJw==} + /js-yaml@3.14.1: resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} hasBin: true @@ -3315,6 +3274,7 @@ packages: resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} engines: {node: '>=6'} hasBin: true + dev: true /jsonc-parser@3.2.1: resolution: {integrity: sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==} @@ -3337,8 +3297,8 @@ packages: engines: {node: '>=6'} dev: true - /knip@5.0.1(@types/node@20.11.18)(typescript@5.3.3): - resolution: {integrity: sha512-rvZbe2JIpx+3i+ZC3XpLpKPp6oII9f5w1MOMsXwS1JnuYVuNd4R2i4eon2hFds9a+pf8F10DC1Gvt1W8SIBw3A==} + /knip@5.0.3(@types/node@20.11.25)(typescript@5.4.2): + resolution: {integrity: sha512-U4bCIkf4aZ3zZSrBaNE8xIdqX1QVhIHXpwUoAW7odx7oajMwa76hUDd9KjlFlb6qAPjdUuTGHjDszIgpfg+Ndg==} engines: {node: '>=18.6.0'} hasBin: true peerDependencies: @@ -3350,9 +3310,9 @@ packages: '@npmcli/map-workspaces': 3.0.4 '@npmcli/package-json': 5.0.0 '@pnpm/logger': 5.0.0 - '@pnpm/workspace.pkgs-graph': 2.0.14(@pnpm/logger@5.0.0) + '@pnpm/workspace.pkgs-graph': 2.0.15(@pnpm/logger@5.0.0) '@snyk/github-codeowners': 1.1.0 - '@types/node': 20.11.18 + '@types/node': 20.11.25 '@types/picomatch': 2.3.3 easy-table: 1.2.0 fast-glob: 3.3.2 @@ -3367,9 +3327,9 @@ packages: smol-toml: 1.1.4 strip-json-comments: 5.0.1 summary: 2.1.0 - typescript: 5.3.3 + typescript: 5.4.2 zod: 3.22.4 - zod-validation-error: 3.0.0(zod@3.22.4) + zod-validation-error: 3.0.2(zod@3.22.4) transitivePeerDependencies: - bluebird - domexception @@ -3400,7 +3360,7 @@ packages: resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==} engines: {node: '>=14'} dependencies: - mlly: 1.5.0 + mlly: 1.6.1 pkg-types: 1.0.3 /locate-path@6.0.0: @@ -3476,8 +3436,8 @@ packages: vlq: 0.2.3 dev: true - /magic-string@0.30.6: - resolution: {integrity: sha512-n62qCLbPjNjyo+owKtveQxZFZTBm+Ms6YoGD23Wew6Vw337PElFNifQpknPruVRQV57kVShPnLGo9vWxVhpPvA==} + /magic-string@0.30.8: + resolution: {integrity: sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==} engines: {node: '>=12'} dependencies: '@jridgewell/sourcemap-codec': 1.4.15 @@ -3524,8 +3484,8 @@ packages: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} - /meriyah@4.3.9: - resolution: {integrity: sha512-IepKx25Ph/5T67o+Q6Ezrt+repNAcJsydfsNWgelrdOhdcQcs4NI9qPHxB9Qz3WSYpj77hScNJrq5IjdwE1woQ==} + /meriyah@4.4.0: + resolution: {integrity: sha512-loEeDY1+BXyAlTsksyoqv0mtEAA6Tb9xTxq/Qo/J8CxR6Ap81Q/Dej4S6XWX1OFTQJZ/zILPHnvULB+gjtTs8A==} engines: {node: '>=10.4.0'} dev: true @@ -3620,13 +3580,13 @@ packages: hasBin: true dev: false - /mlly@1.5.0: - resolution: {integrity: sha512-NPVQvAY1xr1QoVeG0cy8yUYC7FQcOx6evl/RjT1wL5FvzPnzOysoqB/jmx/DhssT2dYa8nxECLAaFI/+gVLhDQ==} + /mlly@1.6.1: + resolution: {integrity: sha512-vLgaHvaeunuOXHSmEbZ9izxPx3USsk8KCQ8iC+aTlp5sKRSoZvwhHh5L9VbKSaVC6sJDqbyohIS76E2VmHIPAA==} dependencies: acorn: 8.11.3 pathe: 1.1.2 pkg-types: 1.0.3 - ufo: 1.3.2 + ufo: 1.4.0 /moo@0.5.2: resolution: {integrity: sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q==} @@ -3790,12 +3750,13 @@ packages: dependencies: path-key: 4.0.0 - /nypm@0.3.6: - resolution: {integrity: sha512-2CATJh3pd6CyNfU5VZM7qSwFu0ieyabkEdnogE30Obn1czrmOYiZ8DOZLe1yBdLKWoyD3Mcy2maUs+0MR3yVjQ==} + /nypm@0.3.8: + resolution: {integrity: sha512-IGWlC6So2xv6V4cIDmoV0SwwWx7zLG086gyqkyumteH2fIgCAM4nDVFB2iDRszDvmdSVW9xb1N+2KjQ6C7d4og==} engines: {node: ^14.16.0 || >=16.10.0} hasBin: true dependencies: citty: 0.1.6 + consola: 3.2.3 execa: 8.0.1 pathe: 1.1.2 ufo: 1.4.0 @@ -4070,7 +4031,7 @@ packages: resolution: {integrity: sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==} dependencies: jsonc-parser: 3.2.1 - mlly: 1.5.0 + mlly: 1.6.1 pathe: 1.1.2 /please-upgrade-node@3.2.0: @@ -4091,8 +4052,8 @@ packages: trouter: 2.0.1 dev: true - /postcss@8.4.33: - resolution: {integrity: sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg==} + /postcss@8.4.35: + resolution: {integrity: sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==} engines: {node: ^10 || ^12 || >=14} dependencies: nanoid: 3.3.7 @@ -4214,8 +4175,8 @@ packages: /queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - /quicktype-core@23.0.104: - resolution: {integrity: sha512-Y/9/hO0w4lYbacxxWdSyBhfZgs2kXELR21tawGFz7MICgxKX9KaPGLH3YQEd3NsX7KNZKdWPZdxkImgZL0RnQw==} + /quicktype-core@23.0.105: + resolution: {integrity: sha512-amxAkFPUMfvU5uzmIAwdCFo30bPj3TrSnFq3dFoIgmcltPPMdOxFzcwHG9DCHveR4u6Qj0DRWj7IQ4e/1TEJeA==} dependencies: '@glideapps/ts-necessities': 2.1.3 '@types/urijs': 1.19.25 @@ -4223,7 +4184,7 @@ packages: collection-utils: 1.0.1 cross-fetch: 4.0.0 is-url: 1.2.4 - js-base64: 3.7.6 + js-base64: 3.7.7 lodash: 4.17.21 pako: 1.0.11 pluralize: 8.0.0 @@ -4231,7 +4192,7 @@ packages: unicode-properties: 1.4.1 urijs: 1.19.11 wordwrap: 1.0.0 - yaml: 2.3.4 + yaml: 2.4.1 transitivePeerDependencies: - encoding dev: false @@ -4252,7 +4213,7 @@ packages: resolution: {integrity: sha512-lNeOl38Ws0eNxpO3+wD1I9rkHGQyj1NU1jlzv4go2CtEnEQEUfqnIvZG7W+bC/aXdJ27n5x/yUjb6RoT9tko+Q==} dependencies: defu: 6.1.4 - destr: 2.0.2 + destr: 2.0.3 flat: 5.0.2 dev: false @@ -4301,8 +4262,8 @@ packages: dependencies: picomatch: 2.3.1 - /remeda@1.41.0: - resolution: {integrity: sha512-QIle6xHZEblnLhqynWgdI8dLOcYKKz2EG35ut8Wws7BUutZLZPWdxAsfjZVSO63rCoU9H3jI4fUJ+CF16gngsA==} + /remeda@1.47.0: + resolution: {integrity: sha512-NhB81y1itYfqF4AYnZW5nq/ukkVtuWrEmmowkkF6MSjSdjiQpYo0khK/h4mNSWjZX50WZHOU5sX80Bd2mw2RRQ==} dev: false /rename-overwrite@5.0.0: @@ -4380,26 +4341,26 @@ packages: dependencies: glob: 7.2.3 - /rollup@4.9.6: - resolution: {integrity: sha512-05lzkCS2uASX0CiLFybYfVkwNbKZG5NFQ6Go0VWyogFTXXbR039UVsegViTntkk4OglHBdF54ccApXRRuXRbsg==} + /rollup@4.12.1: + resolution: {integrity: sha512-ggqQKvx/PsB0FaWXhIvVkSWh7a/PCLQAsMjBc+nA2M8Rv2/HG0X6zvixAB7KyZBRtifBUhy5k8voQX/mRnABPg==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true dependencies: '@types/estree': 1.0.5 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.9.6 - '@rollup/rollup-android-arm64': 4.9.6 - '@rollup/rollup-darwin-arm64': 4.9.6 - '@rollup/rollup-darwin-x64': 4.9.6 - '@rollup/rollup-linux-arm-gnueabihf': 4.9.6 - '@rollup/rollup-linux-arm64-gnu': 4.9.6 - '@rollup/rollup-linux-arm64-musl': 4.9.6 - '@rollup/rollup-linux-riscv64-gnu': 4.9.6 - '@rollup/rollup-linux-x64-gnu': 4.9.6 - '@rollup/rollup-linux-x64-musl': 4.9.6 - '@rollup/rollup-win32-arm64-msvc': 4.9.6 - '@rollup/rollup-win32-ia32-msvc': 4.9.6 - '@rollup/rollup-win32-x64-msvc': 4.9.6 + '@rollup/rollup-android-arm-eabi': 4.12.1 + '@rollup/rollup-android-arm64': 4.12.1 + '@rollup/rollup-darwin-arm64': 4.12.1 + '@rollup/rollup-darwin-x64': 4.12.1 + '@rollup/rollup-linux-arm-gnueabihf': 4.12.1 + '@rollup/rollup-linux-arm64-gnu': 4.12.1 + '@rollup/rollup-linux-arm64-musl': 4.12.1 + '@rollup/rollup-linux-riscv64-gnu': 4.12.1 + '@rollup/rollup-linux-x64-gnu': 4.12.1 + '@rollup/rollup-linux-x64-musl': 4.12.1 + '@rollup/rollup-win32-arm64-msvc': 4.12.1 + '@rollup/rollup-win32-ia32-msvc': 4.12.1 + '@rollup/rollup-win32-x64-msvc': 4.12.1 fsevents: 2.3.3 /run-parallel@1.2.0: @@ -4429,6 +4390,7 @@ packages: hasBin: true dependencies: lru-cache: 6.0.0 + dev: false /semver@7.6.0: resolution: {integrity: sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==} @@ -4488,18 +4450,17 @@ packages: resolution: {integrity: sha512-w5lNKEa/Az+S3d3KEX/4Xm2whJIZEoAQeRcfQggQTOlzBIXSBBm8H1NxdqfX9DWUIS4+WUse/1A/2wd9ynIBJA==} dev: true - /skott@0.32.1: - resolution: {integrity: sha512-r1X49+6Xnf5ahzf0KwoezYvyU97mo/K0tcUaIIUPaNNCG5epYxllnMZmo+XdmWmuxfk4jKcY+C5jz6Uwq69iAA==} + /skott@0.33.0: + resolution: {integrity: sha512-rllFTgVSAgdoe2gXUQ2UUQt3x9HqlfMMfQN02v4EEpWhcFRa23Gyvnk46MGY132dddv5okTrA+uS2hAmvk7hig==} hasBin: true dependencies: - '@effect/data': 0.4.1 - '@effect/io': 0.8.0 - '@parcel/watcher': 2.4.0 - '@typescript-eslint/typescript-estree': 6.20.0(typescript@5.3.3) + '@parcel/watcher': 2.4.1 + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.4.2) commander: 11.1.0 compression: 1.7.4 depcheck: 1.4.7 digraph-js: 2.2.3 + effect: 2.4.0 estree-walker: 3.0.3 fp-ts: 2.5.0 fs-tree-structure: 0.0.5 @@ -4509,14 +4470,14 @@ packages: json5: 2.2.3 kleur: 4.1.5 lodash-es: 4.17.21 - meriyah: 4.3.9 + meriyah: 4.4.0 minimatch: 9.0.3 ora: 6.3.1 parse-gitignore: 2.0.0 polka: 0.5.2 sirv: 2.0.4 skott-webapp: 2.1.1 - typescript: 5.3.3 + typescript: 5.4.2 transitivePeerDependencies: - supports-color dev: true @@ -4672,10 +4633,10 @@ packages: engines: {node: '>=14.16'} dev: true - /strip-literal@1.3.0: - resolution: {integrity: sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==} + /strip-literal@2.0.0: + resolution: {integrity: sha512-f9vHgsCWBq2ugHAkGMiiYY+AYG0D/cbloKKg0nhaaaSNsujdGIpVXCNsrJpCKr5M0f4aI31mr13UjY6GAuXCKA==} dependencies: - acorn: 8.11.3 + js-tokens: 8.0.3 /summary@2.1.0: resolution: {integrity: sha512-nMIjMrd5Z2nuB2RZCKJfFMjgS3fygbeyGk9PxPPaJR1RIcyN9yn4A63Isovzm3ZtQuEkLBVgMdPup8UeLH7aQw==} @@ -4756,8 +4717,8 @@ packages: resolution: {integrity: sha512-SUszKYe5wgsxnNOVlBYO6IC+8VGWdVGZWAqUxp3UErNBtptZvWbwyUOyzNL59zigz2rCA92QiL3wvG+JDSdJdQ==} engines: {node: '>=14.0.0'} - /tinyspy@2.2.0: - resolution: {integrity: sha512-d2eda04AN/cPOR89F7Xv5bK/jrQEhmcLFe6HFldoeO9AJtps+fqEnh486vnT/8y4bw38pSyxDcTCAq+Ks2aJTg==} + /tinyspy@2.2.1: + resolution: {integrity: sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==} engines: {node: '>=14.0.0'} /tmp-promise@3.0.3: @@ -4815,22 +4776,13 @@ packages: matchit: 1.1.0 dev: true - /ts-api-utils@1.0.3(typescript@5.3.3): - resolution: {integrity: sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==} - engines: {node: '>=16.13.0'} - peerDependencies: - typescript: '>=4.2.0' - dependencies: - typescript: 5.3.3 - - /ts-api-utils@1.2.1(typescript@5.3.3): + /ts-api-utils@1.2.1(typescript@5.4.2): resolution: {integrity: sha512-RIYA36cJn2WiH9Hy77hdF9r7oEwxAtB/TS9/S4Qd90Ap4z5FSiin5zEiTL44OII1Y3IIlEvxwxFUVgrHSZ/UpA==} engines: {node: '>=16'} peerDependencies: typescript: '>=4.2.0' dependencies: - typescript: 5.3.3 - dev: false + typescript: 5.4.2 /tslib@2.6.2: resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} @@ -4852,64 +4804,64 @@ packages: dependencies: safe-buffer: 5.2.1 - /turbo-darwin-64@1.12.4: - resolution: {integrity: sha512-dBwFxhp9isTa9RS/fz2gDVk5wWhKQsPQMozYhjM7TT4jTrnYn0ZJMzr7V3B/M/T8QF65TbniW7w1gtgxQgX5Zg==} + /turbo-darwin-64@1.12.5: + resolution: {integrity: sha512-0GZ8reftwNQgIQLHkHjHEXTc/Z1NJm+YjsrBP+qhM/7yIZ3TEy9gJhuogDt2U0xIWwFgisTyzbtU7xNaQydtoA==} cpu: [x64] os: [darwin] requiresBuild: true dev: true optional: true - /turbo-darwin-arm64@1.12.4: - resolution: {integrity: sha512-1Uo5iI6xsJ1j9ObsqxYRsa3W26mEbUe6fnj4rQYV6kDaqYD54oAMJ6hM53q9rB8JvFxwdrUXGp3PwTw9A0qqkA==} + /turbo-darwin-arm64@1.12.5: + resolution: {integrity: sha512-8WpOLNNzvH6kohQOjihD+gaWL+ZFNfjvBwhOF0rjEzvW+YR3Pa7KjhulrjWyeN2yMFqAPubTbZIGOz1EVXLuQA==} cpu: [arm64] os: [darwin] requiresBuild: true dev: true optional: true - /turbo-linux-64@1.12.4: - resolution: {integrity: sha512-ONg2aSqKP7LAQOg7ysmU5WpEQp4DGNxSlAiR7um+LKtbmC/UxogbR5+T+Uuq6zGuQ5kJyKjWJ4NhtvUswOqBsA==} + /turbo-linux-64@1.12.5: + resolution: {integrity: sha512-INit73+bNUpwqGZCxgXCR3I+cQsdkQ3/LkfkgSOibkpg+oGqxJRzeXw3sp990d7SCoE8QOcs3iw+PtiFX/LDAA==} cpu: [x64] os: [linux] requiresBuild: true dev: true optional: true - /turbo-linux-arm64@1.12.4: - resolution: {integrity: sha512-9FPufkwdgfIKg/9jj87Cdtftw8o36y27/S2vLN7FTR2pp9c0MQiTBOLVYadUr1FlShupddmaMbTkXEhyt9SdrA==} + /turbo-linux-arm64@1.12.5: + resolution: {integrity: sha512-6lkRBvxtI/GQdGtaAec9LvVQUoRw6nXFp0kM+Eu+5PbZqq7yn6cMkgDJLI08zdeui36yXhone8XGI8pHg8bpUQ==} cpu: [arm64] os: [linux] requiresBuild: true dev: true optional: true - /turbo-windows-64@1.12.4: - resolution: {integrity: sha512-2mOtxHW5Vjh/5rDVu/aFwsMzI+chs8XcEuJHlY1sYOpEymYTz+u6AXbnzRvwZFMrLKr7J7fQOGl+v96sLKbNdA==} + /turbo-windows-64@1.12.5: + resolution: {integrity: sha512-gQYbOhZg5Ww0bQ/bC0w/4W6yQRwBumUUnkB+QPo15VznwxZe2a7bo6JM+9Xy9dKLa/kn+p7zTqme4OEp6M3/Yg==} cpu: [x64] os: [win32] requiresBuild: true dev: true optional: true - /turbo-windows-arm64@1.12.4: - resolution: {integrity: sha512-nOY5wae9qnxPOpT1fRuYO0ks6dTwpKMPV6++VkDkamFDLFHUDVM/9kmD2UTeh1yyrKnrZksbb9zmShhmfj1wog==} + /turbo-windows-arm64@1.12.5: + resolution: {integrity: sha512-auvhZ9FrhnvQ4mgBlY9O68MT4dIfprYGvd2uPICba/mHUZZvVy5SGgbHJ0KbMwaJfnnFoPgLJO6M+3N2gDprKw==} cpu: [arm64] os: [win32] requiresBuild: true dev: true optional: true - /turbo@1.12.4: - resolution: {integrity: sha512-yUJ7elEUSToiGwFZogXpYKJpQ0BvaMbkEuQECIWtkBLcmWzlMOt6bActsIm29oN83mRU0WbzGt4e8H1KHWedhg==} + /turbo@1.12.5: + resolution: {integrity: sha512-FATU5EnhrYG8RvQJYFJnDd18DpccDjyvd53hggw9T9JEg9BhWtIEoeaKtBjYbpXwOVrJQMDdXcIB4f2nD3QPPg==} hasBin: true optionalDependencies: - turbo-darwin-64: 1.12.4 - turbo-darwin-arm64: 1.12.4 - turbo-linux-64: 1.12.4 - turbo-linux-arm64: 1.12.4 - turbo-windows-64: 1.12.4 - turbo-windows-arm64: 1.12.4 + turbo-darwin-64: 1.12.5 + turbo-darwin-arm64: 1.12.5 + turbo-linux-64: 1.12.5 + turbo-linux-arm64: 1.12.5 + turbo-windows-64: 1.12.5 + turbo-windows-arm64: 1.12.5 dev: true /type-check@0.4.0: @@ -4931,17 +4883,13 @@ packages: engines: {node: '>=8'} dev: true - /typescript@5.3.3: - resolution: {integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==} + /typescript@5.4.2: + resolution: {integrity: sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==} engines: {node: '>=14.17'} hasBin: true - /ufo@1.3.2: - resolution: {integrity: sha512-o+ORpgGwaYQXgqGDwd+hkS4PuZ3QnmqMMxRuajK/a38L6fTpcE5GPIfrf+L/KemFzfUpeUQc1rRS1iDBozvnFA==} - /ufo@1.4.0: resolution: {integrity: sha512-Hhy+BhRBleFjpJ2vchUNN40qgkh0366FWJGqVLYBHev0vpHTrXSA0ryT+74UiW6KWsldNurQMKGqCm1M2zBciQ==} - dev: false /undici-types@5.26.5: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} @@ -5042,8 +4990,8 @@ packages: semver: 7.6.0 dev: true - /vite-node@1.2.2(@types/node@20.11.18): - resolution: {integrity: sha512-1as4rDTgVWJO3n1uHmUYqq7nsFgINQ9u+mRcXpjeOMJUmviqNKjcZB7UfRZrlM7MjYXMKpuWp5oGkjaFLnjawg==} + /vite-node@1.3.1(@types/node@20.11.25): + resolution: {integrity: sha512-azbRrqRxlWTJEVbzInZCTchx0X69M/XPTCz4H+TLvlTcR/xH/3hkRqhOakT41fMJCMzXTu4UvegkZiEoJAWvng==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true dependencies: @@ -5051,7 +4999,7 @@ packages: debug: 4.3.4 pathe: 1.1.2 picocolors: 1.0.0 - vite: 5.0.12(@types/node@20.11.18) + vite: 5.1.5(@types/node@20.11.25) transitivePeerDependencies: - '@types/node' - less @@ -5062,8 +5010,8 @@ packages: - supports-color - terser - /vite@5.0.12(@types/node@20.11.18): - resolution: {integrity: sha512-4hsnEkG3q0N4Tzf1+t6NdN9dg/L3BM+q8SWgbSPnJvrgH2kgdyzfVJwbR1ic69/4uMJJ/3dqDZZE5/WwqW8U1w==} + /vite@5.1.5(@types/node@20.11.25): + resolution: {integrity: sha512-BdN1xh0Of/oQafhU+FvopafUp6WaYenLU/NFoL5WyJL++GxkNfieKzBhM24H3HVsPQrlAqB7iJYTHabzaRed5Q==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: @@ -5090,22 +5038,22 @@ packages: terser: optional: true dependencies: - '@types/node': 20.11.18 + '@types/node': 20.11.25 esbuild: 0.19.12 - postcss: 8.4.33 - rollup: 4.9.6 + postcss: 8.4.35 + rollup: 4.12.1 optionalDependencies: fsevents: 2.3.3 - /vitest@1.2.2(@types/node@20.11.18): - resolution: {integrity: sha512-d5Ouvrnms3GD9USIK36KG8OZ5bEvKEkITFtnGv56HFaSlbItJuYr7hv2Lkn903+AvRAgSixiamozUVfORUekjw==} + /vitest@1.3.1(@types/node@20.11.25): + resolution: {integrity: sha512-/1QJqXs8YbCrfv/GPQ05wAZf2eakUPLPa18vkJAKE7RXOKfVHqMZZ1WlTjiwl6Gcn65M5vpNUB6EFLnEdRdEXQ==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@types/node': ^18.0.0 || >=20.0.0 - '@vitest/browser': ^1.0.0 - '@vitest/ui': ^1.0.0 + '@vitest/browser': 1.3.1 + '@vitest/ui': 1.3.1 happy-dom: '*' jsdom: '*' peerDependenciesMeta: @@ -5122,27 +5070,26 @@ packages: jsdom: optional: true dependencies: - '@types/node': 20.11.18 - '@vitest/expect': 1.2.2 - '@vitest/runner': 1.2.2 - '@vitest/snapshot': 1.2.2 - '@vitest/spy': 1.2.2 - '@vitest/utils': 1.2.2 + '@types/node': 20.11.25 + '@vitest/expect': 1.3.1 + '@vitest/runner': 1.3.1 + '@vitest/snapshot': 1.3.1 + '@vitest/spy': 1.3.1 + '@vitest/utils': 1.3.1 acorn-walk: 8.3.2 - cac: 6.7.14 chai: 4.4.1 debug: 4.3.4 execa: 8.0.1 local-pkg: 0.5.0 - magic-string: 0.30.6 + magic-string: 0.30.8 pathe: 1.1.2 picocolors: 1.0.0 std-env: 3.7.0 - strip-literal: 1.3.0 + strip-literal: 2.0.0 tinybench: 2.6.0 tinypool: 0.8.2 - vite: 5.0.12(@types/node@20.11.18) - vite-node: 1.2.2(@types/node@20.11.18) + vite: 5.1.5(@types/node@20.11.25) + vite-node: 1.3.1(@types/node@20.11.25) why-is-node-running: 2.2.2 transitivePeerDependencies: - less @@ -5240,9 +5187,10 @@ packages: engines: {node: '>= 6'} dev: true - /yaml@2.3.4: - resolution: {integrity: sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==} + /yaml@2.4.1: + resolution: {integrity: sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg==} engines: {node: '>= 14'} + hasBin: true dev: false /yargs-parser@20.2.9: @@ -5260,7 +5208,7 @@ packages: engines: {node: '>=10'} dependencies: cliui: 7.0.4 - escalade: 3.1.1 + escalade: 3.1.2 get-caller-file: 2.0.5 require-directory: 2.1.1 string-width: 4.2.3 @@ -5289,8 +5237,8 @@ packages: resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==} engines: {node: '>=12.20'} - /zod-validation-error@3.0.0(zod@3.22.4): - resolution: {integrity: sha512-x+agsJJG9rvC7axF0xqTEdZhJkLHyIZkdOAWDJSmwGPzxNHMHwtU6w2yDOAAP6yuSfTAUhAMJRBfhVGY64ySEQ==} + /zod-validation-error@3.0.2(zod@3.22.4): + resolution: {integrity: sha512-21xGaDmnU7lJZ4J63n5GXWqi+rTzGy3gDHbuZ1jP6xrK/DEQGyOqs/xW7eH96tIfCOYm+ecCuT0bfajBRKEVUw==} engines: {node: '>=18.0.0'} peerDependencies: zod: ^3.18.0