diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a5f91755e..3b7f8cbba 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -222,7 +222,7 @@ To understand how test should be created and run - please check [Run tests](#-ru 📂 extensions/ - all the extension helpers for databases -📂 serialaizer/ - all the necessary logic to read from the Drizzle ORM schema and convert it to a common JSON format, as well as the logic to introspect all tables, types, and other database elements and convert them to a common JSON format +📂 serializer/ - all the necessary logic to read from the Drizzle ORM schema and convert it to a common JSON format, as well as the logic to introspect all tables, types, and other database elements and convert them to a common JSON format 📄 introspect-pg.ts, introspect-mysql.ts, introspect-sqlite.ts - these files are responsible for mapping JSON snapshots to TypeScript files during introspect commands diff --git a/changelogs/drizzle-kit/0.27.0.md b/changelogs/drizzle-kit/0.27.0.md new file mode 100644 index 000000000..e4f51fdb3 --- /dev/null +++ b/changelogs/drizzle-kit/0.27.0.md @@ -0,0 +1,421 @@ +> This version of `drizzle-jit` requires `drizzle-orm@0.36.0` to enable all new features + +# New Features + +## Row-Level Security (RLS) + +With Drizzle, you can enable Row-Level Security (RLS) for any Postgres table, create policies with various options, and define and manage the roles those policies apply to. + +Drizzle supports a raw representation of Postgres policies and roles that can be used in any way you want. This works with popular Postgres database providers such as `Neon` and `Supabase`. + +In Drizzle, we have specific predefined RLS roles and functions for RLS with both database providers, but you can also define your own logic. + +### Enable RLS + +If you just want to enable RLS on a table without adding policies, you can use `.enableRLS()` + +As mentioned in the PostgreSQL documentation: + +> If no policy exists for the table, a default-deny policy is used, meaning that no rows are visible or can be modified. +Operations that apply to the whole table, such as TRUNCATE and REFERENCES, are not subject to row security. + +```ts +import { integer, pgTable } from 'drizzle-orm/pg-core'; + +export const users = pgTable('users', { + id: integer(), +}).enableRLS(); +``` + +> If you add a policy to a table, RLS will be enabled automatically. So, there’s no need to explicitly enable RLS when adding policies to a table. + +### Roles + +Currently, Drizzle supports defining roles with a few different options, as shown below. Support for more options will be added in a future release. + +```ts +import { pgRole } from 'drizzle-orm/pg-core'; + +export const admin = pgRole('admin', { createRole: true, createDb: true, inherit: true }); +``` + +If a role already exists in your database, and you don’t want drizzle-kit to ‘see’ it or include it in migrations, you can mark the role as existing. + +```ts +import { pgRole } from 'drizzle-orm/pg-core'; + +export const admin = pgRole('admin').existing(); +``` + +### Policies + +To fully leverage RLS, you can define policies within a Drizzle table. + +> In PostgreSQL, policies should be linked to an existing table. Since policies are always associated with a specific table, we decided that policy definitions should be defined as a parameter of `pgTable` + +**Example of pgPolicy with all available properties** +```ts +import { sql } from 'drizzle-orm'; +import { integer, pgPolicy, pgRole, pgTable } from 'drizzle-orm/pg-core'; + +export const admin = pgRole('admin'); + +export const users = pgTable('users', { + id: integer(), +}, (t) => [ + pgPolicy('policy', { + as: 'permissive', + to: admin, + for: 'delete', + using: sql``, + withCheck: sql``, + }), +]); +``` + +**Link Policy to an existing table** + +There are situations where you need to link a policy to an existing table in your database. +The most common use case is with database providers like `Neon` or `Supabase`, where you need to add a policy +to their existing tables. In this case, you can use the `.link()` API + +```ts +import { sql } from "drizzle-orm"; +import { pgPolicy } from "drizzle-orm/pg-core"; +import { authenticatedRole, realtimeMessages } from "drizzle-orm/supabase"; + +export const policy = pgPolicy("authenticated role insert policy", { + for: "insert", + to: authenticatedRole, + using: sql``, +}).link(realtimeMessages); +``` + +### Migrations + +If you are using drizzle-kit to manage your schema and roles, there may be situations where you want to refer to roles that are not defined in your Drizzle schema. In such cases, you may want drizzle-kit to skip managing these roles without having to define each role in your drizzle schema and marking it with `.existing()`. + +In these cases, you can use `entities.roles` in `drizzle.config.ts`. For a complete reference, refer to the the [`drizzle.config.ts`](https://orm.drizzle.team/docs/drizzle-config-file) documentation. + +By default, `drizzle-kit` does not manage roles for you, so you will need to enable this feature in `drizzle.config.ts`. + +```ts {12-14} +// drizzle.config.ts +import { defineConfig } from "drizzle-kit"; + +export default defineConfig({ + dialect: 'postgresql', + schema: "./drizzle/schema.ts", + dbCredentials: { + url: process.env.DATABASE_URL! + }, + verbose: true, + strict: true, + entities: { + roles: true + } +}); +``` + +In case you need additional configuration options, let's take a look at a few more examples. + +**You have an `admin` role and want to exclude it from the list of manageable roles** + +```ts +// drizzle.config.ts +import { defineConfig } from "drizzle-kit"; + +export default defineConfig({ + ... + entities: { + roles: { + exclude: ['admin'] + } + } +}); +``` + +**You have an `admin` role and want to include it in the list of manageable roles** + +```ts +// drizzle.config.ts +import { defineConfig } from "drizzle-kit"; + +export default defineConfig({ + ... + entities: { + roles: { + include: ['admin'] + } + } +}); +``` + +**If you are using `Neon` and want to exclude Neon-defined roles, you can use the provider option** + +```ts +// drizzle.config.ts +import { defineConfig } from "drizzle-kit"; + +export default defineConfig({ + ... + entities: { + roles: { + provider: 'neon' + } + } +}); +``` + +**If you are using `Supabase` and want to exclude Supabase-defined roles, you can use the provider option** + +```ts +// drizzle.config.ts +import { defineConfig } from "drizzle-kit"; + +export default defineConfig({ + ... + entities: { + roles: { + provider: 'supabase' + } + } +}); +``` + +> You may encounter situations where Drizzle is slightly outdated compared to new roles specified by your database provider. +In such cases, you can use the `provider` option and `exclude` additional roles: + +```ts +// drizzle.config.ts +import { defineConfig } from "drizzle-kit"; + +export default defineConfig({ + ... + entities: { + roles: { + provider: 'supabase', + exclude: ['new_supabase_role'] + } + } +}); +``` + +### RLS on views + +With Drizzle, you can also specify RLS policies on views. For this, you need to use `security_invoker` in the view's WITH options. Here is a small example: + +```ts {5} +... + +export const roomsUsersProfiles = pgView("rooms_users_profiles") + .with({ + securityInvoker: true, + }) + .as((qb) => + qb + .select({ + ...getTableColumns(roomsUsers), + email: profiles.email, + }) + .from(roomsUsers) + .innerJoin(profiles, eq(roomsUsers.userId, profiles.id)) + ); +``` + +### Using with Neon + +The Neon Team helped us implement their vision of a wrapper on top of our raw policies API. We defined a specific +`/neon` import with the `crudPolicy` function that includes predefined functions and Neon's default roles. + +Here's an example of how to use the `crudPolicy` function: + +```ts +import { crudPolicy } from 'drizzle-orm/neon'; +import { integer, pgRole, pgTable } from 'drizzle-orm/pg-core'; + +export const admin = pgRole('admin'); + +export const users = pgTable('users', { + id: integer(), +}, (t) => [ + crudPolicy({ role: admin, read: true, modify: false }), +]); +``` + +This policy is equivalent to: + +```ts +import { sql } from 'drizzle-orm'; +import { integer, pgPolicy, pgRole, pgTable } from 'drizzle-orm/pg-core'; + +export const admin = pgRole('admin'); + +export const users = pgTable('users', { + id: integer(), +}, (t) => [ + pgPolicy(`crud-${admin.name}-policy-insert`, { + for: 'insert', + to: admin, + withCheck: sql`false`, + }), + pgPolicy(`crud-${admin.name}-policy-update`, { + for: 'update', + to: admin, + using: sql`false`, + withCheck: sql`false`, + }), + pgPolicy(`crud-${admin.name}-policy-delete`, { + for: 'delete', + to: admin, + using: sql`false`, + }), + pgPolicy(`crud-${admin.name}-policy-select`, { + for: 'select', + to: admin, + using: sql`true`, + }), +]); +``` + +`Neon` exposes predefined `authenticated` and `anaonymous` roles and related functions. If you are using `Neon` for RLS, you can use these roles, which are marked as existing, and the related functions in your RLS queries. + +```ts +// drizzle-orm/neon +export const authenticatedRole = pgRole('authenticated').existing(); +export const anonymousRole = pgRole('anonymous').existing(); + +export const authUid = (userIdColumn: AnyPgColumn) => sql`(select auth.user_id() = ${userIdColumn})`; +``` + +For example, you can use the `Neon` predefined roles and functions like this: + + +```ts +import { sql } from 'drizzle-orm'; +import { authenticatedRole } from 'drizzle-orm/neon'; +import { integer, pgPolicy, pgRole, pgTable } from 'drizzle-orm/pg-core'; + +export const admin = pgRole('admin'); + +export const users = pgTable('users', { + id: integer(), +}, (t) => [ + pgPolicy(`policy-insert`, { + for: 'insert', + to: authenticatedRole, + withCheck: sql`false`, + }), +]); +``` + +### Using with Supabase + +We also have a `/supabase` import with a set of predefined roles marked as existing, which you can use in your schema. +This import will be extended in a future release with more functions and helpers to make using RLS and `Supabase` simpler. + +```ts +// drizzle-orm/supabase +export const anonRole = pgRole('anon').existing(); +export const authenticatedRole = pgRole('authenticated').existing(); +export const serviceRole = pgRole('service_role').existing(); +export const postgresRole = pgRole('postgres_role').existing(); +export const supabaseAuthAdminRole = pgRole('supabase_auth_admin').existing(); +``` + +For example, you can use the `Supabase` predefined roles like this: + +```ts +import { sql } from 'drizzle-orm'; +import { serviceRole } from 'drizzle-orm/supabase'; +import { integer, pgPolicy, pgRole, pgTable } from 'drizzle-orm/pg-core'; + +export const admin = pgRole('admin'); + +export const users = pgTable('users', { + id: integer(), +}, (t) => [ + pgPolicy(`policy-insert`, { + for: 'insert', + to: serviceRole, + withCheck: sql`false`, + }), +]); +``` + +The `/supabase` import also includes predefined tables and functions that you can use in your application + +```ts +// drizzle-orm/supabase + +const auth = pgSchema('auth'); +export const authUsers = auth.table('users', { + id: uuid().primaryKey().notNull(), +}); + +const realtime = pgSchema('realtime'); +export const realtimeMessages = realtime.table( + 'messages', + { + id: bigserial({ mode: 'bigint' }).primaryKey(), + topic: text().notNull(), + extension: text({ + enum: ['presence', 'broadcast', 'postgres_changes'], + }).notNull(), + }, +); + +export const authUid = sql`(select auth.uid())`; +export const realtimeTopic = sql`realtime.topic()`; +``` + +This allows you to use it in your code, and Drizzle Kit will treat them as existing databases, +using them only as information to connect to other entities + +```ts +import { foreignKey, pgPolicy, pgTable, text, uuid } from "drizzle-orm/pg-core"; +import { sql } from "drizzle-orm/sql"; +import { authenticatedRole, authUsers } from "drizzle-orm/supabase"; + +export const profiles = pgTable( + "profiles", + { + id: uuid().primaryKey().notNull(), + email: text().notNull(), + }, + (table) => [ + foreignKey({ + columns: [table.id], + // reference to the auth table from Supabase + foreignColumns: [authUsers.id], + name: "profiles_id_fk", + }).onDelete("cascade"), + pgPolicy("authenticated can view all profiles", { + for: "select", + // using predefined role from Supabase + to: authenticatedRole, + using: sql`true`, + }), + ] +); +``` + +Let's check an example of adding a policy to a table that exists in `Supabase` + +```ts +import { sql } from "drizzle-orm"; +import { pgPolicy } from "drizzle-orm/pg-core"; +import { authenticatedRole, realtimeMessages } from "drizzle-orm/supabase"; + +export const policy = pgPolicy("authenticated role insert policy", { + for: "insert", + to: authenticatedRole, + using: sql``, +}).link(realtimeMessages); +``` + +# Bug fixes + +- [[BUG]: Studio + mysql default mode, wrong format related timezone](https://github.com/drizzle-team/drizzle-orm/issues/2747) +- [[BUG]: Drizzle Studio CORS error](https://github.com/drizzle-team/drizzle-orm/issues/1857) +- [[BUG]: TIMESTAMPS showing up incorrectly on drizzle studio](https://github.com/drizzle-team/drizzle-orm/issues/2549) \ No newline at end of file diff --git a/changelogs/drizzle-orm/0.36.0.md b/changelogs/drizzle-orm/0.36.0.md new file mode 100644 index 000000000..0f01b6e91 --- /dev/null +++ b/changelogs/drizzle-orm/0.36.0.md @@ -0,0 +1,419 @@ +> This version of `drizzle-orm` requires `drizzle-kit@0.27.0` to enable all new features + +# New Features + +## Row-Level Security (RLS) + +With Drizzle, you can enable Row-Level Security (RLS) for any Postgres table, create policies with various options, and define and manage the roles those policies apply to. + +Drizzle supports a raw representation of Postgres policies and roles that can be used in any way you want. This works with popular Postgres database providers such as `Neon` and `Supabase`. + +In Drizzle, we have specific predefined RLS roles and functions for RLS with both database providers, but you can also define your own logic. + +### Enable RLS + +If you just want to enable RLS on a table without adding policies, you can use `.enableRLS()` + +As mentioned in the PostgreSQL documentation: + +> If no policy exists for the table, a default-deny policy is used, meaning that no rows are visible or can be modified. +Operations that apply to the whole table, such as TRUNCATE and REFERENCES, are not subject to row security. + +```ts +import { integer, pgTable } from 'drizzle-orm/pg-core'; + +export const users = pgTable('users', { + id: integer(), +}).enableRLS(); +``` + +> If you add a policy to a table, RLS will be enabled automatically. So, there’s no need to explicitly enable RLS when adding policies to a table. + +### Roles + +Currently, Drizzle supports defining roles with a few different options, as shown below. Support for more options will be added in a future release. + +```ts +import { pgRole } from 'drizzle-orm/pg-core'; + +export const admin = pgRole('admin', { createRole: true, createDb: true, inherit: true }); +``` + +If a role already exists in your database, and you don’t want drizzle-kit to ‘see’ it or include it in migrations, you can mark the role as existing. + +```ts +import { pgRole } from 'drizzle-orm/pg-core'; + +export const admin = pgRole('admin').existing(); +``` + +### Policies + +To fully leverage RLS, you can define policies within a Drizzle table. + +> In PostgreSQL, policies should be linked to an existing table. Since policies are always associated with a specific table, we decided that policy definitions should be defined as a parameter of `pgTable` + +**Example of pgPolicy with all available properties** +```ts +import { sql } from 'drizzle-orm'; +import { integer, pgPolicy, pgRole, pgTable } from 'drizzle-orm/pg-core'; + +export const admin = pgRole('admin'); + +export const users = pgTable('users', { + id: integer(), +}, (t) => [ + pgPolicy('policy', { + as: 'permissive', + to: admin, + for: 'delete', + using: sql``, + withCheck: sql``, + }), +]); +``` + +**Link Policy to an existing table** + +There are situations where you need to link a policy to an existing table in your database. +The most common use case is with database providers like `Neon` or `Supabase`, where you need to add a policy +to their existing tables. In this case, you can use the `.link()` API + +```ts +import { sql } from "drizzle-orm"; +import { pgPolicy } from "drizzle-orm/pg-core"; +import { authenticatedRole, realtimeMessages } from "drizzle-orm/supabase"; + +export const policy = pgPolicy("authenticated role insert policy", { + for: "insert", + to: authenticatedRole, + using: sql``, +}).link(realtimeMessages); +``` + +### Migrations + +If you are using drizzle-kit to manage your schema and roles, there may be situations where you want to refer to roles that are not defined in your Drizzle schema. In such cases, you may want drizzle-kit to skip managing these roles without having to define each role in your drizzle schema and marking it with `.existing()`. + +In these cases, you can use `entities.roles` in `drizzle.config.ts`. For a complete reference, refer to the the [`drizzle.config.ts`](https://orm.drizzle.team/docs/drizzle-config-file) documentation. + +By default, `drizzle-kit` does not manage roles for you, so you will need to enable this feature in `drizzle.config.ts`. + +```ts {12-14} +// drizzle.config.ts +import { defineConfig } from "drizzle-kit"; + +export default defineConfig({ + dialect: 'postgresql', + schema: "./drizzle/schema.ts", + dbCredentials: { + url: process.env.DATABASE_URL! + }, + verbose: true, + strict: true, + entities: { + roles: true + } +}); +``` + +In case you need additional configuration options, let's take a look at a few more examples. + +**You have an `admin` role and want to exclude it from the list of manageable roles** + +```ts +// drizzle.config.ts +import { defineConfig } from "drizzle-kit"; + +export default defineConfig({ + ... + entities: { + roles: { + exclude: ['admin'] + } + } +}); +``` + +**You have an `admin` role and want to include it in the list of manageable roles** + +```ts +// drizzle.config.ts +import { defineConfig } from "drizzle-kit"; + +export default defineConfig({ + ... + entities: { + roles: { + include: ['admin'] + } + } +}); +``` + +**If you are using `Neon` and want to exclude Neon-defined roles, you can use the provider option** + +```ts +// drizzle.config.ts +import { defineConfig } from "drizzle-kit"; + +export default defineConfig({ + ... + entities: { + roles: { + provider: 'neon' + } + } +}); +``` + +**If you are using `Supabase` and want to exclude Supabase-defined roles, you can use the provider option** + +```ts +// drizzle.config.ts +import { defineConfig } from "drizzle-kit"; + +export default defineConfig({ + ... + entities: { + roles: { + provider: 'supabase' + } + } +}); +``` + +> You may encounter situations where Drizzle is slightly outdated compared to new roles specified by your database provider. +In such cases, you can use the `provider` option and `exclude` additional roles: + +```ts +// drizzle.config.ts +import { defineConfig } from "drizzle-kit"; + +export default defineConfig({ + ... + entities: { + roles: { + provider: 'supabase', + exclude: ['new_supabase_role'] + } + } +}); +``` + +### RLS on views + +With Drizzle, you can also specify RLS policies on views. For this, you need to use `security_invoker` in the view's WITH options. Here is a small example: + +```ts {5} +... + +export const roomsUsersProfiles = pgView("rooms_users_profiles") + .with({ + securityInvoker: true, + }) + .as((qb) => + qb + .select({ + ...getTableColumns(roomsUsers), + email: profiles.email, + }) + .from(roomsUsers) + .innerJoin(profiles, eq(roomsUsers.userId, profiles.id)) + ); +``` + +### Using with Neon + +The Neon Team helped us implement their vision of a wrapper on top of our raw policies API. We defined a specific +`/neon` import with the `crudPolicy` function that includes predefined functions and Neon's default roles. + +Here's an example of how to use the `crudPolicy` function: + +```ts +import { crudPolicy } from 'drizzle-orm/neon'; +import { integer, pgRole, pgTable } from 'drizzle-orm/pg-core'; + +export const admin = pgRole('admin'); + +export const users = pgTable('users', { + id: integer(), +}, (t) => [ + crudPolicy({ role: admin, read: true, modify: false }), +]); +``` + +This policy is equivalent to: + +```ts +import { sql } from 'drizzle-orm'; +import { integer, pgPolicy, pgRole, pgTable } from 'drizzle-orm/pg-core'; + +export const admin = pgRole('admin'); + +export const users = pgTable('users', { + id: integer(), +}, (t) => [ + pgPolicy(`crud-${admin.name}-policy-insert`, { + for: 'insert', + to: admin, + withCheck: sql`false`, + }), + pgPolicy(`crud-${admin.name}-policy-update`, { + for: 'update', + to: admin, + using: sql`false`, + withCheck: sql`false`, + }), + pgPolicy(`crud-${admin.name}-policy-delete`, { + for: 'delete', + to: admin, + using: sql`false`, + }), + pgPolicy(`crud-${admin.name}-policy-select`, { + for: 'select', + to: admin, + using: sql`true`, + }), +]); +``` + +`Neon` exposes predefined `authenticated` and `anaonymous` roles and related functions. If you are using `Neon` for RLS, you can use these roles, which are marked as existing, and the related functions in your RLS queries. + +```ts +// drizzle-orm/neon +export const authenticatedRole = pgRole('authenticated').existing(); +export const anonymousRole = pgRole('anonymous').existing(); + +export const authUid = (userIdColumn: AnyPgColumn) => sql`(select auth.user_id() = ${userIdColumn})`; +``` + +For example, you can use the `Neon` predefined roles and functions like this: + + +```ts +import { sql } from 'drizzle-orm'; +import { authenticatedRole } from 'drizzle-orm/neon'; +import { integer, pgPolicy, pgRole, pgTable } from 'drizzle-orm/pg-core'; + +export const admin = pgRole('admin'); + +export const users = pgTable('users', { + id: integer(), +}, (t) => [ + pgPolicy(`policy-insert`, { + for: 'insert', + to: authenticatedRole, + withCheck: sql`false`, + }), +]); +``` + +### Using with Supabase + +We also have a `/supabase` import with a set of predefined roles marked as existing, which you can use in your schema. +This import will be extended in a future release with more functions and helpers to make using RLS and `Supabase` simpler. + +```ts +// drizzle-orm/supabase +export const anonRole = pgRole('anon').existing(); +export const authenticatedRole = pgRole('authenticated').existing(); +export const serviceRole = pgRole('service_role').existing(); +export const postgresRole = pgRole('postgres_role').existing(); +export const supabaseAuthAdminRole = pgRole('supabase_auth_admin').existing(); +``` + +For example, you can use the `Supabase` predefined roles like this: + +```ts +import { sql } from 'drizzle-orm'; +import { serviceRole } from 'drizzle-orm/supabase'; +import { integer, pgPolicy, pgRole, pgTable } from 'drizzle-orm/pg-core'; + +export const admin = pgRole('admin'); + +export const users = pgTable('users', { + id: integer(), +}, (t) => [ + pgPolicy(`policy-insert`, { + for: 'insert', + to: serviceRole, + withCheck: sql`false`, + }), +]); +``` + +The `/supabase` import also includes predefined tables and functions that you can use in your application + +```ts +// drizzle-orm/supabase + +const auth = pgSchema('auth'); +export const authUsers = auth.table('users', { + id: uuid().primaryKey().notNull(), +}); + +const realtime = pgSchema('realtime'); +export const realtimeMessages = realtime.table( + 'messages', + { + id: bigserial({ mode: 'bigint' }).primaryKey(), + topic: text().notNull(), + extension: text({ + enum: ['presence', 'broadcast', 'postgres_changes'], + }).notNull(), + }, +); + +export const authUid = sql`(select auth.uid())`; +export const realtimeTopic = sql`realtime.topic()`; +``` + +This allows you to use it in your code, and Drizzle Kit will treat them as existing databases, +using them only as information to connect to other entities + +```ts +import { foreignKey, pgPolicy, pgTable, text, uuid } from "drizzle-orm/pg-core"; +import { sql } from "drizzle-orm/sql"; +import { authenticatedRole, authUsers } from "drizzle-orm/supabase"; + +export const profiles = pgTable( + "profiles", + { + id: uuid().primaryKey().notNull(), + email: text().notNull(), + }, + (table) => [ + foreignKey({ + columns: [table.id], + // reference to the auth table from Supabase + foreignColumns: [authUsers.id], + name: "profiles_id_fk", + }).onDelete("cascade"), + pgPolicy("authenticated can view all profiles", { + for: "select", + // using predefined role from Supabase + to: authenticatedRole, + using: sql`true`, + }), + ] +); +``` + +Let's check an example of adding a policy to a table that exists in `Supabase` + +```ts +import { sql } from "drizzle-orm"; +import { pgPolicy } from "drizzle-orm/pg-core"; +import { authenticatedRole, realtimeMessages } from "drizzle-orm/supabase"; + +export const policy = pgPolicy("authenticated role insert policy", { + for: "insert", + to: authenticatedRole, + using: sql``, +}).link(realtimeMessages); +``` + +# Bug fixes + +- [[BUG]: postgres-js driver throws error when using new { client } constructor arguments ](https://github.com/drizzle-team/drizzle-orm/issues/3176) \ No newline at end of file diff --git a/drizzle-kit/.gitignore b/drizzle-kit/.gitignore index 8d2cf5a81..6269daaf5 100644 --- a/drizzle-kit/.gitignore +++ b/drizzle-kit/.gitignore @@ -13,6 +13,7 @@ !package.json !tsconfig.json !tsconfig.cli-types.json +!tsconfig.build.json !pnpm-lock.yaml !.github !build.ts diff --git a/drizzle-kit/package.json b/drizzle-kit/package.json index 7499a7ec1..36822a052 100644 --- a/drizzle-kit/package.json +++ b/drizzle-kit/package.json @@ -1,6 +1,6 @@ { "name": "drizzle-kit", - "version": "0.26.2", + "version": "0.27.0", "homepage": "https://orm.drizzle.team", "keywords": [ "drizzle", @@ -34,15 +34,15 @@ "api": "tsx ./dev/api.ts", "migrate:old": "drizzle-kit generate:mysql", "cli": "tsx ./src/cli/index.ts", - "test": "TEST_CONFIG_PATH_PREFIX=./tests/cli/ vitest", + "test": "pnpm tsc && TEST_CONFIG_PATH_PREFIX=./tests/cli/ vitest", "build": "rm -rf ./dist && tsx build.ts && cp package.json dist/ && attw --pack dist", "build:dev": "rm -rf ./dist && tsx build.dev.ts && tsc -p tsconfig.cli-types.json && chmod +x ./dist/index.cjs", "pack": "cp package.json README.md dist/ && (cd dist && npm pack --pack-destination ..) && rm -f package.tgz && mv *.tgz package.tgz", - "tsc": "tsc -p tsconfig.build.json", + "tsc": "tsc -p tsconfig.build.json --noEmit", "publish": "npm publish package.tgz" }, "dependencies": { - "@drizzle-team/brocli": "^0.10.1", + "@drizzle-team/brocli": "^0.10.2", "@esbuild-kit/esm-loader": "^2.5.5", "esbuild": "^0.19.7", "esbuild-register": "^3.5.0" @@ -103,7 +103,7 @@ "superjson": "^2.2.1", "tsup": "^8.0.2", "tsx": "^3.12.1", - "typescript": "^5.4.3", + "typescript": "^5.6.3", "uuid": "^9.0.1", "vite-tsconfig-paths": "^4.3.2", "vitest": "^1.4.0", diff --git a/drizzle-kit/pnpm-lock.yaml b/drizzle-kit/pnpm-lock.yaml deleted file mode 100644 index 8f4d58f55..000000000 --- a/drizzle-kit/pnpm-lock.yaml +++ /dev/null @@ -1,7603 +0,0 @@ -lockfileVersion: '9.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -patchedDependencies: - difflib@0.2.4: - hash: jq4t3ysdpnbunjeje4v7nrqn2q - path: patches/difflib@0.2.4.patch - -importers: - - .: - dependencies: - '@esbuild-kit/esm-loader': - specifier: ^2.5.5 - version: 2.6.5 - esbuild: - specifier: ^0.19.7 - version: 0.19.12 - esbuild-register: - specifier: ^3.5.0 - version: 3.5.0(esbuild@0.19.12) - devDependencies: - '@arethetypeswrong/cli': - specifier: ^0.15.3 - version: 0.15.3 - '@aws-sdk/client-rds-data': - specifier: ^3.556.0 - version: 3.577.0 - '@cloudflare/workers-types': - specifier: ^4.20230518.0 - version: 4.20240512.0 - '@electric-sql/pglite': - specifier: ^0.1.5 - version: 0.1.5 - '@hono/node-server': - specifier: ^1.9.0 - version: 1.11.1 - '@hono/zod-validator': - specifier: ^0.2.1 - version: 0.2.1(hono@4.3.9)(zod@3.23.8) - '@libsql/client': - specifier: ^0.4.2 - version: 0.4.3(bufferutil@4.0.8)(utf-8-validate@6.0.3) - '@neondatabase/serverless': - specifier: ^0.9.1 - version: 0.9.3 - '@originjs/vite-plugin-commonjs': - specifier: ^1.0.3 - version: 1.0.3 - '@planetscale/database': - specifier: ^1.16.0 - version: 1.18.0 - '@types/better-sqlite3': - specifier: ^7.6.4 - version: 7.6.10 - '@types/dockerode': - specifier: ^3.3.28 - version: 3.3.29 - '@types/glob': - specifier: ^8.1.0 - version: 8.1.0 - '@types/json-diff': - specifier: ^1.0.3 - version: 1.0.3 - '@types/minimatch': - specifier: ^5.1.2 - version: 5.1.2 - '@types/node': - specifier: ^18.11.15 - version: 18.19.33 - '@types/pg': - specifier: ^8.10.7 - version: 8.11.6 - '@types/pluralize': - specifier: ^0.0.33 - version: 0.0.33 - '@types/semver': - specifier: ^7.5.5 - version: 7.5.8 - '@types/uuid': - specifier: ^9.0.8 - version: 9.0.8 - '@types/ws': - specifier: ^8.5.10 - version: 8.5.10 - '@typescript-eslint/eslint-plugin': - specifier: ^7.2.0 - version: 7.10.0(@typescript-eslint/parser@7.10.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5) - '@typescript-eslint/parser': - specifier: ^7.2.0 - version: 7.10.0(eslint@8.57.0)(typescript@5.4.5) - '@vercel/postgres': - specifier: ^0.8.0 - version: 0.8.0 - ava: - specifier: ^5.1.0 - version: 5.3.1 - better-sqlite3: - specifier: ^9.4.3 - version: 9.6.0 - camelcase: - specifier: ^7.0.1 - version: 7.0.1 - chalk: - specifier: ^5.2.0 - version: 5.3.0 - commander: - specifier: ^12.1.0 - version: 12.1.0 - dockerode: - specifier: ^3.3.4 - version: 3.3.5 - dotenv: - specifier: ^16.0.3 - version: 16.4.5 - drizzle-kit: - specifier: 0.21.2 - version: 0.21.2 - drizzle-orm: - specifier: 0.32.0-85c8008 - version: 0.32.0-85c8008(@aws-sdk/client-rds-data@3.577.0)(@cloudflare/workers-types@4.20240512.0)(@electric-sql/pglite@0.1.5)(@libsql/client@0.4.3(bufferutil@4.0.8)(utf-8-validate@6.0.3))(@neondatabase/serverless@0.9.3)(@planetscale/database@1.18.0)(@types/better-sqlite3@7.6.10)(@types/pg@8.11.6)(@vercel/postgres@0.8.0)(better-sqlite3@9.6.0)(mysql2@2.3.3)(pg@8.11.5)(postgres@3.4.4) - env-paths: - specifier: ^3.0.0 - version: 3.0.0 - esbuild-node-externals: - specifier: ^1.9.0 - version: 1.13.1(esbuild@0.19.12) - eslint: - specifier: ^8.57.0 - version: 8.57.0 - eslint-config-prettier: - specifier: ^9.1.0 - version: 9.1.0(eslint@8.57.0) - eslint-plugin-prettier: - specifier: ^5.1.3 - version: 5.1.3(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@8.57.0)(prettier@2.8.8) - get-port: - specifier: ^6.1.2 - version: 6.1.2 - glob: - specifier: ^8.1.0 - version: 8.1.0 - hanji: - specifier: ^0.0.5 - version: 0.0.5 - hono: - specifier: ^4.1.5 - version: 4.3.9 - json-diff: - specifier: 1.0.6 - version: 1.0.6 - minimatch: - specifier: ^7.4.3 - version: 7.4.6 - mysql2: - specifier: 2.3.3 - version: 2.3.3 - node-fetch: - specifier: ^3.3.2 - version: 3.3.2 - pg: - specifier: ^8.11.5 - version: 8.11.5 - pluralize: - specifier: ^8.0.0 - version: 8.0.0 - postgres: - specifier: ^3.4.4 - version: 3.4.4 - prettier: - specifier: ^2.8.1 - version: 2.8.8 - semver: - specifier: ^7.5.4 - version: 7.6.2 - superjson: - specifier: ^2.2.1 - version: 2.2.1 - tsup: - specifier: ^8.0.2 - version: 8.0.2(postcss@8.4.38)(typescript@5.4.5) - tsx: - specifier: ^3.12.1 - version: 3.14.0 - typescript: - specifier: ^5.4.3 - version: 5.4.5 - uuid: - specifier: ^9.0.1 - version: 9.0.1 - vite-tsconfig-paths: - specifier: ^4.3.2 - version: 4.3.2(typescript@5.4.5)(vite@5.2.11(@types/node@18.19.33)) - vitest: - specifier: ^1.4.0 - version: 1.6.0(@types/node@18.19.33) - wrangler: - specifier: ^3.22.1 - version: 3.57.0(@cloudflare/workers-types@4.20240512.0)(bufferutil@4.0.8)(utf-8-validate@6.0.3) - ws: - specifier: ^8.16.0 - version: 8.17.0(bufferutil@4.0.8)(utf-8-validate@6.0.3) - zod: - specifier: ^3.20.2 - version: 3.23.8 - zx: - specifier: ^7.2.2 - version: 7.2.3 - -packages: - - '@andrewbranch/untar.js@1.0.3': - resolution: {integrity: sha512-Jh15/qVmrLGhkKJBdXlK1+9tY4lZruYjsgkDFj08ZmDiWVBLJcqkok7Z0/R0In+i1rScBpJlSvrTS2Lm41Pbnw==} - - '@arethetypeswrong/cli@0.15.3': - resolution: {integrity: sha512-sIMA9ZJBWDEg1+xt5RkAEflZuf8+PO8SdKj17x6PtETuUho+qlZJg4DgmKc3q+QwQ9zOB5VLK6jVRbFdNLdUIA==} - engines: {node: '>=18'} - hasBin: true - - '@arethetypeswrong/core@0.15.1': - resolution: {integrity: sha512-FYp6GBAgsNz81BkfItRz8RLZO03w5+BaeiPma1uCfmxTnxbtuMrI/dbzGiOk8VghO108uFI0oJo0OkewdSHw7g==} - engines: {node: '>=18'} - - '@aws-crypto/ie11-detection@3.0.0': - resolution: {integrity: sha512-341lBBkiY1DfDNKai/wXM3aujNBkXR7tq1URPQDL9wi3AUbI80NR74uF1TXHMm7po1AcnFk8iu2S2IeU/+/A+Q==} - - '@aws-crypto/sha256-browser@3.0.0': - resolution: {integrity: sha512-8VLmW2B+gjFbU5uMeqtQM6Nj0/F1bro80xQXCW6CQBWgosFWXTx77aeOF5CAIAmbOK64SdMBJdNr6J41yP5mvQ==} - - '@aws-crypto/sha256-js@3.0.0': - resolution: {integrity: sha512-PnNN7os0+yd1XvXAy23CFOmTbMaDxgxXtTKHybrJ39Y8kGzBATgBFibWJKH6BhytLI/Zyszs87xCOBNyBig6vQ==} - - '@aws-crypto/supports-web-crypto@3.0.0': - resolution: {integrity: sha512-06hBdMwUAb2WFTuGG73LSC0wfPu93xWwo5vL2et9eymgmu3Id5vFAHBbajVWiGhPO37qcsdCap/FqXvJGJWPIg==} - - '@aws-crypto/util@3.0.0': - resolution: {integrity: sha512-2OJlpeJpCR48CC8r+uKVChzs9Iungj9wkZrl8Z041DWEWvyIHILYKCPNzJghKsivj+S3mLo6BVc7mBNzdxA46w==} - - '@aws-sdk/client-rds-data@3.577.0': - resolution: {integrity: sha512-24a27II6UkNhe2RB6ZwtQPcM3QB/DuRcKvzMmfvipgWS72Q5FEtuq3CO66IObWUel/pxi3ucE6mSvVCFnm7tBQ==} - engines: {node: '>=16.0.0'} - - '@aws-sdk/client-sso-oidc@3.577.0': - resolution: {integrity: sha512-njmKSPDWueWWYVFpFcZ2P3fI6/pdQVDa0FgCyYZhOnJLgEHZIcBBg1AsnkVWacBuLopp9XVt2m+7hO6ugY1/1g==} - engines: {node: '>=16.0.0'} - - '@aws-sdk/client-sso@3.577.0': - resolution: {integrity: sha512-BwujdXrydlk6UEyPmewm5GqG4nkQ6OVyRhS/SyZP/6UKSFv2/sf391Cmz0hN0itUTH1rR4XeLln8XCOtarkrzg==} - engines: {node: '>=16.0.0'} - - '@aws-sdk/client-sts@3.577.0': - resolution: {integrity: sha512-509Kklimva1XVlhGbpTpeX3kOP6ORpm44twJxDHpa9TURbmoaxj7veWlnLCbDorxDTrbsDghvYZshvcLsojVpg==} - engines: {node: '>=16.0.0'} - - '@aws-sdk/core@3.576.0': - resolution: {integrity: sha512-KDvDlbeipSTIf+ffKtTg1m419TK7s9mZSWC8bvuZ9qx6/sjQFOXIKOVqyuli6DnfxGbvRcwoRuY99OcCH1N/0w==} - engines: {node: '>=16.0.0'} - - '@aws-sdk/credential-provider-env@3.577.0': - resolution: {integrity: sha512-Jxu255j0gToMGEiqufP8ZtKI8HW90lOLjwJ3LrdlD/NLsAY0tOQf1fWc53u28hWmmNGMxmCrL2p66IOgMDhDUw==} - engines: {node: '>=16.0.0'} - - '@aws-sdk/credential-provider-http@3.577.0': - resolution: {integrity: sha512-n++yhCp67b9+ZRGEdY1jhamB5E/O+QsIDOPSuRmdaSGMCOd82oUEKPgIVEU1bkqxDsBxgiEWuvtfhK6sNiDS0A==} - engines: {node: '>=16.0.0'} - - '@aws-sdk/credential-provider-ini@3.577.0': - resolution: {integrity: sha512-q7lHPtv6BjRvChUE3m0tIaEZKxPTaZ1B3lKxGYsFl3VLAu5N8yGCUKwuA1izf4ucT+LyKscVGqK6VDZx1ev3nw==} - engines: {node: '>=16.0.0'} - peerDependencies: - '@aws-sdk/client-sts': ^3.577.0 - - '@aws-sdk/credential-provider-node@3.577.0': - resolution: {integrity: sha512-epZ1HOMsrXBNczc0HQpv0VMjqAEpc09DUA7Rg3gUJfn8umhML7A7bXnUyqPA+S54q397UYg1leQKdSn23OiwQQ==} - engines: {node: '>=16.0.0'} - - '@aws-sdk/credential-provider-process@3.577.0': - resolution: {integrity: sha512-Gin6BWtOiXxIgITrJ3Nwc+Y2P1uVT6huYR4EcbA/DJUPWyO0n9y5UFLewPvVbLkRn15JeEqErBLUrHclkiOKtw==} - engines: {node: '>=16.0.0'} - - '@aws-sdk/credential-provider-sso@3.577.0': - resolution: {integrity: sha512-iVm5SQvS7EgZTJsRaqUOmDQpBQPPPat42SCbWFvFQOLrl8qewq8OP94hFS5w2mP62zngeYzqhJnDel79HXbxew==} - engines: {node: '>=16.0.0'} - - '@aws-sdk/credential-provider-web-identity@3.577.0': - resolution: {integrity: sha512-ZGHGNRaCtJJmszb9UTnC7izNCtRUttdPlLdMkh41KPS32vfdrBDHs1JrpbZijItRj1xKuOXsiYSXLAaHGcLh8Q==} - engines: {node: '>=16.0.0'} - peerDependencies: - '@aws-sdk/client-sts': ^3.577.0 - - '@aws-sdk/middleware-host-header@3.577.0': - resolution: {integrity: sha512-9ca5MJz455CODIVXs0/sWmJm7t3QO4EUa1zf8pE8grLpzf0J94bz/skDWm37Pli13T3WaAQBHCTiH2gUVfCsWg==} - engines: {node: '>=16.0.0'} - - '@aws-sdk/middleware-logger@3.577.0': - resolution: {integrity: sha512-aPFGpGjTZcJYk+24bg7jT4XdIp42mFXSuPt49lw5KygefLyJM/sB0bKKqPYYivW0rcuZ9brQ58eZUNthrzYAvg==} - engines: {node: '>=16.0.0'} - - '@aws-sdk/middleware-recursion-detection@3.577.0': - resolution: {integrity: sha512-pn3ZVEd2iobKJlR3H+bDilHjgRnNrQ6HMmK9ZzZw89Ckn3Dcbv48xOv4RJvu0aU8SDLl/SNCxppKjeLDTPGBNA==} - engines: {node: '>=16.0.0'} - - '@aws-sdk/middleware-user-agent@3.577.0': - resolution: {integrity: sha512-P55HAXgwmiHHpFx5JEPvOnAbfhN7v6sWv9PBQs+z2tC7QiBcPS0cdJR6PfV7J1n4VPK52/OnrK3l9VxdQ7Ms0g==} - engines: {node: '>=16.0.0'} - - '@aws-sdk/region-config-resolver@3.577.0': - resolution: {integrity: sha512-4ChCFACNwzqx/xjg3zgFcW8Ali6R9C95cFECKWT/7CUM1D0MGvkclSH2cLarmHCmJgU6onKkJroFtWp0kHhgyg==} - engines: {node: '>=16.0.0'} - - '@aws-sdk/token-providers@3.577.0': - resolution: {integrity: sha512-0CkIZpcC3DNQJQ1hDjm2bdSy/Xjs7Ny5YvSsacasGOkNfk+FdkiQy6N67bZX3Zbc9KIx+Nz4bu3iDeNSNplnnQ==} - engines: {node: '>=16.0.0'} - peerDependencies: - '@aws-sdk/client-sso-oidc': ^3.577.0 - - '@aws-sdk/types@3.577.0': - resolution: {integrity: sha512-FT2JZES3wBKN/alfmhlo+3ZOq/XJ0C7QOZcDNrpKjB0kqYoKjhVKZ/Hx6ArR0czkKfHzBBEs6y40ebIHx2nSmA==} - engines: {node: '>=16.0.0'} - - '@aws-sdk/util-endpoints@3.577.0': - resolution: {integrity: sha512-FjuUz1Kdy4Zly2q/c58tpdqHd6z7iOdU/caYzoc8jwgAHBDBbIJNQLCU9hXJnPV2M8pWxQDyIZsoVwtmvErPzw==} - engines: {node: '>=16.0.0'} - - '@aws-sdk/util-locate-window@3.568.0': - resolution: {integrity: sha512-3nh4TINkXYr+H41QaPelCceEB2FXP3fxp93YZXB/kqJvX0U9j0N0Uk45gvsjmEPzG8XxkPEeLIfT2I1M7A6Lig==} - engines: {node: '>=16.0.0'} - - '@aws-sdk/util-user-agent-browser@3.577.0': - resolution: {integrity: sha512-zEAzHgR6HWpZOH7xFgeJLc6/CzMcx4nxeQolZxVZoB5pPaJd3CjyRhZN0xXeZB0XIRCWmb4yJBgyiugXLNMkLA==} - - '@aws-sdk/util-user-agent-node@3.577.0': - resolution: {integrity: sha512-XqvtFjbSMtycZTWVwDe8DRWovuoMbA54nhUoZwVU6rW9OSD6NZWGR512BUGHFaWzW0Wg8++Dj10FrKTG2XtqfA==} - engines: {node: '>=16.0.0'} - peerDependencies: - aws-crt: '>=1.0.0' - peerDependenciesMeta: - aws-crt: - optional: true - - '@aws-sdk/util-utf8-browser@3.259.0': - resolution: {integrity: sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw==} - - '@balena/dockerignore@1.0.2': - resolution: {integrity: sha512-wMue2Sy4GAVTk6Ic4tJVcnfdau+gx2EnG7S+uAEe+TWJFqE4YoWN4/H8MSLj4eYJKxGg26lZwboEniNiNwZQ6Q==} - - '@cloudflare/kv-asset-handler@0.3.2': - resolution: {integrity: sha512-EeEjMobfuJrwoctj7FA1y1KEbM0+Q1xSjobIEyie9k4haVEBB7vkDvsasw1pM3rO39mL2akxIAzLMUAtrMHZhA==} - engines: {node: '>=16.13'} - - '@cloudflare/workerd-darwin-64@1.20240512.0': - resolution: {integrity: sha512-VMp+CsSHFALQiBzPdQ5dDI4T1qwLu0mQ0aeKVNDosXjueN0f3zj/lf+mFil5/9jBbG3t4mG0y+6MMnalP9Lobw==} - engines: {node: '>=16'} - cpu: [x64] - os: [darwin] - - '@cloudflare/workerd-darwin-arm64@1.20240512.0': - resolution: {integrity: sha512-lZktXGmzMrB5rJqY9+PmnNfv1HKlj/YLZwMjPfF0WVKHUFdvQbAHsi7NlKv6mW9uIvlZnS+K4sIkWc0MDXcRnA==} - engines: {node: '>=16'} - cpu: [arm64] - os: [darwin] - - '@cloudflare/workerd-linux-64@1.20240512.0': - resolution: {integrity: sha512-wrHvqCZZqXz6Y3MUTn/9pQNsvaoNjbJpuA6vcXsXu8iCzJi911iVW2WUEBX+MpUWD+mBIP0oXni5tTlhkokOPw==} - engines: {node: '>=16'} - cpu: [x64] - os: [linux] - - '@cloudflare/workerd-linux-arm64@1.20240512.0': - resolution: {integrity: sha512-YPezHMySL9J9tFdzxz390eBswQ//QJNYcZolz9Dgvb3FEfdpK345cE/bsWbMOqw5ws2f82l388epoenghtYvAg==} - engines: {node: '>=16'} - cpu: [arm64] - os: [linux] - - '@cloudflare/workerd-windows-64@1.20240512.0': - resolution: {integrity: sha512-SxKapDrIYSscMR7lGIp/av0l6vokjH4xQ9ACxHgXh+OdOus9azppSmjaPyw4/ePvg7yqpkaNjf9o258IxWtvKQ==} - engines: {node: '>=16'} - cpu: [x64] - os: [win32] - - '@cloudflare/workers-types@4.20240512.0': - resolution: {integrity: sha512-o2yTEWg+YK/I1t/Me+dA0oarO0aCbjibp6wSeaw52DSE9tDyKJ7S+Qdyw/XsMrKn4t8kF6f/YOba+9O4MJfW9w==} - - '@colors/colors@1.5.0': - resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} - engines: {node: '>=0.1.90'} - - '@cspotcode/source-map-support@0.8.1': - resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} - engines: {node: '>=12'} - - '@electric-sql/pglite@0.1.5': - resolution: {integrity: sha512-eymv4ONNvoPZQTvOQIi5dbpR+J5HzEv0qQH9o/y3gvNheJV/P/NFcrbsfJZYTsDKoq7DKrTiFNexsRkJKy8x9Q==} - - '@esbuild-kit/core-utils@3.3.2': - resolution: {integrity: sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ==} - - '@esbuild-kit/esm-loader@2.6.5': - resolution: {integrity: sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA==} - - '@esbuild-plugins/node-globals-polyfill@0.2.3': - resolution: {integrity: sha512-r3MIryXDeXDOZh7ih1l/yE9ZLORCd5e8vWg02azWRGj5SPTuoh69A2AIyn0Z31V/kHBfZ4HgWJ+OK3GTTwLmnw==} - peerDependencies: - esbuild: '*' - - '@esbuild-plugins/node-modules-polyfill@0.2.2': - resolution: {integrity: sha512-LXV7QsWJxRuMYvKbiznh+U1ilIop3g2TeKRzUxOG5X3YITc8JyyTa90BmLwqqv0YnX4v32CSlG+vsziZp9dMvA==} - peerDependencies: - esbuild: '*' - - '@esbuild/aix-ppc64@0.19.12': - resolution: {integrity: sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [aix] - - '@esbuild/aix-ppc64@0.20.2': - resolution: {integrity: sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [aix] - - '@esbuild/android-arm64@0.17.19': - resolution: {integrity: sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm64@0.18.20': - resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm64@0.19.12': - resolution: {integrity: sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm64@0.20.2': - resolution: {integrity: sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm@0.17.19': - resolution: {integrity: sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - - '@esbuild/android-arm@0.18.20': - resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - - '@esbuild/android-arm@0.19.12': - resolution: {integrity: sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - - '@esbuild/android-arm@0.20.2': - resolution: {integrity: sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - - '@esbuild/android-x64@0.17.19': - resolution: {integrity: sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - - '@esbuild/android-x64@0.18.20': - resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - - '@esbuild/android-x64@0.19.12': - resolution: {integrity: sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - - '@esbuild/android-x64@0.20.2': - resolution: {integrity: sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - - '@esbuild/darwin-arm64@0.17.19': - resolution: {integrity: sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-arm64@0.18.20': - resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-arm64@0.19.12': - resolution: {integrity: sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-arm64@0.20.2': - resolution: {integrity: sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-x64@0.17.19': - resolution: {integrity: sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - - '@esbuild/darwin-x64@0.18.20': - resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - - '@esbuild/darwin-x64@0.19.12': - resolution: {integrity: sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - - '@esbuild/darwin-x64@0.20.2': - resolution: {integrity: sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - - '@esbuild/freebsd-arm64@0.17.19': - resolution: {integrity: sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-arm64@0.18.20': - resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-arm64@0.19.12': - resolution: {integrity: sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-arm64@0.20.2': - resolution: {integrity: sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.17.19': - resolution: {integrity: sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.18.20': - resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.19.12': - resolution: {integrity: sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.20.2': - resolution: {integrity: sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - - '@esbuild/linux-arm64@0.17.19': - resolution: {integrity: sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm64@0.18.20': - resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm64@0.19.12': - resolution: {integrity: sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm64@0.20.2': - resolution: {integrity: sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm@0.17.19': - resolution: {integrity: sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-arm@0.18.20': - resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-arm@0.19.12': - resolution: {integrity: sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-arm@0.20.2': - resolution: {integrity: sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-ia32@0.17.19': - resolution: {integrity: sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-ia32@0.18.20': - resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-ia32@0.19.12': - resolution: {integrity: sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-ia32@0.20.2': - resolution: {integrity: sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-loong64@0.14.54': - resolution: {integrity: sha512-bZBrLAIX1kpWelV0XemxBZllyRmM6vgFQQG2GdNb+r3Fkp0FOh1NJSvekXDs7jq70k4euu1cryLMfU+mTXlEpw==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-loong64@0.17.19': - resolution: {integrity: sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-loong64@0.18.20': - resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-loong64@0.19.12': - resolution: {integrity: sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-loong64@0.20.2': - resolution: {integrity: sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-mips64el@0.17.19': - resolution: {integrity: sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-mips64el@0.18.20': - resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-mips64el@0.19.12': - resolution: {integrity: sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-mips64el@0.20.2': - resolution: {integrity: sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-ppc64@0.17.19': - resolution: {integrity: sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-ppc64@0.18.20': - resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-ppc64@0.19.12': - resolution: {integrity: sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-ppc64@0.20.2': - resolution: {integrity: sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-riscv64@0.17.19': - resolution: {integrity: sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-riscv64@0.18.20': - resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-riscv64@0.19.12': - resolution: {integrity: sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-riscv64@0.20.2': - resolution: {integrity: sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-s390x@0.17.19': - resolution: {integrity: sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-s390x@0.18.20': - resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-s390x@0.19.12': - resolution: {integrity: sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-s390x@0.20.2': - resolution: {integrity: sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-x64@0.17.19': - resolution: {integrity: sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - - '@esbuild/linux-x64@0.18.20': - resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - - '@esbuild/linux-x64@0.19.12': - resolution: {integrity: sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - - '@esbuild/linux-x64@0.20.2': - resolution: {integrity: sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - - '@esbuild/netbsd-x64@0.17.19': - resolution: {integrity: sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - - '@esbuild/netbsd-x64@0.18.20': - resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - - '@esbuild/netbsd-x64@0.19.12': - resolution: {integrity: sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - - '@esbuild/netbsd-x64@0.20.2': - resolution: {integrity: sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - - '@esbuild/openbsd-x64@0.17.19': - resolution: {integrity: sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - - '@esbuild/openbsd-x64@0.18.20': - resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - - '@esbuild/openbsd-x64@0.19.12': - resolution: {integrity: sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - - '@esbuild/openbsd-x64@0.20.2': - resolution: {integrity: sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - - '@esbuild/sunos-x64@0.17.19': - resolution: {integrity: sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - - '@esbuild/sunos-x64@0.18.20': - resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - - '@esbuild/sunos-x64@0.19.12': - resolution: {integrity: sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - - '@esbuild/sunos-x64@0.20.2': - resolution: {integrity: sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - - '@esbuild/win32-arm64@0.17.19': - resolution: {integrity: sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-arm64@0.18.20': - resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-arm64@0.19.12': - resolution: {integrity: sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-arm64@0.20.2': - resolution: {integrity: sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-ia32@0.17.19': - resolution: {integrity: sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-ia32@0.18.20': - resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-ia32@0.19.12': - resolution: {integrity: sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-ia32@0.20.2': - resolution: {integrity: sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-x64@0.17.19': - resolution: {integrity: sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - - '@esbuild/win32-x64@0.18.20': - resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - - '@esbuild/win32-x64@0.19.12': - resolution: {integrity: sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - - '@esbuild/win32-x64@0.20.2': - resolution: {integrity: sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - - '@eslint-community/eslint-utils@4.4.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 - - '@eslint-community/regexpp@4.10.0': - resolution: {integrity: sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - - '@eslint/eslintrc@2.1.4': - resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - '@eslint/js@8.57.0': - resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - '@ewoudenberg/difflib@0.1.0': - resolution: {integrity: sha512-OU5P5mJyD3OoWYMWY+yIgwvgNS9cFAU10f+DDuvtogcWQOoJIsQ4Hy2McSfUfhKjq8L0FuWVb4Rt7kgA+XK86A==} - - '@fastify/busboy@2.1.1': - resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==} - engines: {node: '>=14'} - - '@hono/node-server@1.11.1': - resolution: {integrity: sha512-GW1Iomhmm1o4Z+X57xGby8A35Cu9UZLL7pSMdqDBkD99U5cywff8F+8hLk5aBTzNubnsFAvWQ/fZjNwPsEn9lA==} - engines: {node: '>=18.14.1'} - - '@hono/zod-validator@0.2.1': - resolution: {integrity: sha512-HFoxln7Q6JsE64qz2WBS28SD33UB2alp3aRKmcWnNLDzEL1BLsWfbdX6e1HIiUprHYTIXf5y7ax8eYidKUwyaA==} - peerDependencies: - hono: '>=3.9.0' - zod: ^3.19.1 - - '@humanwhocodes/config-array@0.11.14': - resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} - engines: {node: '>=10.10.0'} - - '@humanwhocodes/module-importer@1.0.1': - resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} - engines: {node: '>=12.22'} - - '@humanwhocodes/object-schema@2.0.3': - resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} - - '@isaacs/cliui@8.0.2': - resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} - engines: {node: '>=12'} - - '@jest/schemas@29.6.3': - resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jridgewell/gen-mapping@0.3.5': - resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} - engines: {node: '>=6.0.0'} - - '@jridgewell/resolve-uri@3.1.2': - resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} - engines: {node: '>=6.0.0'} - - '@jridgewell/set-array@1.2.1': - resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} - engines: {node: '>=6.0.0'} - - '@jridgewell/sourcemap-codec@1.4.15': - resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} - - '@jridgewell/trace-mapping@0.3.25': - resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} - - '@jridgewell/trace-mapping@0.3.9': - resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} - - '@libsql/client@0.4.3': - resolution: {integrity: sha512-AUYKnSPqAsFBVWBvmtrb4dG3pQlvTKT92eztAest9wQU2iJkabH8WzHLDb3dKFWKql7/kiCqvBQUVpozDwhekQ==} - - '@libsql/core@0.4.3': - resolution: {integrity: sha512-r28iYBtaLBW9RRgXPFh6cGCsVI/rwRlOzSOpAu/1PVTm6EJ3t233pUf97jETVHU0vjdr1d8VvV6fKAvJkokqCw==} - - '@libsql/darwin-arm64@0.2.0': - resolution: {integrity: sha512-+qyT2W/n5CFH1YZWv2mxW4Fsoo4dX9Z9M/nvbQqZ7H84J8hVegvVAsIGYzcK8xAeMEcpU5yGKB1Y9NoDY4hOSQ==} - cpu: [arm64] - os: [darwin] - - '@libsql/darwin-x64@0.2.0': - resolution: {integrity: sha512-hwmO2mF1n8oDHKFrUju6Jv+n9iFtTf5JUK+xlnIE3Td0ZwGC/O1R/Z/btZTd9nD+vsvakC8SJT7/Q6YlWIkhEw==} - cpu: [x64] - os: [darwin] - - '@libsql/hrana-client@0.5.6': - resolution: {integrity: sha512-mjQoAmejZ1atG+M3YR2ZW+rg6ceBByH/S/h17ZoYZkqbWrvohFhXyz2LFxj++ARMoY9m6w3RJJIRdJdmnEUlFg==} - - '@libsql/isomorphic-fetch@0.1.12': - resolution: {integrity: sha512-MRo4UcmjAGAa3ac56LoD5OE13m2p0lu0VEtZC2NZMcogM/jc5fU9YtMQ3qbPjFJ+u2BBjFZgMPkQaLS1dlMhpg==} - - '@libsql/isomorphic-ws@0.1.5': - resolution: {integrity: sha512-DtLWIH29onUYR00i0GlQ3UdcTRC6EP4u9w/h9LxpUZJWRMARk6dQwZ6Jkd+QdwVpuAOrdxt18v0K2uIYR3fwFg==} - - '@libsql/linux-arm64-gnu@0.2.0': - resolution: {integrity: sha512-1w2lPXIYtnBaK5t/Ej5E8x7lPiE+jP3KATI/W4yei5Z/ONJh7jQW5PJ7sYU95vTME3hWEM1FXN6kvzcpFAte7w==} - cpu: [arm64] - os: [linux] - - '@libsql/linux-arm64-musl@0.2.0': - resolution: {integrity: sha512-lkblBEJ7xuNiWNjP8DDq0rqoWccszfkUS7Efh5EjJ+GDWdCBVfh08mPofIZg0fZVLWQCY3j+VZCG1qZfATBizg==} - cpu: [arm64] - os: [linux] - - '@libsql/linux-x64-gnu@0.2.0': - resolution: {integrity: sha512-+x/d289KeJydwOhhqSxKT+6MSQTCfLltzOpTzPccsvdt5fxg8CBi+gfvEJ4/XW23Sa+9bc7zodFP0i6MOlxX7w==} - cpu: [x64] - os: [linux] - - '@libsql/linux-x64-musl@0.2.0': - resolution: {integrity: sha512-5Xn0c5A6vKf9D1ASpgk7mef//FuY7t5Lktj/eiU4n3ryxG+6WTpqstTittJUgepVjcleLPYxIhQAYeYwTYH1IQ==} - cpu: [x64] - os: [linux] - - '@libsql/win32-x64-msvc@0.2.0': - resolution: {integrity: sha512-rpK+trBIpRST15m3cMYg5aPaX7kvCIottxY7jZPINkKAaScvfbn9yulU/iZUM9YtuK96Y1ZmvwyVIK/Y5DzoMQ==} - cpu: [x64] - os: [win32] - - '@neon-rs/load@0.0.4': - resolution: {integrity: sha512-kTPhdZyTQxB+2wpiRcFWrDcejc4JI6tkPuS7UZCG4l6Zvc5kU/gGQ/ozvHTh1XR5tS+UlfAfGuPajjzQjCiHCw==} - - '@neondatabase/serverless@0.7.2': - resolution: {integrity: sha512-wU3WA2uTyNO7wjPs3Mg0G01jztAxUxzd9/mskMmtPwPTjf7JKWi9AW5/puOGXLxmZ9PVgRFeBVRVYq5nBPhsCg==} - - '@neondatabase/serverless@0.9.3': - resolution: {integrity: sha512-6ZBK8asl2Z3+ADEaELvbaVVGVlmY1oAzkxxZfpmXPKFuJhbDN+5fU3zYBamsahS/Ch1zE+CVWB3R+8QEI2LMSw==} - - '@nodelib/fs.scandir@2.1.5': - resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} - engines: {node: '>= 8'} - - '@nodelib/fs.stat@2.0.5': - resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} - engines: {node: '>= 8'} - - '@nodelib/fs.walk@1.2.8': - resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} - engines: {node: '>= 8'} - - '@originjs/vite-plugin-commonjs@1.0.3': - resolution: {integrity: sha512-KuEXeGPptM2lyxdIEJ4R11+5ztipHoE7hy8ClZt3PYaOVQ/pyngd2alaSrPnwyFeOW1UagRBaQ752aA1dTMdOQ==} - - '@pkgjs/parseargs@0.11.0': - resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} - engines: {node: '>=14'} - - '@pkgr/core@0.1.1': - resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} - engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - - '@planetscale/database@1.18.0': - resolution: {integrity: sha512-t2XdOfrVgcF7AW791FtdPS27NyNqcE1SpoXgk3HpziousvUMsJi4Q6NL3JyOBpsMOrvk94749o8yyonvX5quPw==} - engines: {node: '>=16'} - - '@rollup/rollup-android-arm-eabi@4.17.2': - resolution: {integrity: sha512-NM0jFxY8bB8QLkoKxIQeObCaDlJKewVlIEkuyYKm5An1tdVZ966w2+MPQ2l8LBZLjR+SgyV+nRkTIunzOYBMLQ==} - cpu: [arm] - os: [android] - - '@rollup/rollup-android-arm64@4.17.2': - resolution: {integrity: sha512-yeX/Usk7daNIVwkq2uGoq2BYJKZY1JfyLTaHO/jaiSwi/lsf8fTFoQW/n6IdAsx5tx+iotu2zCJwz8MxI6D/Bw==} - cpu: [arm64] - os: [android] - - '@rollup/rollup-darwin-arm64@4.17.2': - resolution: {integrity: sha512-kcMLpE6uCwls023+kknm71ug7MZOrtXo+y5p/tsg6jltpDtgQY1Eq5sGfHcQfb+lfuKwhBmEURDga9N0ol4YPw==} - cpu: [arm64] - os: [darwin] - - '@rollup/rollup-darwin-x64@4.17.2': - resolution: {integrity: sha512-AtKwD0VEx0zWkL0ZjixEkp5tbNLzX+FCqGG1SvOu993HnSz4qDI6S4kGzubrEJAljpVkhRSlg5bzpV//E6ysTQ==} - cpu: [x64] - os: [darwin] - - '@rollup/rollup-linux-arm-gnueabihf@4.17.2': - resolution: {integrity: sha512-3reX2fUHqN7sffBNqmEyMQVj/CKhIHZd4y631duy0hZqI8Qoqf6lTtmAKvJFYa6bhU95B1D0WgzHkmTg33In0A==} - cpu: [arm] - os: [linux] - - '@rollup/rollup-linux-arm-musleabihf@4.17.2': - resolution: {integrity: sha512-uSqpsp91mheRgw96xtyAGP9FW5ChctTFEoXP0r5FAzj/3ZRv3Uxjtc7taRQSaQM/q85KEKjKsZuiZM3GyUivRg==} - cpu: [arm] - os: [linux] - - '@rollup/rollup-linux-arm64-gnu@4.17.2': - resolution: {integrity: sha512-EMMPHkiCRtE8Wdk3Qhtciq6BndLtstqZIroHiiGzB3C5LDJmIZcSzVtLRbwuXuUft1Cnv+9fxuDtDxz3k3EW2A==} - cpu: [arm64] - os: [linux] - - '@rollup/rollup-linux-arm64-musl@4.17.2': - resolution: {integrity: sha512-NMPylUUZ1i0z/xJUIx6VUhISZDRT+uTWpBcjdv0/zkp7b/bQDF+NfnfdzuTiB1G6HTodgoFa93hp0O1xl+/UbA==} - cpu: [arm64] - os: [linux] - - '@rollup/rollup-linux-powerpc64le-gnu@4.17.2': - resolution: {integrity: sha512-T19My13y8uYXPw/L/k0JYaX1fJKFT/PWdXiHr8mTbXWxjVF1t+8Xl31DgBBvEKclw+1b00Chg0hxE2O7bTG7GQ==} - cpu: [ppc64] - os: [linux] - - '@rollup/rollup-linux-riscv64-gnu@4.17.2': - resolution: {integrity: sha512-BOaNfthf3X3fOWAB+IJ9kxTgPmMqPPH5f5k2DcCsRrBIbWnaJCgX2ll77dV1TdSy9SaXTR5iDXRL8n7AnoP5cg==} - cpu: [riscv64] - os: [linux] - - '@rollup/rollup-linux-s390x-gnu@4.17.2': - resolution: {integrity: sha512-W0UP/x7bnn3xN2eYMql2T/+wpASLE5SjObXILTMPUBDB/Fg/FxC+gX4nvCfPBCbNhz51C+HcqQp2qQ4u25ok6g==} - cpu: [s390x] - os: [linux] - - '@rollup/rollup-linux-x64-gnu@4.17.2': - resolution: {integrity: sha512-Hy7pLwByUOuyaFC6mAr7m+oMC+V7qyifzs/nW2OJfC8H4hbCzOX07Ov0VFk/zP3kBsELWNFi7rJtgbKYsav9QQ==} - cpu: [x64] - os: [linux] - - '@rollup/rollup-linux-x64-musl@4.17.2': - resolution: {integrity: sha512-h1+yTWeYbRdAyJ/jMiVw0l6fOOm/0D1vNLui9iPuqgRGnXA0u21gAqOyB5iHjlM9MMfNOm9RHCQ7zLIzT0x11Q==} - cpu: [x64] - os: [linux] - - '@rollup/rollup-win32-arm64-msvc@4.17.2': - resolution: {integrity: sha512-tmdtXMfKAjy5+IQsVtDiCfqbynAQE/TQRpWdVataHmhMb9DCoJxp9vLcCBjEQWMiUYxO1QprH/HbY9ragCEFLA==} - cpu: [arm64] - os: [win32] - - '@rollup/rollup-win32-ia32-msvc@4.17.2': - resolution: {integrity: sha512-7II/QCSTAHuE5vdZaQEwJq2ZACkBpQDOmQsE6D6XUbnBHW8IAhm4eTufL6msLJorzrHDFv3CF8oCA/hSIRuZeQ==} - cpu: [ia32] - os: [win32] - - '@rollup/rollup-win32-x64-msvc@4.17.2': - resolution: {integrity: sha512-TGGO7v7qOq4CYmSBVEYpI1Y5xDuCEnbVC5Vth8mOsW0gDSzxNrVERPc790IGHsrT2dQSimgMr9Ub3Y1Jci5/8w==} - cpu: [x64] - os: [win32] - - '@sinclair/typebox@0.27.8': - resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} - - '@sindresorhus/is@4.6.0': - resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} - engines: {node: '>=10'} - - '@smithy/abort-controller@3.0.0': - resolution: {integrity: sha512-p6GlFGBt9K4MYLu72YuJ523NVR4A8oHlC5M2JO6OmQqN8kAc/uh1JqLE+FizTokrSJGg0CSvC+BrsmGzKtsZKA==} - engines: {node: '>=16.0.0'} - - '@smithy/config-resolver@3.0.0': - resolution: {integrity: sha512-2GzOfADwYLQugYkKQhIyZyQlM05K+tMKvRnc6eFfZcpJGRfKoMUMYdPlBKmqHwQFXQKBrGV6cxL9oymWgDzvFw==} - engines: {node: '>=16.0.0'} - - '@smithy/core@2.0.1': - resolution: {integrity: sha512-rcMkjvwxH/bER+oZUPR0yTA0ELD6m3A+d92+CFkdF6HJFCBB1bXo7P5pm21L66XwTN01B6bUhSCQ7cymWRD8zg==} - engines: {node: '>=16.0.0'} - - '@smithy/credential-provider-imds@3.0.0': - resolution: {integrity: sha512-lfmBiFQcA3FsDAPxNfY0L7CawcWtbyWsBOHo34nF095728JLkBX4Y9q/VPPE2r7fqMVK+drmDigqE2/SSQeVRA==} - engines: {node: '>=16.0.0'} - - '@smithy/fetch-http-handler@3.0.1': - resolution: {integrity: sha512-uaH74i5BDj+rBwoQaXioKpI0SHBJFtOVwzrCpxZxphOW0ki5jhj7dXvDMYM2IJem8TpdFvS2iC08sjOblfFGFg==} - - '@smithy/hash-node@3.0.0': - resolution: {integrity: sha512-84qXstNemP3XS5jcof0el6+bDfjzuvhJPQTEfro3lgtbCtKgzPm3MgiS6ehXVPjeQ5+JS0HqmTz8f/RYfzHVxw==} - engines: {node: '>=16.0.0'} - - '@smithy/invalid-dependency@3.0.0': - resolution: {integrity: sha512-F6wBBaEFgJzj0s4KUlliIGPmqXemwP6EavgvDqYwCH40O5Xr2iMHvS8todmGVZtuJCorBkXsYLyTu4PuizVq5g==} - - '@smithy/is-array-buffer@3.0.0': - resolution: {integrity: sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ==} - engines: {node: '>=16.0.0'} - - '@smithy/middleware-content-length@3.0.0': - resolution: {integrity: sha512-3C4s4d/iGobgCtk2tnWW6+zSTOBg1PRAm2vtWZLdriwTroFbbWNSr3lcyzHdrQHnEXYCC5K52EbpfodaIUY8sg==} - engines: {node: '>=16.0.0'} - - '@smithy/middleware-endpoint@3.0.0': - resolution: {integrity: sha512-aXOAWztw/5qAfp0NcA2OWpv6ZI/E+Dh9mByif7i91D/0iyYNUcKvskmXiowKESFkuZ7PIMd3VOR4fTibZDs2OQ==} - engines: {node: '>=16.0.0'} - - '@smithy/middleware-retry@3.0.1': - resolution: {integrity: sha512-hBhSEuL841FhJBK/19WpaGk5YWSzFk/P2UaVjANGKRv3eYNO8Y1lANWgqnuPWjOyCEWMPr58vELFDWpxvRKANw==} - engines: {node: '>=16.0.0'} - - '@smithy/middleware-serde@3.0.0': - resolution: {integrity: sha512-I1vKG1foI+oPgG9r7IMY1S+xBnmAn1ISqployvqkwHoSb8VPsngHDTOgYGYBonuOKndaWRUGJZrKYYLB+Ane6w==} - engines: {node: '>=16.0.0'} - - '@smithy/middleware-stack@3.0.0': - resolution: {integrity: sha512-+H0jmyfAyHRFXm6wunskuNAqtj7yfmwFB6Fp37enytp2q047/Od9xetEaUbluyImOlGnGpaVGaVfjwawSr+i6Q==} - engines: {node: '>=16.0.0'} - - '@smithy/node-config-provider@3.0.0': - resolution: {integrity: sha512-buqfaSdDh0zo62EPLf8rGDvcpKwGpO5ho4bXS2cdFhlOta7tBkWJt+O5uiaAeICfIOfPclNOndshDNSanX2X9g==} - engines: {node: '>=16.0.0'} - - '@smithy/node-http-handler@3.0.0': - resolution: {integrity: sha512-3trD4r7NOMygwLbUJo4eodyQuypAWr7uvPnebNJ9a70dQhVn+US8j/lCnvoJS6BXfZeF7PkkkI0DemVJw+n+eQ==} - engines: {node: '>=16.0.0'} - - '@smithy/property-provider@3.0.0': - resolution: {integrity: sha512-LmbPgHBswdXCrkWWuUwBm9w72S2iLWyC/5jet9/Y9cGHtzqxi+GVjfCfahkvNV4KXEwgnH8EMpcrD9RUYe0eLQ==} - engines: {node: '>=16.0.0'} - - '@smithy/protocol-http@4.0.0': - resolution: {integrity: sha512-qOQZOEI2XLWRWBO9AgIYuHuqjZ2csyr8/IlgFDHDNuIgLAMRx2Bl8ck5U5D6Vh9DPdoaVpuzwWMa0xcdL4O/AQ==} - engines: {node: '>=16.0.0'} - - '@smithy/querystring-builder@3.0.0': - resolution: {integrity: sha512-bW8Fi0NzyfkE0TmQphDXr1AmBDbK01cA4C1Z7ggwMAU5RDz5AAv/KmoRwzQAS0kxXNf/D2ALTEgwK0U2c4LtRg==} - engines: {node: '>=16.0.0'} - - '@smithy/querystring-parser@3.0.0': - resolution: {integrity: sha512-UzHwthk0UEccV4dHzPySnBy34AWw3V9lIqUTxmozQ+wPDAO9csCWMfOLe7V9A2agNYy7xE+Pb0S6K/J23JSzfQ==} - engines: {node: '>=16.0.0'} - - '@smithy/service-error-classification@3.0.0': - resolution: {integrity: sha512-3BsBtOUt2Gsnc3X23ew+r2M71WwtpHfEDGhHYHSDg6q1t8FrWh15jT25DLajFV1H+PpxAJ6gqe9yYeRUsmSdFA==} - engines: {node: '>=16.0.0'} - - '@smithy/shared-ini-file-loader@3.0.0': - resolution: {integrity: sha512-REVw6XauXk8xE4zo5aGL7Rz4ywA8qNMUn8RtWeTRQsgAlmlvbJ7CEPBcaXU2NDC3AYBgYAXrGyWD8XrN8UGDog==} - engines: {node: '>=16.0.0'} - - '@smithy/signature-v4@3.0.0': - resolution: {integrity: sha512-kXFOkNX+BQHe2qnLxpMEaCRGap9J6tUGLzc3A9jdn+nD4JdMwCKTJ+zFwQ20GkY+mAXGatyTw3HcoUlR39HwmA==} - engines: {node: '>=16.0.0'} - - '@smithy/smithy-client@3.0.1': - resolution: {integrity: sha512-KAiFY4Y4jdHxR+4zerH/VBhaFKM8pbaVmJZ/CWJRwtM/CmwzTfXfvYwf6GoUwiHepdv+lwiOXCuOl6UBDUEINw==} - engines: {node: '>=16.0.0'} - - '@smithy/types@3.0.0': - resolution: {integrity: sha512-VvWuQk2RKFuOr98gFhjca7fkBS+xLLURT8bUjk5XQoV0ZLm7WPwWPPY3/AwzTLuUBDeoKDCthfe1AsTUWaSEhw==} - engines: {node: '>=16.0.0'} - - '@smithy/url-parser@3.0.0': - resolution: {integrity: sha512-2XLazFgUu+YOGHtWihB3FSLAfCUajVfNBXGGYjOaVKjLAuAxx3pSBY3hBgLzIgB17haf59gOG3imKqTy8mcrjw==} - - '@smithy/util-base64@3.0.0': - resolution: {integrity: sha512-Kxvoh5Qtt0CDsfajiZOCpJxgtPHXOKwmM+Zy4waD43UoEMA+qPxxa98aE/7ZhdnBFZFXMOiBR5xbcaMhLtznQQ==} - engines: {node: '>=16.0.0'} - - '@smithy/util-body-length-browser@3.0.0': - resolution: {integrity: sha512-cbjJs2A1mLYmqmyVl80uoLTJhAcfzMOyPgjwAYusWKMdLeNtzmMz9YxNl3/jRLoxSS3wkqkf0jwNdtXWtyEBaQ==} - - '@smithy/util-body-length-node@3.0.0': - resolution: {integrity: sha512-Tj7pZ4bUloNUP6PzwhN7K386tmSmEET9QtQg0TgdNOnxhZvCssHji+oZTUIuzxECRfG8rdm2PMw2WCFs6eIYkA==} - engines: {node: '>=16.0.0'} - - '@smithy/util-buffer-from@3.0.0': - resolution: {integrity: sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA==} - engines: {node: '>=16.0.0'} - - '@smithy/util-config-provider@3.0.0': - resolution: {integrity: sha512-pbjk4s0fwq3Di/ANL+rCvJMKM5bzAQdE5S/6RL5NXgMExFAi6UgQMPOm5yPaIWPpr+EOXKXRonJ3FoxKf4mCJQ==} - engines: {node: '>=16.0.0'} - - '@smithy/util-defaults-mode-browser@3.0.1': - resolution: {integrity: sha512-nW5kEzdJn1Bn5TF+gOPHh2rcPli8JU9vSSXLbfg7uPnfR1TMRQqs9zlYRhIb87NeSxIbpdXOI94tvXSy+fvDYg==} - engines: {node: '>= 10.0.0'} - - '@smithy/util-defaults-mode-node@3.0.1': - resolution: {integrity: sha512-TFk+Qb+elLc/MOhtSp+50fstyfZ6avQbgH2d96xUBpeScu+Al9elxv+UFAjaTHe0HQe5n+wem8ZLpXvU8lwV6Q==} - engines: {node: '>= 10.0.0'} - - '@smithy/util-endpoints@2.0.0': - resolution: {integrity: sha512-+exaXzEY3DNt2qtA2OtRNSDlVrE4p32j1JSsQkzA5AdP0YtJNjkYbYhJxkFmPYcjI1abuwopOZCwUmv682QkiQ==} - engines: {node: '>=16.0.0'} - - '@smithy/util-hex-encoding@3.0.0': - resolution: {integrity: sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ==} - engines: {node: '>=16.0.0'} - - '@smithy/util-middleware@3.0.0': - resolution: {integrity: sha512-q5ITdOnV2pXHSVDnKWrwgSNTDBAMHLptFE07ua/5Ty5WJ11bvr0vk2a7agu7qRhrCFRQlno5u3CneU5EELK+DQ==} - engines: {node: '>=16.0.0'} - - '@smithy/util-retry@3.0.0': - resolution: {integrity: sha512-nK99bvJiziGv/UOKJlDvFF45F00WgPLKVIGUfAK+mDhzVN2hb/S33uW2Tlhg5PVBoqY7tDVqL0zmu4OxAHgo9g==} - engines: {node: '>=16.0.0'} - - '@smithy/util-stream@3.0.1': - resolution: {integrity: sha512-7F7VNNhAsfMRA8I986YdOY5fE0/T1/ZjFF6OLsqkvQVNP3vZ/szYDfGCyphb7ioA09r32K/0qbSFfNFU68aSzA==} - engines: {node: '>=16.0.0'} - - '@smithy/util-uri-escape@3.0.0': - resolution: {integrity: sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==} - engines: {node: '>=16.0.0'} - - '@smithy/util-utf8@3.0.0': - resolution: {integrity: sha512-rUeT12bxFnplYDe815GXbq/oixEGHfRFFtcTF3YdDi/JaENIM6aSYYLJydG83UNzLXeRI5K8abYd/8Sp/QM0kA==} - engines: {node: '>=16.0.0'} - - '@types/better-sqlite3@7.6.10': - resolution: {integrity: sha512-TZBjD+yOsyrUJGmcUj6OS3JADk3+UZcNv3NOBqGkM09bZdi28fNZw8ODqbMOLfKCu7RYCO62/ldq1iHbzxqoPw==} - - '@types/docker-modem@3.0.6': - resolution: {integrity: sha512-yKpAGEuKRSS8wwx0joknWxsmLha78wNMe9R2S3UNsVOkZded8UqOrV8KoeDXoXsjndxwyF3eIhyClGbO1SEhEg==} - - '@types/dockerode@3.3.29': - resolution: {integrity: sha512-5PRRq/yt5OT/Jf77ltIdz4EiR9+VLnPF+HpU4xGFwUqmV24Co2HKBNW3w+slqZ1CYchbcDeqJASHDYWzZCcMiQ==} - - '@types/estree@1.0.5': - resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} - - '@types/fs-extra@11.0.4': - resolution: {integrity: sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==} - - '@types/glob@8.1.0': - resolution: {integrity: sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w==} - - '@types/json-diff@1.0.3': - resolution: {integrity: sha512-Qvxm8fpRMv/1zZR3sQWImeRK2mBYJji20xF51Fq9Gt//Ed18u0x6/FNLogLS1xhfUWTEmDyqveJqn95ltB6Kvw==} - - '@types/jsonfile@6.1.4': - resolution: {integrity: sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==} - - '@types/minimatch@5.1.2': - resolution: {integrity: sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==} - - '@types/minimist@1.2.5': - resolution: {integrity: sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==} - - '@types/node-fetch@2.6.11': - resolution: {integrity: sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==} - - '@types/node-forge@1.3.11': - resolution: {integrity: sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==} - - '@types/node@18.19.33': - resolution: {integrity: sha512-NR9+KrpSajr2qBVp/Yt5TU/rp+b5Mayi3+OlMlcg2cVCfRmcG5PWZ7S4+MG9PZ5gWBoc9Pd0BKSRViuBCRPu0A==} - - '@types/pg@8.11.6': - resolution: {integrity: sha512-/2WmmBXHLsfRqzfHW7BNZ8SbYzE8OSk7i3WjFYvfgRHj7S1xj+16Je5fUKv3lVdVzk/zn9TXOqf+avFCFIE0yQ==} - - '@types/pg@8.6.6': - resolution: {integrity: sha512-O2xNmXebtwVekJDD+02udOncjVcMZQuTEQEMpKJ0ZRf5E7/9JJX3izhKUcUifBkyKpljyUM6BTgy2trmviKlpw==} - - '@types/pluralize@0.0.33': - resolution: {integrity: sha512-JOqsl+ZoCpP4e8TDke9W79FDcSgPAR0l6pixx2JHkhnRjvShyYiAYw2LVsnA7K08Y6DeOnaU6ujmENO4os/cYg==} - - '@types/ps-tree@1.1.6': - resolution: {integrity: sha512-PtrlVaOaI44/3pl3cvnlK+GxOM3re2526TJvPvh7W+keHIXdV4TE0ylpPBAcvFQCbGitaTXwL9u+RF7qtVeazQ==} - - '@types/semver@7.5.8': - resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} - - '@types/ssh2@1.15.0': - resolution: {integrity: sha512-YcT8jP5F8NzWeevWvcyrrLB3zcneVjzYY9ZDSMAMboI+2zR1qYWFhwsyOFVzT7Jorn67vqxC0FRiw8YyG9P1ww==} - - '@types/uuid@9.0.8': - resolution: {integrity: sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==} - - '@types/which@3.0.3': - resolution: {integrity: sha512-2C1+XoY0huExTbs8MQv1DuS5FS86+SEjdM9F/+GS61gg5Hqbtj8ZiDSx8MfWcyei907fIPbfPGCOrNUTnVHY1g==} - - '@types/ws@8.5.10': - resolution: {integrity: sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==} - - '@typescript-eslint/eslint-plugin@7.10.0': - resolution: {integrity: sha512-PzCr+a/KAef5ZawX7nbyNwBDtM1HdLIT53aSA2DDlxmxMngZ43O8SIePOeX8H5S+FHXeI6t97mTt/dDdzY4Fyw==} - engines: {node: ^18.18.0 || >=20.0.0} - peerDependencies: - '@typescript-eslint/parser': ^7.0.0 - eslint: ^8.56.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - - '@typescript-eslint/parser@7.10.0': - resolution: {integrity: sha512-2EjZMA0LUW5V5tGQiaa2Gys+nKdfrn2xiTIBLR4fxmPmVSvgPcKNW+AE/ln9k0A4zDUti0J/GZXMDupQoI+e1w==} - engines: {node: ^18.18.0 || >=20.0.0} - peerDependencies: - eslint: ^8.56.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - - '@typescript-eslint/scope-manager@7.10.0': - resolution: {integrity: sha512-7L01/K8W/VGl7noe2mgH0K7BE29Sq6KAbVmxurj8GGaPDZXPr8EEQ2seOeAS+mEV9DnzxBQB6ax6qQQ5C6P4xg==} - engines: {node: ^18.18.0 || >=20.0.0} - - '@typescript-eslint/type-utils@7.10.0': - resolution: {integrity: sha512-D7tS4WDkJWrVkuzgm90qYw9RdgBcrWmbbRkrLA4d7Pg3w0ttVGDsvYGV19SH8gPR5L7OtcN5J1hTtyenO9xE9g==} - engines: {node: ^18.18.0 || >=20.0.0} - peerDependencies: - eslint: ^8.56.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - - '@typescript-eslint/types@7.10.0': - resolution: {integrity: sha512-7fNj+Ya35aNyhuqrA1E/VayQX9Elwr8NKZ4WueClR3KwJ7Xx9jcCdOrLW04h51de/+gNbyFMs+IDxh5xIwfbNg==} - engines: {node: ^18.18.0 || >=20.0.0} - - '@typescript-eslint/typescript-estree@7.10.0': - resolution: {integrity: sha512-LXFnQJjL9XIcxeVfqmNj60YhatpRLt6UhdlFwAkjNc6jSUlK8zQOl1oktAP8PlWFzPQC1jny/8Bai3/HPuvN5g==} - engines: {node: ^18.18.0 || >=20.0.0} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - - '@typescript-eslint/utils@7.10.0': - resolution: {integrity: sha512-olzif1Fuo8R8m/qKkzJqT7qwy16CzPRWBvERS0uvyc+DHd8AKbO4Jb7kpAvVzMmZm8TrHnI7hvjN4I05zow+tg==} - engines: {node: ^18.18.0 || >=20.0.0} - peerDependencies: - eslint: ^8.56.0 - - '@typescript-eslint/visitor-keys@7.10.0': - resolution: {integrity: sha512-9ntIVgsi6gg6FIq9xjEO4VQJvwOqA3jaBFQJ/6TK5AvEup2+cECI6Fh7QiBxmfMHXU0V0J4RyPeOU1VDNzl9cg==} - engines: {node: ^18.18.0 || >=20.0.0} - - '@ungap/structured-clone@1.2.0': - resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} - - '@vercel/postgres@0.8.0': - resolution: {integrity: sha512-/QUV9ExwaNdKooRjOQqvrKNVnRvsaXeukPNI5DB1ovUTesglfR/fparw7ngo1KUWWKIVpEj2TRrA+ObRHRdaLg==} - engines: {node: '>=14.6'} - - '@vitest/expect@1.6.0': - resolution: {integrity: sha512-ixEvFVQjycy/oNgHjqsL6AZCDduC+tflRluaHIzKIsdbzkLn2U/iBnVeJwB6HsIjQBdfMR8Z0tRxKUsvFJEeWQ==} - - '@vitest/runner@1.6.0': - resolution: {integrity: sha512-P4xgwPjwesuBiHisAVz/LSSZtDjOTPYZVmNAnpHHSR6ONrf8eCJOFRvUwdHn30F5M1fxhqtl7QZQUk2dprIXAg==} - - '@vitest/snapshot@1.6.0': - resolution: {integrity: sha512-+Hx43f8Chus+DCmygqqfetcAZrDJwvTj0ymqjQq4CvmpKFSTVteEOBzCusu1x2tt4OJcvBflyHUE0DZSLgEMtQ==} - - '@vitest/spy@1.6.0': - resolution: {integrity: sha512-leUTap6B/cqi/bQkXUu6bQV5TZPx7pmMBKBQiI0rJA8c3pB56ZsaTbREnF7CJfmvAS4V2cXIBAh/3rVwrrCYgw==} - - '@vitest/utils@1.6.0': - resolution: {integrity: sha512-21cPiuGMoMZwiOHa2i4LXkMkMkCGzA+MVFV70jRwHo95dL4x/ts5GZhML1QWuy7yfp3WzK3lRvZi3JnXTYqrBw==} - - acorn-jsx@5.3.2: - resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - - acorn-walk@8.3.2: - resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==} - engines: {node: '>=0.4.0'} - - acorn@8.11.3: - resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} - engines: {node: '>=0.4.0'} - hasBin: true - - aggregate-error@4.0.1: - resolution: {integrity: sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w==} - engines: {node: '>=12'} - - ajv@6.12.6: - resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} - - ansi-escapes@6.2.1: - resolution: {integrity: sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==} - engines: {node: '>=14.16'} - - ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} - - ansi-regex@6.0.1: - resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} - engines: {node: '>=12'} - - ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} - - ansi-styles@5.2.0: - resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} - engines: {node: '>=10'} - - ansi-styles@6.2.1: - resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} - engines: {node: '>=12'} - - ansicolors@0.3.2: - resolution: {integrity: sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==} - - any-promise@1.3.0: - resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} - - anymatch@3.1.3: - resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} - engines: {node: '>= 8'} - - argparse@1.0.10: - resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} - - argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - - array-find-index@1.0.2: - resolution: {integrity: sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==} - engines: {node: '>=0.10.0'} - - array-union@2.1.0: - resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} - engines: {node: '>=8'} - - arrgv@1.0.2: - resolution: {integrity: sha512-a4eg4yhp7mmruZDQFqVMlxNRFGi/i1r87pt8SDHy0/I8PqSXoUTlWZRdAZo0VXgvEARcujbtTk8kiZRi1uDGRw==} - engines: {node: '>=8.0.0'} - - arrify@3.0.0: - resolution: {integrity: sha512-tLkvA81vQG/XqE2mjDkGQHoOINtMHtysSnemrmoGe6PydDPMRbVugqyk4A6V/WDWEfm3l+0d8anA9r8cv/5Jaw==} - engines: {node: '>=12'} - - as-table@1.0.55: - resolution: {integrity: sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ==} - - asn1@0.2.6: - resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==} - - assertion-error@1.1.0: - resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} - - asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - - ava@5.3.1: - resolution: {integrity: sha512-Scv9a4gMOXB6+ni4toLuhAm9KYWEjsgBglJl+kMGI5+IVDt120CCDZyB5HNU9DjmLI2t4I0GbnxGLmmRfGTJGg==} - engines: {node: '>=14.19 <15 || >=16.15 <17 || >=18'} - hasBin: true - peerDependencies: - '@ava/typescript': '*' - peerDependenciesMeta: - '@ava/typescript': - optional: true - - balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - - base64-js@1.5.1: - resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - - bcrypt-pbkdf@1.0.2: - resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==} - - better-sqlite3@9.6.0: - resolution: {integrity: sha512-yR5HATnqeYNVnkaUTf4bOP2dJSnyhP4puJN/QPRyx4YkBEEUxib422n2XzPqDEHjQQqazoYoADdAm5vE15+dAQ==} - - binary-extensions@2.3.0: - resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} - engines: {node: '>=8'} - - bindings@1.5.0: - resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} - - bl@4.1.0: - resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} - - blake3-wasm@2.1.5: - resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==} - - blueimp-md5@2.19.0: - resolution: {integrity: sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w==} - - bowser@2.11.0: - resolution: {integrity: sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==} - - brace-expansion@1.1.11: - resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} - - brace-expansion@2.0.1: - resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} - - braces@3.0.2: - resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} - engines: {node: '>=8'} - - buffer-from@1.1.2: - resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - - buffer@5.7.1: - resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} - - bufferutil@4.0.8: - resolution: {integrity: sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==} - engines: {node: '>=6.14.2'} - - buildcheck@0.0.6: - resolution: {integrity: sha512-8f9ZJCUXyT1M35Jx7MkBgmBMo3oHTTBIPLiY9xyL0pl3T5RwcPEY8cUHr5LBNfu/fk6c2T4DJZuVM/8ZZT2D2A==} - engines: {node: '>=10.0.0'} - - bundle-require@4.1.0: - resolution: {integrity: sha512-FeArRFM+ziGkRViKRnSTbHZc35dgmR9yNog05Kn0+ItI59pOAISGvnnIwW1WgFZQW59IxD9QpJnUPkdIPfZuXg==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - peerDependencies: - esbuild: '>=0.17' - - cac@6.7.14: - resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} - engines: {node: '>=8'} - - callsites@3.1.0: - resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} - engines: {node: '>=6'} - - callsites@4.1.0: - resolution: {integrity: sha512-aBMbD1Xxay75ViYezwT40aQONfr+pSXTHwNKvIXhXD6+LY3F1dLIcceoC5OZKBVHbXcysz1hL9D2w0JJIMXpUw==} - engines: {node: '>=12.20'} - - camelcase@7.0.1: - resolution: {integrity: sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==} - engines: {node: '>=14.16'} - - capnp-ts@0.7.0: - resolution: {integrity: sha512-XKxXAC3HVPv7r674zP0VC3RTXz+/JKhfyw94ljvF80yynK6VkTnqE3jMuN8b3dUVmmc43TjyxjW4KTsmB3c86g==} - - cardinal@2.1.1: - resolution: {integrity: sha512-JSr5eOgoEymtYHBjNWyjrMqet9Am2miJhlfKNdqLp6zoeAh0KN5dRAcxlecj5mAJrmQomgiOBj35xHLrFjqBpw==} - hasBin: true - - cbor@8.1.0: - resolution: {integrity: sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==} - engines: {node: '>=12.19'} - - chai@4.4.1: - resolution: {integrity: sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==} - engines: {node: '>=4'} - - chalk@4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} - - chalk@5.3.0: - resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} - engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - - char-regex@1.0.2: - resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} - engines: {node: '>=10'} - - check-error@1.0.3: - resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} - - chokidar@3.6.0: - resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} - engines: {node: '>= 8.10.0'} - - chownr@1.1.4: - resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} - - chunkd@2.0.1: - resolution: {integrity: sha512-7d58XsFmOq0j6el67Ug9mHf9ELUXsQXYJBkyxhH/k+6Ke0qXRnv0kbemx+Twc6fRJ07C49lcbdgm9FL1Ei/6SQ==} - - ci-info@3.9.0: - resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} - engines: {node: '>=8'} - - ci-parallel-vars@1.0.1: - resolution: {integrity: sha512-uvzpYrpmidaoxvIQHM+rKSrigjOe9feHYbw4uOI2gdfe1C3xIlxO+kVXq83WQWNniTf8bAxVpy+cQeFQsMERKg==} - - clean-stack@4.2.0: - resolution: {integrity: sha512-LYv6XPxoyODi36Dp976riBtSY27VmFo+MKqEU9QCCWyTrdEPDog+RWA7xQWHi6Vbp61j5c4cdzzX1NidnwtUWg==} - engines: {node: '>=12'} - - clean-yaml-object@0.1.0: - resolution: {integrity: sha512-3yONmlN9CSAkzNwnRCiJQ7Q2xK5mWuEfL3PuTZcAUzhObbXsfsnMptJzXwz93nc5zn9V9TwCVMmV7w4xsm43dw==} - engines: {node: '>=0.10.0'} - - cli-color@2.0.4: - resolution: {integrity: sha512-zlnpg0jNcibNrO7GG9IeHH7maWFeCz+Ja1wx/7tZNU5ASSSSZ+/qZciM0/LHCYxSdqv5h2sdbQ/PXYdOuetXvA==} - engines: {node: '>=0.10'} - - cli-table3@0.6.5: - resolution: {integrity: sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==} - engines: {node: 10.* || >= 12.*} - - cli-truncate@3.1.0: - resolution: {integrity: sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - cliui@8.0.1: - resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} - engines: {node: '>=12'} - - code-excerpt@4.0.0: - resolution: {integrity: sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} - - color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - - colors@1.4.0: - resolution: {integrity: sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==} - engines: {node: '>=0.1.90'} - - combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} - - commander@10.0.1: - resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} - engines: {node: '>=14'} - - commander@12.1.0: - resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} - engines: {node: '>=18'} - - commander@4.1.1: - resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} - engines: {node: '>= 6'} - - commander@9.5.0: - resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} - engines: {node: ^12.20.0 || >=14} - - common-path-prefix@3.0.0: - resolution: {integrity: sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==} - - concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - - concordance@5.0.4: - resolution: {integrity: sha512-OAcsnTEYu1ARJqWVGwf4zh4JDfHZEaSNlNccFmt8YjB2l/n19/PF2viLINHc57vO4FKIAFl2FWASIGZZWZ2Kxw==} - engines: {node: '>=10.18.0 <11 || >=12.14.0 <13 || >=14'} - - confbox@0.1.7: - resolution: {integrity: sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==} - - convert-to-spaces@2.0.1: - resolution: {integrity: sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - cookie@0.5.0: - resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} - engines: {node: '>= 0.6'} - - copy-anything@3.0.5: - resolution: {integrity: sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==} - engines: {node: '>=12.13'} - - cpu-features@0.0.10: - resolution: {integrity: sha512-9IkYqtX3YHPCzoVg1Py+o9057a3i0fp7S530UWokCSaFVTc7CwXPRiOjRjBQQ18ZCNafx78YfnG+HALxtVmOGA==} - engines: {node: '>=10.0.0'} - - cross-spawn@7.0.3: - resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} - engines: {node: '>= 8'} - - currently-unhandled@0.4.1: - resolution: {integrity: sha512-/fITjgjGU50vjQ4FH6eUoYu+iUoUKIXws2hL15JJpIR+BbTxaXQsMuuyjtNh2WqsSBS5nsaZHFsFecyw5CCAng==} - engines: {node: '>=0.10.0'} - - d@1.0.2: - resolution: {integrity: sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==} - engines: {node: '>=0.12'} - - data-uri-to-buffer@2.0.2: - resolution: {integrity: sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA==} - - data-uri-to-buffer@4.0.1: - resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} - engines: {node: '>= 12'} - - date-time@3.1.0: - resolution: {integrity: sha512-uqCUKXE5q1PNBXjPqvwhwJf9SwMoAHBgWJ6DcrnS5o+W2JOiIILl0JEdVD8SGujrNS02GGxgwAg2PN2zONgtjg==} - engines: {node: '>=6'} - - debug@4.3.4: - resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - decompress-response@6.0.0: - resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} - engines: {node: '>=10'} - - deep-eql@4.1.3: - resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==} - engines: {node: '>=6'} - - deep-extend@0.6.0: - resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} - engines: {node: '>=4.0.0'} - - deep-is@0.1.4: - resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - - delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} - - denque@2.1.0: - resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==} - engines: {node: '>=0.10'} - - detect-libc@2.0.2: - resolution: {integrity: sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==} - engines: {node: '>=8'} - - detect-libc@2.0.3: - resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==} - engines: {node: '>=8'} - - diff-sequences@29.6.3: - resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - difflib@0.2.4: - resolution: {integrity: sha512-9YVwmMb0wQHQNr5J9m6BSj6fk4pfGITGQOOs+D9Fl+INODWFOfvhIU1hNv6GgR1RBoC/9NJcwu77zShxV0kT7w==} - - dir-glob@3.0.1: - resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} - engines: {node: '>=8'} - - docker-modem@3.0.8: - resolution: {integrity: sha512-f0ReSURdM3pcKPNS30mxOHSbaFLcknGmQjwSfmbcdOw1XWKXVhukM3NJHhr7NpY9BIyyWQb0EBo3KQvvuU5egQ==} - engines: {node: '>= 8.0'} - - dockerode@3.3.5: - resolution: {integrity: sha512-/0YNa3ZDNeLr/tSckmD69+Gq+qVNhvKfAHNeZJBnp7EOP6RGKV8ORrJHkUn20So5wU+xxT7+1n5u8PjHbfjbSA==} - engines: {node: '>= 8.0'} - - doctrine@3.0.0: - resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} - engines: {node: '>=6.0.0'} - - dotenv@16.4.5: - resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} - engines: {node: '>=12'} - - dreamopt@0.8.0: - resolution: {integrity: sha512-vyJTp8+mC+G+5dfgsY+r3ckxlz+QMX40VjPQsZc5gxVAxLmi64TBoVkP54A/pRAXMXsbu2GMMBrZPxNv23waMg==} - engines: {node: '>=0.4.0'} - - drizzle-kit@0.21.2: - resolution: {integrity: sha512-U87IhZyCt/9d0ZT/Na3KFJVY31tSxtTx/n9UMcWFpW/5c2Ede39xiCG5efNV/0iimsv97UIRtDI0ldLBW5lbcg==} - hasBin: true - - drizzle-orm@0.32.0-85c8008: - resolution: {integrity: sha512-gHLqGZz0eqAvSw4vq46sHRV8qLHxrbuCVlwaVZ1t4ntyH8csyCKEXTWO78cBJwYUpz7BCSzqVX+5ZYa/QM+/Gw==} - peerDependencies: - '@aws-sdk/client-rds-data': '>=3' - '@cloudflare/workers-types': '>=3' - '@electric-sql/pglite': '>=0.1.1' - '@libsql/client': '*' - '@neondatabase/serverless': '>=0.1' - '@op-engineering/op-sqlite': '>=2' - '@opentelemetry/api': ^1.4.1 - '@planetscale/database': '>=1' - '@tidbcloud/serverless': '*' - '@types/better-sqlite3': '*' - '@types/pg': '*' - '@types/react': '>=18' - '@types/sql.js': '*' - '@vercel/postgres': '>=0.8.0' - '@xata.io/client': '*' - better-sqlite3: '>=7' - bun-types: '*' - expo-sqlite: '>=13.2.0' - knex: '*' - kysely: '*' - mysql2: '>=2' - pg: '>=8' - postgres: '>=3' - react: '>=18' - sql.js: '>=1' - sqlite3: '>=5' - peerDependenciesMeta: - '@aws-sdk/client-rds-data': - optional: true - '@cloudflare/workers-types': - optional: true - '@electric-sql/pglite': - optional: true - '@libsql/client': - optional: true - '@neondatabase/serverless': - optional: true - '@op-engineering/op-sqlite': - optional: true - '@opentelemetry/api': - optional: true - '@planetscale/database': - optional: true - '@tidbcloud/serverless': - optional: true - '@types/better-sqlite3': - optional: true - '@types/pg': - optional: true - '@types/react': - optional: true - '@types/sql.js': - optional: true - '@vercel/postgres': - optional: true - '@xata.io/client': - optional: true - better-sqlite3: - optional: true - bun-types: - optional: true - expo-sqlite: - optional: true - knex: - optional: true - kysely: - optional: true - mysql2: - optional: true - pg: - optional: true - postgres: - optional: true - react: - optional: true - sql.js: - optional: true - sqlite3: - optional: true - - duplexer@0.1.2: - resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} - - eastasianwidth@0.2.0: - resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - - emittery@1.0.3: - resolution: {integrity: sha512-tJdCJitoy2lrC2ldJcqN4vkqJ00lT+tOWNT1hBJjO/3FDMJa5TTIiYGCKGkn/WfCyOzUMObeohbVTj00fhiLiA==} - engines: {node: '>=14.16'} - - emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - - emoji-regex@9.2.2: - resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - - emojilib@2.4.0: - resolution: {integrity: sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==} - - end-of-stream@1.4.4: - resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} - - env-paths@3.0.0: - resolution: {integrity: sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - es5-ext@0.10.64: - resolution: {integrity: sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==} - engines: {node: '>=0.10'} - - es6-iterator@2.0.3: - resolution: {integrity: sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==} - - es6-symbol@3.1.4: - resolution: {integrity: sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==} - engines: {node: '>=0.12'} - - es6-weak-map@2.0.3: - resolution: {integrity: sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==} - - esbuild-android-64@0.14.54: - resolution: {integrity: sha512-Tz2++Aqqz0rJ7kYBfz+iqyE3QMycD4vk7LBRyWaAVFgFtQ/O8EJOnVmTOiDWYZ/uYzB4kvP+bqejYdVKzE5lAQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - - esbuild-android-arm64@0.14.54: - resolution: {integrity: sha512-F9E+/QDi9sSkLaClO8SOV6etqPd+5DgJje1F9lOWoNncDdOBL2YF59IhsWATSt0TLZbYCf3pNlTHvVV5VfHdvg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - - esbuild-darwin-64@0.14.54: - resolution: {integrity: sha512-jtdKWV3nBviOd5v4hOpkVmpxsBy90CGzebpbO9beiqUYVMBtSc0AL9zGftFuBon7PNDcdvNCEuQqw2x0wP9yug==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - - esbuild-darwin-arm64@0.14.54: - resolution: {integrity: sha512-OPafJHD2oUPyvJMrsCvDGkRrVCar5aVyHfWGQzY1dWnzErjrDuSETxwA2HSsyg2jORLY8yBfzc1MIpUkXlctmw==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - - esbuild-freebsd-64@0.14.54: - resolution: {integrity: sha512-OKwd4gmwHqOTp4mOGZKe/XUlbDJ4Q9TjX0hMPIDBUWWu/kwhBAudJdBoxnjNf9ocIB6GN6CPowYpR/hRCbSYAg==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - - esbuild-freebsd-arm64@0.14.54: - resolution: {integrity: sha512-sFwueGr7OvIFiQT6WeG0jRLjkjdqWWSrfbVwZp8iMP+8UHEHRBvlaxL6IuKNDwAozNUmbb8nIMXa7oAOARGs1Q==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - - esbuild-linux-32@0.14.54: - resolution: {integrity: sha512-1ZuY+JDI//WmklKlBgJnglpUL1owm2OX+8E1syCD6UAxcMM/XoWd76OHSjl/0MR0LisSAXDqgjT3uJqT67O3qw==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - - esbuild-linux-64@0.14.54: - resolution: {integrity: sha512-EgjAgH5HwTbtNsTqQOXWApBaPVdDn7XcK+/PtJwZLT1UmpLoznPd8c5CxqsH2dQK3j05YsB3L17T8vE7cp4cCg==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - - esbuild-linux-arm64@0.14.54: - resolution: {integrity: sha512-WL71L+0Rwv+Gv/HTmxTEmpv0UgmxYa5ftZILVi2QmZBgX3q7+tDeOQNqGtdXSdsL8TQi1vIaVFHUPDe0O0kdig==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - - esbuild-linux-arm@0.14.54: - resolution: {integrity: sha512-qqz/SjemQhVMTnvcLGoLOdFpCYbz4v4fUo+TfsWG+1aOu70/80RV6bgNpR2JCrppV2moUQkww+6bWxXRL9YMGw==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - - esbuild-linux-mips64le@0.14.54: - resolution: {integrity: sha512-qTHGQB8D1etd0u1+sB6p0ikLKRVuCWhYQhAHRPkO+OF3I/iSlTKNNS0Lh2Oc0g0UFGguaFZZiPJdJey3AGpAlw==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - - esbuild-linux-ppc64le@0.14.54: - resolution: {integrity: sha512-j3OMlzHiqwZBDPRCDFKcx595XVfOfOnv68Ax3U4UKZ3MTYQB5Yz3X1mn5GnodEVYzhtZgxEBidLWeIs8FDSfrQ==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - - esbuild-linux-riscv64@0.14.54: - resolution: {integrity: sha512-y7Vt7Wl9dkOGZjxQZnDAqqn+XOqFD7IMWiewY5SPlNlzMX39ocPQlOaoxvT4FllA5viyV26/QzHtvTjVNOxHZg==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - - esbuild-linux-s390x@0.14.54: - resolution: {integrity: sha512-zaHpW9dziAsi7lRcyV4r8dhfG1qBidQWUXweUjnw+lliChJqQr+6XD71K41oEIC3Mx1KStovEmlzm+MkGZHnHA==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - - esbuild-netbsd-64@0.14.54: - resolution: {integrity: sha512-PR01lmIMnfJTgeU9VJTDY9ZerDWVFIUzAtJuDHwwceppW7cQWjBBqP48NdeRtoP04/AtO9a7w3viI+PIDr6d+w==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - - esbuild-node-externals@1.13.1: - resolution: {integrity: sha512-ho4Lokc6iMB1lWbb2tWJ6otien+3Kfoaxe0fy7NUNgVuLnfmlW+GRINftTVUGtTVY/dapuwUu/CvFylYNwzkMA==} - engines: {node: '>=12'} - peerDependencies: - esbuild: 0.12 - 0.21 - - esbuild-openbsd-64@0.14.54: - resolution: {integrity: sha512-Qyk7ikT2o7Wu76UsvvDS5q0amJvmRzDyVlL0qf5VLsLchjCa1+IAvd8kTBgUxD7VBUUVgItLkk609ZHUc1oCaw==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - - esbuild-register@3.5.0: - resolution: {integrity: sha512-+4G/XmakeBAsvJuDugJvtyF1x+XJT4FMocynNpxrvEBViirpfUn2PgNpCHedfWhF4WokNsO/OvMKrmJOIJsI5A==} - peerDependencies: - esbuild: '>=0.12 <1' - - esbuild-sunos-64@0.14.54: - resolution: {integrity: sha512-28GZ24KmMSeKi5ueWzMcco6EBHStL3B6ubM7M51RmPwXQGLe0teBGJocmWhgwccA1GeFXqxzILIxXpHbl9Q/Kw==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - - esbuild-windows-32@0.14.54: - resolution: {integrity: sha512-T+rdZW19ql9MjS7pixmZYVObd9G7kcaZo+sETqNH4RCkuuYSuv9AGHUVnPoP9hhuE1WM1ZimHz1CIBHBboLU7w==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - - esbuild-windows-64@0.14.54: - resolution: {integrity: sha512-AoHTRBUuYwXtZhjXZbA1pGfTo8cJo3vZIcWGLiUcTNgHpJJMC1rVA44ZereBHMJtotyN71S8Qw0npiCIkW96cQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - - esbuild-windows-arm64@0.14.54: - resolution: {integrity: sha512-M0kuUvXhot1zOISQGXwWn6YtS+Y/1RT9WrVIOywZnJHo3jCDyewAc79aKNQWFCQm+xNHVTq9h8dZKvygoXQQRg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - - esbuild@0.14.54: - resolution: {integrity: sha512-Cy9llcy8DvET5uznocPyqL3BFRrFXSVqbgpMJ9Wz8oVjZlh/zUSNbPRbov0VX7VxN2JH1Oa0uNxZ7eLRb62pJA==} - engines: {node: '>=12'} - hasBin: true - - esbuild@0.17.19: - resolution: {integrity: sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==} - engines: {node: '>=12'} - hasBin: true - - esbuild@0.18.20: - resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==} - engines: {node: '>=12'} - hasBin: true - - esbuild@0.19.12: - resolution: {integrity: sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==} - engines: {node: '>=12'} - hasBin: true - - esbuild@0.20.2: - resolution: {integrity: sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==} - engines: {node: '>=12'} - hasBin: true - - escalade@3.1.2: - resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} - engines: {node: '>=6'} - - escape-string-regexp@2.0.0: - resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} - engines: {node: '>=8'} - - escape-string-regexp@4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} - - escape-string-regexp@5.0.0: - resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} - engines: {node: '>=12'} - - eslint-config-prettier@9.1.0: - resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} - hasBin: true - peerDependencies: - eslint: '>=7.0.0' - - eslint-plugin-prettier@5.1.3: - resolution: {integrity: sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==} - engines: {node: ^14.18.0 || >=16.0.0} - peerDependencies: - '@types/eslint': '>=8.0.0' - eslint: '>=8.0.0' - eslint-config-prettier: '*' - prettier: '>=3.0.0' - peerDependenciesMeta: - '@types/eslint': - optional: true - eslint-config-prettier: - optional: true - - eslint-scope@7.2.2: - resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - eslint-visitor-keys@3.4.3: - resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - eslint@8.57.0: - resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - hasBin: true - - esniff@2.0.1: - resolution: {integrity: sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==} - engines: {node: '>=0.10'} - - espree@9.6.1: - resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - esprima@4.0.1: - resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} - engines: {node: '>=4'} - hasBin: true - - esquery@1.5.0: - resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} - engines: {node: '>=0.10'} - - esrecurse@4.3.0: - resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} - engines: {node: '>=4.0'} - - estraverse@5.3.0: - resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} - engines: {node: '>=4.0'} - - estree-walker@0.6.1: - resolution: {integrity: sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==} - - estree-walker@3.0.3: - resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} - - esutils@2.0.3: - resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} - engines: {node: '>=0.10.0'} - - event-emitter@0.3.5: - resolution: {integrity: sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==} - - event-stream@3.3.4: - resolution: {integrity: sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==} - - execa@5.1.1: - resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} - engines: {node: '>=10'} - - execa@8.0.1: - resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} - engines: {node: '>=16.17'} - - exit-hook@2.2.1: - resolution: {integrity: sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==} - engines: {node: '>=6'} - - expand-template@2.0.3: - resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} - engines: {node: '>=6'} - - ext@1.7.0: - resolution: {integrity: sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==} - - fast-deep-equal@3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - - fast-diff@1.3.0: - resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} - - fast-glob@3.3.2: - resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} - engines: {node: '>=8.6.0'} - - fast-json-stable-stringify@2.1.0: - resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} - - fast-levenshtein@2.0.6: - resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - - fast-xml-parser@4.2.5: - resolution: {integrity: sha512-B9/wizE4WngqQftFPmdaMYlXoJlJOYxGQOanC77fq9k8+Z0v5dDSVh+3glErdIROP//s/jgb7ZuxKfB8nVyo0g==} - hasBin: true - - fastq@1.17.1: - resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} - - fetch-blob@3.2.0: - resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} - engines: {node: ^12.20 || >= 14.13} - - fflate@0.8.2: - resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==} - - figures@5.0.0: - resolution: {integrity: sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg==} - engines: {node: '>=14'} - - file-entry-cache@6.0.1: - resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} - engines: {node: ^10.12.0 || >=12.0.0} - - file-uri-to-path@1.0.0: - resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} - - fill-range@7.1.1: - resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} - engines: {node: '>=8'} - - find-up@5.0.0: - resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} - engines: {node: '>=10'} - - find-up@6.3.0: - resolution: {integrity: sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - flat-cache@3.2.0: - resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} - engines: {node: ^10.12.0 || >=12.0.0} - - flatted@3.3.1: - resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} - - foreground-child@3.1.1: - resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==} - engines: {node: '>=14'} - - form-data@4.0.0: - resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} - engines: {node: '>= 6'} - - formdata-polyfill@4.0.10: - resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} - engines: {node: '>=12.20.0'} - - from@0.1.7: - resolution: {integrity: sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==} - - fs-constants@1.0.0: - resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} - - fs-extra@11.2.0: - resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} - engines: {node: '>=14.14'} - - fs.realpath@1.0.0: - resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} - - fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - - function-bind@1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - - fx@34.0.0: - resolution: {integrity: sha512-/fZih3/WLsrtlaj2mahjWxAmyuikmcl3D5kKPqLtFmEilLsy9wp0+/vEmfvYXXhwJc+ajtCFDCf+yttXmPMHSQ==} - hasBin: true - - generate-function@2.3.1: - resolution: {integrity: sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==} - - get-caller-file@2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} - - get-func-name@2.0.2: - resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} - - get-port@6.1.2: - resolution: {integrity: sha512-BrGGraKm2uPqurfGVj/z97/zv8dPleC6x9JBNRTrDNtCkkRF4rPwrQXFgL7+I+q8QSdU4ntLQX2D7KIxSy8nGw==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - get-source@2.0.12: - resolution: {integrity: sha512-X5+4+iD+HoSeEED+uwrQ07BOQr0kEDFMVqqpBuI+RaZBpBpHCuXxo70bjar6f0b0u/DQJsJ7ssurpP0V60Az+w==} - - get-stream@6.0.1: - resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} - engines: {node: '>=10'} - - get-stream@8.0.1: - resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} - engines: {node: '>=16'} - - get-tsconfig@4.7.5: - resolution: {integrity: sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==} - - github-from-package@0.0.0: - resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} - - glob-parent@5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} - - glob-parent@6.0.2: - resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} - engines: {node: '>=10.13.0'} - - glob-to-regexp@0.4.1: - resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} - - glob@10.3.15: - resolution: {integrity: sha512-0c6RlJt1TICLyvJYIApxb8GsXoai0KUP7AxKKAtsYXdgJR1mGEUa7DgwShbdk1nly0PYoZj01xd4hzbq3fsjpw==} - engines: {node: '>=16 || 14 >=14.18'} - hasBin: true - - glob@7.2.3: - resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - - glob@8.1.0: - resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} - engines: {node: '>=12'} - - globals@13.24.0: - resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} - engines: {node: '>=8'} - - globby@11.1.0: - resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} - engines: {node: '>=10'} - - globby@13.2.2: - resolution: {integrity: sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - globrex@0.1.2: - resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==} - - graceful-fs@4.2.11: - resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - - graphemer@1.4.0: - resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - - hanji@0.0.5: - resolution: {integrity: sha512-Abxw1Lq+TnYiL4BueXqMau222fPSPMFtya8HdpWsz/xVAhifXou71mPh/kY2+08RgFcVccjG3uZHs6K5HAe3zw==} - - has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} - - hasown@2.0.2: - resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} - engines: {node: '>= 0.4'} - - heap@0.2.7: - resolution: {integrity: sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==} - - hono@4.3.9: - resolution: {integrity: sha512-6c5LVE23HnIS8iBhY+XPmYJlPeeClznOi7mBNsAsJCgxo8Ciz75LTjqRUf5wv4RYq8kL+1KPLUZHCtKmbZssNg==} - engines: {node: '>=16.0.0'} - - human-signals@2.1.0: - resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} - engines: {node: '>=10.17.0'} - - human-signals@5.0.0: - resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} - engines: {node: '>=16.17.0'} - - iconv-lite@0.6.3: - resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} - engines: {node: '>=0.10.0'} - - ieee754@1.2.1: - resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - - ignore-by-default@2.1.0: - resolution: {integrity: sha512-yiWd4GVmJp0Q6ghmM2B/V3oZGRmjrKLXvHR3TE1nfoXsmoggllfZUQe74EN0fJdPFZu2NIvNdrMMLm3OsV7Ohw==} - engines: {node: '>=10 <11 || >=12 <13 || >=14'} - - ignore@5.3.1: - resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} - engines: {node: '>= 4'} - - import-fresh@3.3.0: - resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} - engines: {node: '>=6'} - - imurmurhash@0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} - - indent-string@5.0.0: - resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==} - engines: {node: '>=12'} - - inflight@1.0.6: - resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} - - inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - - ini@1.3.8: - resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} - - irregular-plurals@3.5.0: - resolution: {integrity: sha512-1ANGLZ+Nkv1ptFb2pa8oG8Lem4krflKuX/gINiHJHjJUKaJHk/SXk5x6K3J+39/p0h1RQ2saROclJJ+QLvETCQ==} - engines: {node: '>=8'} - - is-binary-path@2.1.0: - resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} - engines: {node: '>=8'} - - is-core-module@2.13.1: - resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} - - is-error@2.2.2: - resolution: {integrity: sha512-IOQqts/aHWbiisY5DuPJQ0gcbvaLFCa7fBa9xoLfxBZvQ+ZI/Zh9xoI7Gk+G64N0FdK4AbibytHht2tWgpJWLg==} - - is-extglob@2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} - - is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} - - is-fullwidth-code-point@4.0.0: - resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} - engines: {node: '>=12'} - - is-glob@4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} - - is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} - - is-path-inside@3.0.3: - resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} - engines: {node: '>=8'} - - is-plain-object@5.0.0: - resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} - engines: {node: '>=0.10.0'} - - is-promise@2.2.2: - resolution: {integrity: sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==} - - is-promise@4.0.0: - resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} - - is-property@1.0.2: - resolution: {integrity: sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==} - - is-stream@2.0.1: - resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} - engines: {node: '>=8'} - - is-stream@3.0.0: - resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - is-unicode-supported@1.3.0: - resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==} - engines: {node: '>=12'} - - is-what@4.1.16: - resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==} - engines: {node: '>=12.13'} - - isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - - jackspeak@2.3.6: - resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==} - engines: {node: '>=14'} - - joycon@3.1.1: - resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} - engines: {node: '>=10'} - - js-base64@3.7.7: - resolution: {integrity: sha512-7rCnleh0z2CkXhH67J8K1Ytz0b2Y+yxTPL+/KOJoa20hfnVQ/3/T6W/KflYI4bRHRagNeXeU2bkNGI3v1oS/lw==} - - js-string-escape@1.0.1: - resolution: {integrity: sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg==} - engines: {node: '>= 0.8'} - - js-tokens@9.0.0: - resolution: {integrity: sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ==} - - js-yaml@3.14.1: - resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} - hasBin: true - - js-yaml@4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} - hasBin: true - - json-buffer@3.0.1: - resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} - - json-diff@0.9.0: - resolution: {integrity: sha512-cVnggDrVkAAA3OvFfHpFEhOnmcsUpleEKq4d4O8sQWWSH40MBrWstKigVB1kGrgLWzuom+7rRdaCsnBD6VyObQ==} - hasBin: true - - json-diff@1.0.6: - resolution: {integrity: sha512-tcFIPRdlc35YkYdGxcamJjllUhXWv4n2rK9oJ2RsAzV4FBkuV4ojKEDgcZ+kpKxDmJKv+PFK65+1tVVOnSeEqA==} - hasBin: true - - json-schema-traverse@0.4.1: - resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} - - json-stable-stringify-without-jsonify@1.0.1: - resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - - jsonfile@6.1.0: - resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} - - keyv@4.5.4: - resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} - - levn@0.4.1: - resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} - engines: {node: '>= 0.8.0'} - - libsql@0.2.0: - resolution: {integrity: sha512-ELBRqhpJx5Dap0187zKQnntZyk4EjlDHSrjIVL8t+fQ5e8IxbQTeYgZgigMjB1EvrETdkm0Y0VxBGhzPQ+t0Jg==} - cpu: [x64, arm64] - os: [darwin, linux, win32] - - lilconfig@3.1.1: - resolution: {integrity: sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==} - engines: {node: '>=14'} - - lines-and-columns@1.2.4: - resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - - load-json-file@7.0.1: - resolution: {integrity: sha512-Gnxj3ev3mB5TkVBGad0JM6dmLiQL+o0t23JPBZ9sd+yvSLk05mFoqKBw5N8gbbkU4TNXyqCgIrl/VM17OgUIgQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - load-tsconfig@0.2.5: - resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - local-pkg@0.5.0: - resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==} - engines: {node: '>=14'} - - locate-path@6.0.0: - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} - engines: {node: '>=10'} - - locate-path@7.2.0: - resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - lodash.merge@4.6.2: - resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - - lodash.sortby@4.7.0: - resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} - - lodash.throttle@4.1.1: - resolution: {integrity: sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==} - - lodash@4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - - long@4.0.0: - resolution: {integrity: sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==} - - loupe@2.3.7: - resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} - - lru-cache@10.2.2: - resolution: {integrity: sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==} - engines: {node: 14 || >=16.14} - - lru-cache@6.0.0: - resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} - engines: {node: '>=10'} - - lru-cache@7.18.3: - resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} - engines: {node: '>=12'} - - lru-queue@0.1.0: - resolution: {integrity: sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==} - - magic-string@0.25.9: - resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} - - magic-string@0.30.10: - resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==} - - map-age-cleaner@0.1.3: - resolution: {integrity: sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==} - engines: {node: '>=6'} - - map-stream@0.1.0: - resolution: {integrity: sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==} - - marked-terminal@6.2.0: - resolution: {integrity: sha512-ubWhwcBFHnXsjYNsu+Wndpg0zhY4CahSpPlA70PlO0rR9r2sZpkyU+rkCsOWH+KMEkx847UpALON+HWgxowFtw==} - engines: {node: '>=16.0.0'} - peerDependencies: - marked: '>=1 <12' - - marked@9.1.6: - resolution: {integrity: sha512-jcByLnIFkd5gSXZmjNvS1TlmRhCXZjIzHYlaGkPlLIekG55JDR2Z4va9tZwCiP+/RDERiNhMOFu01xd6O5ct1Q==} - engines: {node: '>= 16'} - hasBin: true - - matcher@5.0.0: - resolution: {integrity: sha512-s2EMBOWtXFc8dgqvoAzKJXxNHibcdJMV0gwqKUaw9E2JBJuGUK7DrNKrA6g/i+v72TT16+6sVm5mS3thaMLQUw==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - md5-hex@3.0.1: - resolution: {integrity: sha512-BUiRtTtV39LIJwinWBjqVsU9xhdnz7/i889V859IBFpuqGAj6LuOvHv5XLbgZ2R7ptJoJaEcxkv88/h25T7Ciw==} - engines: {node: '>=8'} - - mem@9.0.2: - resolution: {integrity: sha512-F2t4YIv9XQUBHt6AOJ0y7lSmP1+cY7Fm1DRh9GClTGzKST7UWLMx6ly9WZdLH/G/ppM5RL4MlQfRT71ri9t19A==} - engines: {node: '>=12.20'} - - memoizee@0.4.15: - resolution: {integrity: sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==} - - merge-stream@2.0.0: - resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} - - merge2@1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} - engines: {node: '>= 8'} - - micromatch@4.0.5: - resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} - engines: {node: '>=8.6'} - - mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} - - mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} - - mime@3.0.0: - resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} - engines: {node: '>=10.0.0'} - hasBin: true - - mimic-fn@2.1.0: - resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} - engines: {node: '>=6'} - - mimic-fn@4.0.0: - resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} - engines: {node: '>=12'} - - mimic-response@3.1.0: - resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} - engines: {node: '>=10'} - - miniflare@3.20240512.0: - resolution: {integrity: sha512-X0PlKR0AROKpxFoJNmRtCMIuJxj+ngEcyTOlEokj2rAQ0TBwUhB4/1uiPvdI6ofW5NugPOD1uomAv+gLjwsLDQ==} - engines: {node: '>=16.13'} - hasBin: true - - minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - - minimatch@5.1.6: - resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} - engines: {node: '>=10'} - - minimatch@7.4.6: - resolution: {integrity: sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==} - engines: {node: '>=10'} - - minimatch@9.0.4: - resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==} - engines: {node: '>=16 || 14 >=14.17'} - - minimist@1.2.8: - resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - - minipass@7.1.1: - resolution: {integrity: sha512-UZ7eQ+h8ywIRAW1hIEl2AqdwzJucU/Kp59+8kkZeSvafXhZjul247BvIJjEVFVeON6d7lM46XX1HXCduKAS8VA==} - engines: {node: '>=16 || 14 >=14.17'} - - mkdirp-classic@0.5.3: - resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} - - mlly@1.7.0: - resolution: {integrity: sha512-U9SDaXGEREBYQgfejV97coK0UL1r+qnF2SyO9A3qcI8MzKnsIFKHNVEkrDyNncQTKQQumsasmeq84eNMdBfsNQ==} - - ms@2.1.2: - resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} - - ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - - mustache@4.2.0: - resolution: {integrity: sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==} - hasBin: true - - mysql2@2.3.3: - resolution: {integrity: sha512-wxJUev6LgMSgACDkb/InIFxDprRa6T95+VEoR+xPvtngtccNH2dGjEB/fVZ8yg1gWv1510c9CvXuJHi5zUm0ZA==} - engines: {node: '>= 8.0'} - - mz@2.7.0: - resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} - - named-placeholders@1.1.3: - resolution: {integrity: sha512-eLoBxg6wE/rZkJPhU/xRX1WTpkFEwDJEN96oxFrTsqBdbT5ec295Q+CoHrL9IT0DipqKhmGcaZmwOt8OON5x1w==} - engines: {node: '>=12.0.0'} - - nan@2.19.0: - resolution: {integrity: sha512-nO1xXxfh/RWNxfd/XPfbIfFk5vgLsAxUR9y5O0cHMJu/AW9U95JLXqthYHjEp+8gQ5p96K9jUp8nbVOxCdRbtw==} - - nanoid@3.3.7: - resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - - napi-build-utils@1.0.2: - resolution: {integrity: sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==} - - natural-compare@1.4.0: - resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - - next-tick@1.1.0: - resolution: {integrity: sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==} - - node-abi@3.62.0: - resolution: {integrity: sha512-CPMcGa+y33xuL1E0TcNIu4YyaZCxnnvkVaEXrsosR3FxN+fV8xvb7Mzpb7IgKler10qeMkE6+Dp8qJhpzdq35g==} - engines: {node: '>=10'} - - node-domexception@1.0.0: - resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} - engines: {node: '>=10.5.0'} - - node-emoji@2.1.3: - resolution: {integrity: sha512-E2WEOVsgs7O16zsURJ/eH8BqhF029wGpEOnv7Urwdo2wmQanOACwJQh0devF9D9RhoZru0+9JXIS0dBXIAz+lA==} - engines: {node: '>=18'} - - node-fetch@2.7.0: - resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} - engines: {node: 4.x || >=6.0.0} - peerDependencies: - encoding: ^0.1.0 - peerDependenciesMeta: - encoding: - optional: true - - node-fetch@3.3.1: - resolution: {integrity: sha512-cRVc/kyto/7E5shrWca1Wsea4y6tL9iYJE5FBCius3JQfb/4P4I295PfhgbJQBLTx6lATE4z+wK0rPM4VS2uow==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - node-fetch@3.3.2: - resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - node-forge@1.3.1: - resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} - engines: {node: '>= 6.13.0'} - - node-gyp-build@4.8.1: - resolution: {integrity: sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw==} - hasBin: true - - nofilter@3.1.0: - resolution: {integrity: sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==} - engines: {node: '>=12.19'} - - normalize-path@3.0.0: - resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} - engines: {node: '>=0.10.0'} - - npm-run-path@4.0.1: - resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} - engines: {node: '>=8'} - - npm-run-path@5.3.0: - resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - object-assign@4.1.1: - resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} - engines: {node: '>=0.10.0'} - - obuf@1.1.2: - resolution: {integrity: sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==} - - once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - - onetime@5.1.2: - resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} - engines: {node: '>=6'} - - onetime@6.0.0: - resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} - engines: {node: '>=12'} - - optionator@0.9.4: - resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} - engines: {node: '>= 0.8.0'} - - p-defer@1.0.0: - resolution: {integrity: sha512-wB3wfAxZpk2AzOfUMJNL+d36xothRSyj8EXOa4f6GMqYDN9BJaaSISbsk+wS9abmnebVw95C2Kb5t85UmpCxuw==} - engines: {node: '>=4'} - - p-event@5.0.1: - resolution: {integrity: sha512-dd589iCQ7m1L0bmC5NLlVYfy3TbBEsMUfWx9PyAgPeIcFZ/E2yaTZ4Rz4MiBmmJShviiftHVXOqfnfzJ6kyMrQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - p-limit@3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} - - p-limit@4.0.0: - resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - p-limit@5.0.0: - resolution: {integrity: sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==} - engines: {node: '>=18'} - - p-locate@5.0.0: - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} - engines: {node: '>=10'} - - p-locate@6.0.0: - resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - p-map@5.5.0: - resolution: {integrity: sha512-VFqfGDHlx87K66yZrNdI4YGtD70IRyd+zSvgks6mzHPRNkoKy+9EKP4SFC77/vTTQYmRmti7dvqC+m5jBrBAcg==} - engines: {node: '>=12'} - - p-timeout@5.1.0: - resolution: {integrity: sha512-auFDyzzzGZZZdHz3BtET9VEz0SE/uMEAx7uWfGPucfzEwwe/xH0iVeZibQmANYE/hp9T2+UUZT5m+BKyrDp3Ew==} - engines: {node: '>=12'} - - parent-module@1.0.1: - resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} - engines: {node: '>=6'} - - parse-ms@3.0.0: - resolution: {integrity: sha512-Tpb8Z7r7XbbtBTrM9UhpkzzaMrqA2VXMT3YChzYltwV3P3pM6t8wl7TvpMnSTosz1aQAdVib7kdoys7vYOPerw==} - engines: {node: '>=12'} - - path-exists@4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} - - path-exists@5.0.0: - resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - path-is-absolute@1.0.1: - resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} - engines: {node: '>=0.10.0'} - - path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} - - path-key@4.0.0: - resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} - engines: {node: '>=12'} - - path-parse@1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - - path-scurry@1.11.1: - resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} - engines: {node: '>=16 || 14 >=14.18'} - - path-to-regexp@6.2.2: - resolution: {integrity: sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==} - - path-type@4.0.0: - resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} - engines: {node: '>=8'} - - pathe@1.1.2: - resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} - - pathval@1.1.1: - resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} - - pause-stream@0.0.11: - resolution: {integrity: sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==} - - pg-cloudflare@1.1.1: - resolution: {integrity: sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==} - - pg-connection-string@2.6.4: - resolution: {integrity: sha512-v+Z7W/0EO707aNMaAEfiGnGL9sxxumwLl2fJvCQtMn9Fxsg+lPpPkdcyBSv/KFgpGdYkMfn+EI1Or2EHjpgLCA==} - - pg-int8@1.0.1: - resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==} - engines: {node: '>=4.0.0'} - - pg-numeric@1.0.2: - resolution: {integrity: sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw==} - engines: {node: '>=4'} - - pg-pool@3.6.2: - resolution: {integrity: sha512-Htjbg8BlwXqSBQ9V8Vjtc+vzf/6fVUuak/3/XXKA9oxZprwW3IMDQTGHP+KDmVL7rtd+R1QjbnCFPuTHm3G4hg==} - peerDependencies: - pg: '>=8.0' - - pg-protocol@1.6.1: - resolution: {integrity: sha512-jPIlvgoD63hrEuihvIg+tJhoGjUsLPn6poJY9N5CnlPd91c2T18T/9zBtLxZSb1EhYxBRoZJtzScCaWlYLtktg==} - - pg-types@2.2.0: - resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==} - engines: {node: '>=4'} - - pg-types@4.0.2: - resolution: {integrity: sha512-cRL3JpS3lKMGsKaWndugWQoLOCoP+Cic8oseVcbr0qhPzYD5DWXK+RZ9LY9wxRf7RQia4SCwQlXk0q6FCPrVng==} - engines: {node: '>=10'} - - pg@8.11.5: - resolution: {integrity: sha512-jqgNHSKL5cbDjFlHyYsCXmQDrfIX/3RsNwYqpd4N0Kt8niLuNoRNH+aazv6cOd43gPh9Y4DjQCtb+X0MH0Hvnw==} - engines: {node: '>= 8.0.0'} - peerDependencies: - pg-native: '>=3.0.1' - peerDependenciesMeta: - pg-native: - optional: true - - pgpass@1.0.5: - resolution: {integrity: sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==} - - picocolors@1.0.1: - resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} - - picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} - - pirates@4.0.6: - resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} - engines: {node: '>= 6'} - - pkg-conf@4.0.0: - resolution: {integrity: sha512-7dmgi4UY4qk+4mj5Cd8v/GExPo0K+SlY+hulOSdfZ/T6jVH6//y7NtzZo5WrfhDBxuQ0jCa7fLZmNaNh7EWL/w==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - pkg-types@1.1.1: - resolution: {integrity: sha512-ko14TjmDuQJ14zsotODv7dBlwxKhUKQEhuhmbqo1uCi9BB0Z2alo/wAXg6q1dTR5TyuqYyWhjtfe/Tsh+X28jQ==} - - plur@5.1.0: - resolution: {integrity: sha512-VP/72JeXqak2KiOzjgKtQen5y3IZHn+9GOuLDafPv0eXa47xq0At93XahYBs26MsifCQ4enGKwbjBTKgb9QJXg==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - pluralize@8.0.0: - resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} - engines: {node: '>=4'} - - postcss-load-config@4.0.2: - resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==} - engines: {node: '>= 14'} - peerDependencies: - postcss: '>=8.0.9' - ts-node: '>=9.0.0' - peerDependenciesMeta: - postcss: - optional: true - ts-node: - optional: true - - postcss@8.4.38: - resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==} - engines: {node: ^10 || ^12 || >=14} - - postgres-array@2.0.0: - resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} - engines: {node: '>=4'} - - postgres-array@3.0.2: - resolution: {integrity: sha512-6faShkdFugNQCLwucjPcY5ARoW1SlbnrZjmGl0IrrqewpvxvhSLHimCVzqeuULCbG0fQv7Dtk1yDbG3xv7Veog==} - engines: {node: '>=12'} - - postgres-bytea@1.0.0: - resolution: {integrity: sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==} - engines: {node: '>=0.10.0'} - - postgres-bytea@3.0.0: - resolution: {integrity: sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw==} - engines: {node: '>= 6'} - - postgres-date@1.0.7: - resolution: {integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==} - engines: {node: '>=0.10.0'} - - postgres-date@2.1.0: - resolution: {integrity: sha512-K7Juri8gtgXVcDfZttFKVmhglp7epKb1K4pgrkLxehjqkrgPhfG6OO8LHLkfaqkbpjNRnra018XwAr1yQFWGcA==} - engines: {node: '>=12'} - - postgres-interval@1.2.0: - resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==} - engines: {node: '>=0.10.0'} - - postgres-interval@3.0.0: - resolution: {integrity: sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw==} - engines: {node: '>=12'} - - postgres-range@1.1.4: - resolution: {integrity: sha512-i/hbxIE9803Alj/6ytL7UHQxRvZkI9O4Sy+J3HGc4F4oo/2eQAjTSNJ0bfxyse3bH0nuVesCk+3IRLaMtG3H6w==} - - postgres@3.4.4: - resolution: {integrity: sha512-IbyN+9KslkqcXa8AO9fxpk97PA4pzewvpi2B3Dwy9u4zpV32QicaEdgmF3eSQUzdRk7ttDHQejNgAEr4XoeH4A==} - engines: {node: '>=12'} - - prebuild-install@7.1.2: - resolution: {integrity: sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==} - engines: {node: '>=10'} - hasBin: true - - prelude-ls@1.2.1: - resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} - engines: {node: '>= 0.8.0'} - - prettier-linter-helpers@1.0.0: - resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} - engines: {node: '>=6.0.0'} - - prettier@2.8.8: - resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} - engines: {node: '>=10.13.0'} - hasBin: true - - pretty-format@29.7.0: - resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - pretty-ms@8.0.0: - resolution: {integrity: sha512-ASJqOugUF1bbzI35STMBUpZqdfYKlJugy6JBziGi2EE+AL5JPJGSzvpeVXojxrr0ViUYoToUjb5kjSEGf7Y83Q==} - engines: {node: '>=14.16'} - - printable-characters@1.0.42: - resolution: {integrity: sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==} - - ps-tree@1.2.0: - resolution: {integrity: sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==} - engines: {node: '>= 0.10'} - hasBin: true - - pump@3.0.0: - resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} - - punycode@2.3.1: - resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} - engines: {node: '>=6'} - - queue-microtask@1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - - rc@1.2.8: - resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} - hasBin: true - - react-is@18.3.1: - resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} - - readable-stream@3.6.2: - resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} - engines: {node: '>= 6'} - - readdirp@3.6.0: - resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} - engines: {node: '>=8.10.0'} - - redeyed@2.1.1: - resolution: {integrity: sha512-FNpGGo1DycYAdnrKFxCMmKYgo/mILAqtRYbkdQD8Ep/Hk2PQ5+aEAEx+IU713RTDmuBaH0c8P5ZozurNu5ObRQ==} - - require-directory@2.1.1: - resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} - engines: {node: '>=0.10.0'} - - resolve-cwd@3.0.0: - resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} - engines: {node: '>=8'} - - resolve-from@4.0.0: - resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} - engines: {node: '>=4'} - - resolve-from@5.0.0: - resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} - engines: {node: '>=8'} - - resolve-pkg-maps@1.0.0: - resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} - - resolve.exports@2.0.2: - resolution: {integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==} - engines: {node: '>=10'} - - resolve@1.22.8: - resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} - hasBin: true - - reusify@1.0.4: - resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} - engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - - rimraf@3.0.2: - resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} - hasBin: true - - rollup-plugin-inject@3.0.2: - resolution: {integrity: sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w==} - deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-inject. - - rollup-plugin-node-polyfills@0.2.1: - resolution: {integrity: sha512-4kCrKPTJ6sK4/gLL/U5QzVT8cxJcofO0OU74tnB19F40cmuAKSzH5/siithxlofFEjwvw1YAhPmbvGNA6jEroA==} - - rollup-pluginutils@2.8.2: - resolution: {integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==} - - rollup@4.17.2: - resolution: {integrity: sha512-/9ClTJPByC0U4zNLowV1tMBe8yMEAxewtR3cUNX5BoEpGH3dQEWpJLr6CLp0fPdYRF/fzVOgvDb1zXuakwF5kQ==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} - hasBin: true - - run-parallel@1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - - safe-buffer@5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - - safer-buffer@2.1.2: - resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - - selfsigned@2.4.1: - resolution: {integrity: sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==} - engines: {node: '>=10'} - - semver@7.6.2: - resolution: {integrity: sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==} - engines: {node: '>=10'} - hasBin: true - - seq-queue@0.0.5: - resolution: {integrity: sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q==} - - serialize-error@7.0.1: - resolution: {integrity: sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==} - engines: {node: '>=10'} - - shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} - - shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} - - siginfo@2.0.0: - resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} - - signal-exit@3.0.7: - resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} - - signal-exit@4.1.0: - resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} - engines: {node: '>=14'} - - simple-concat@1.0.1: - resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} - - simple-get@4.0.1: - resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} - - sisteransi@1.0.5: - resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} - - skin-tone@2.0.0: - resolution: {integrity: sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==} - engines: {node: '>=8'} - - slash@3.0.0: - resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} - engines: {node: '>=8'} - - slash@4.0.0: - resolution: {integrity: sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==} - engines: {node: '>=12'} - - slice-ansi@5.0.0: - resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} - engines: {node: '>=12'} - - source-map-js@1.2.0: - resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} - engines: {node: '>=0.10.0'} - - source-map-support@0.5.21: - resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} - - source-map@0.6.1: - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} - engines: {node: '>=0.10.0'} - - source-map@0.8.0-beta.0: - resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} - engines: {node: '>= 8'} - - sourcemap-codec@1.4.8: - resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} - deprecated: Please use @jridgewell/sourcemap-codec instead - - split-ca@1.0.1: - resolution: {integrity: sha512-Q5thBSxp5t8WPTTJQS59LrGqOZqOsrhDGDVm8azCqIBjSBd7nd9o2PM+mDulQQkh8h//4U6hFZnc/mul8t5pWQ==} - - split2@4.2.0: - resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} - engines: {node: '>= 10.x'} - - split@0.3.3: - resolution: {integrity: sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA==} - - sprintf-js@1.0.3: - resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} - - sqlstring@2.3.3: - resolution: {integrity: sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==} - engines: {node: '>= 0.6'} - - ssh2@1.15.0: - resolution: {integrity: sha512-C0PHgX4h6lBxYx7hcXwu3QWdh4tg6tZZsTfXcdvc5caW/EMxaB4H9dWsl7qk+F7LAW762hp8VbXOX7x4xUYvEw==} - engines: {node: '>=10.16.0'} - - stack-utils@2.0.6: - resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} - engines: {node: '>=10'} - - stackback@0.0.2: - resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} - - stacktracey@2.1.8: - resolution: {integrity: sha512-Kpij9riA+UNg7TnphqjH7/CzctQ/owJGNbFkfEeve4Z4uxT5+JapVLFXcsurIfN34gnTWZNJ/f7NMG0E8JDzTw==} - - std-env@3.7.0: - resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} - - stoppable@1.1.0: - resolution: {integrity: sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==} - engines: {node: '>=4', npm: '>=6'} - - stream-combiner@0.0.4: - resolution: {integrity: sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==} - - string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} - - string-width@5.1.2: - resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} - engines: {node: '>=12'} - - string_decoder@1.3.0: - resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} - - strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} - - strip-ansi@7.1.0: - resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} - engines: {node: '>=12'} - - strip-final-newline@2.0.0: - resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} - engines: {node: '>=6'} - - strip-final-newline@3.0.0: - resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} - engines: {node: '>=12'} - - strip-json-comments@2.0.1: - resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} - engines: {node: '>=0.10.0'} - - strip-json-comments@3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} - - strip-literal@2.1.0: - resolution: {integrity: sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==} - - strnum@1.0.5: - resolution: {integrity: sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==} - - sucrase@3.35.0: - resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} - engines: {node: '>=16 || 14 >=14.17'} - hasBin: true - - superjson@2.2.1: - resolution: {integrity: sha512-8iGv75BYOa0xRJHK5vRLEjE2H/i4lulTjzpUXic3Eg8akftYjkmQDa8JARQ42rlczXyFR3IeRoeFCc7RxHsYZA==} - engines: {node: '>=16'} - - supertap@3.0.1: - resolution: {integrity: sha512-u1ZpIBCawJnO+0QePsEiOknOfCRq0yERxiAchT0i4li0WHNUJbf0evXXSXOcCAR4M8iMDoajXYmstm/qO81Isw==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} - - supports-hyperlinks@3.0.0: - resolution: {integrity: sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==} - engines: {node: '>=14.18'} - - supports-preserve-symlinks-flag@1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} - - synckit@0.8.8: - resolution: {integrity: sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==} - engines: {node: ^14.18.0 || >=16.0.0} - - tar-fs@2.0.1: - resolution: {integrity: sha512-6tzWDMeroL87uF/+lin46k+Q+46rAJ0SyPGz7OW7wTgblI273hsBqk2C1j0/xNadNLKDTUL9BukSjB7cwgmlPA==} - - tar-fs@2.1.1: - resolution: {integrity: sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==} - - tar-stream@2.2.0: - resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} - engines: {node: '>=6'} - - temp-dir@3.0.0: - resolution: {integrity: sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==} - engines: {node: '>=14.16'} - - text-table@0.2.0: - resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} - - thenify-all@1.6.0: - resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} - engines: {node: '>=0.8'} - - thenify@3.3.1: - resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} - - through@2.3.8: - resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} - - time-zone@1.0.0: - resolution: {integrity: sha512-TIsDdtKo6+XrPtiTm1ssmMngN1sAhyKnTO2kunQWqNPWIVvCm15Wmw4SWInwTVgJ5u/Tr04+8Ei9TNcw4x4ONA==} - engines: {node: '>=4'} - - timers-ext@0.1.7: - resolution: {integrity: sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==} - - tinybench@2.8.0: - resolution: {integrity: sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==} - - tinypool@0.8.4: - resolution: {integrity: sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==} - engines: {node: '>=14.0.0'} - - tinyspy@2.2.1: - resolution: {integrity: sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==} - engines: {node: '>=14.0.0'} - - to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} - - tr46@0.0.3: - resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} - - tr46@1.0.1: - resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==} - - tree-kill@1.2.2: - resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} - hasBin: true - - ts-api-utils@1.3.0: - resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==} - engines: {node: '>=16'} - peerDependencies: - typescript: '>=4.2.0' - - ts-expose-internals-conditionally@1.0.0-empty.0: - resolution: {integrity: sha512-F8m9NOF6ZhdOClDVdlM8gj3fDCav4ZIFSs/EI3ksQbAAXVSCN/Jh5OCJDDZWBuBy9psFc6jULGDlPwjMYMhJDw==} - - ts-interface-checker@0.1.13: - resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} - - tsconfck@3.0.3: - resolution: {integrity: sha512-4t0noZX9t6GcPTfBAbIbbIU4pfpCwh0ueq3S4O/5qXI1VwK1outmxhe9dOiEWqMz3MW2LKgDTpqWV+37IWuVbA==} - engines: {node: ^18 || >=20} - hasBin: true - peerDependencies: - typescript: ^5.0.0 - peerDependenciesMeta: - typescript: - optional: true - - tslib@1.14.1: - resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} - - tslib@2.6.2: - resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} - - tsup@8.0.2: - resolution: {integrity: sha512-NY8xtQXdH7hDUAZwcQdY/Vzlw9johQsaqf7iwZ6g1DOUlFYQ5/AtVAjTvihhEyeRlGo4dLRVHtrRaL35M1daqQ==} - engines: {node: '>=18'} - hasBin: true - peerDependencies: - '@microsoft/api-extractor': ^7.36.0 - '@swc/core': ^1 - postcss: ^8.4.12 - typescript: '>=4.5.0' - peerDependenciesMeta: - '@microsoft/api-extractor': - optional: true - '@swc/core': - optional: true - postcss: - optional: true - typescript: - optional: true - - tsx@3.14.0: - resolution: {integrity: sha512-xHtFaKtHxM9LOklMmJdI3BEnQq/D5F73Of2E1GDrITi9sgoVkvIsrQUTY1G8FlmGtA+awCI4EBlTRRYxkL2sRg==} - hasBin: true - - tunnel-agent@0.6.0: - resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} - - tweetnacl@0.14.5: - resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==} - - type-check@0.4.0: - resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} - engines: {node: '>= 0.8.0'} - - type-detect@4.0.8: - resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} - engines: {node: '>=4'} - - type-fest@0.13.1: - resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==} - engines: {node: '>=10'} - - type-fest@0.20.2: - resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} - engines: {node: '>=10'} - - type@2.7.2: - resolution: {integrity: sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==} - - typescript@5.3.3: - resolution: {integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==} - engines: {node: '>=14.17'} - hasBin: true - - typescript@5.4.5: - resolution: {integrity: sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==} - engines: {node: '>=14.17'} - hasBin: true - - ufo@1.5.3: - resolution: {integrity: sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==} - - undici-types@5.26.5: - resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} - - undici@5.28.4: - resolution: {integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==} - engines: {node: '>=14.0'} - - unicode-emoji-modifier-base@1.0.0: - resolution: {integrity: sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==} - engines: {node: '>=4'} - - universalify@2.0.1: - resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} - engines: {node: '>= 10.0.0'} - - uri-js@4.4.1: - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - - utf-8-validate@6.0.3: - resolution: {integrity: sha512-uIuGf9TWQ/y+0Lp+KGZCMuJWc3N9BHA+l/UmHd/oUHwJJDeysyTRxNQVkbzsIWfGFbRe3OcgML/i0mvVRPOyDA==} - engines: {node: '>=6.14.2'} - - util-deprecate@1.0.2: - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - - uuid@9.0.1: - resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} - hasBin: true - - validate-npm-package-name@5.0.1: - resolution: {integrity: sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - - vite-node@1.6.0: - resolution: {integrity: sha512-de6HJgzC+TFzOu0NTC4RAIsyf/DY/ibWDYQUcuEA84EMHhcefTUGkjFHKKEJhQN4A+6I0u++kr3l36ZF2d7XRw==} - engines: {node: ^18.0.0 || >=20.0.0} - hasBin: true - - vite-tsconfig-paths@4.3.2: - resolution: {integrity: sha512-0Vd/a6po6Q+86rPlntHye7F31zA2URZMbH8M3saAZ/xR9QoGN/L21bxEGfXdWmFdNkqPpRdxFT7nmNe12e9/uA==} - peerDependencies: - vite: '*' - peerDependenciesMeta: - vite: - optional: true - - vite@5.2.11: - resolution: {integrity: sha512-HndV31LWW05i1BLPMUCE1B9E9GFbOu1MbenhS58FuK6owSO5qHm7GiCotrNY1YE5rMeQSFBGmT5ZaLEjFizgiQ==} - engines: {node: ^18.0.0 || >=20.0.0} - hasBin: true - peerDependencies: - '@types/node': ^18.0.0 || >=20.0.0 - less: '*' - lightningcss: ^1.21.0 - sass: '*' - stylus: '*' - sugarss: '*' - terser: ^5.4.0 - peerDependenciesMeta: - '@types/node': - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - - vitest@1.6.0: - resolution: {integrity: sha512-H5r/dN06swuFnzNFhq/dnz37bPXnq8xB2xB5JOVk8K09rUtoeNN+LHWkoQ0A/i3hvbUKKcCei9KpbxqHMLhLLA==} - 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.6.0 - '@vitest/ui': 1.6.0 - happy-dom: '*' - jsdom: '*' - peerDependenciesMeta: - '@edge-runtime/vm': - optional: true - '@types/node': - optional: true - '@vitest/browser': - optional: true - '@vitest/ui': - optional: true - happy-dom: - optional: true - jsdom: - optional: true - - web-streams-polyfill@3.3.3: - resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} - engines: {node: '>= 8'} - - webidl-conversions@3.0.1: - resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} - - webidl-conversions@4.0.2: - resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} - - webpod@0.0.2: - resolution: {integrity: sha512-cSwwQIeg8v4i3p4ajHhwgR7N6VyxAf+KYSSsY6Pd3aETE+xEU4vbitz7qQkB0I321xnhDdgtxuiSfk5r/FVtjg==} - hasBin: true - - well-known-symbols@2.0.0: - resolution: {integrity: sha512-ZMjC3ho+KXo0BfJb7JgtQ5IBuvnShdlACNkKkdsqBmYw3bPAaJfPeYUo6tLUaT5tG/Gkh7xkpBhKRQ9e7pyg9Q==} - engines: {node: '>=6'} - - whatwg-url@5.0.0: - resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} - - whatwg-url@7.1.0: - resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==} - - which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true - - which@3.0.1: - resolution: {integrity: sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - hasBin: true - - why-is-node-running@2.2.2: - resolution: {integrity: sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==} - engines: {node: '>=8'} - hasBin: true - - word-wrap@1.2.5: - resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} - engines: {node: '>=0.10.0'} - - wordwrap@1.0.0: - resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} - - workerd@1.20240512.0: - resolution: {integrity: sha512-VUBmR1PscAPHEE0OF/G2K7/H1gnr9aDWWZzdkIgWfNKkv8dKFCT75H+GJtUHjfwqz3rYCzaNZmatSXOpLGpF8A==} - engines: {node: '>=16'} - hasBin: true - - wrangler@3.57.0: - resolution: {integrity: sha512-izK3AZtlFoTq8N0EZjLOQ7hqwsjaXCc1cbNKuhsLJjDX1jB1YZBDPhIhtXL4VVzkJAcH+0Zw2gguOePFCHNaxw==} - engines: {node: '>=16.17.0'} - hasBin: true - peerDependencies: - '@cloudflare/workers-types': ^4.20240512.0 - peerDependenciesMeta: - '@cloudflare/workers-types': - optional: true - - wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} - - wrap-ansi@8.1.0: - resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} - engines: {node: '>=12'} - - wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - - write-file-atomic@5.0.1: - resolution: {integrity: sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - - ws@8.14.2: - resolution: {integrity: sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: '>=5.0.2' - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - - ws@8.17.0: - resolution: {integrity: sha512-uJq6108EgZMAl20KagGkzCKfMEjxmKvZHG7Tlq0Z6nOky7YF7aq4mOx6xK8TJ/i1LeK4Qus7INktacctDgY8Ow==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: '>=5.0.2' - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - - xtend@4.0.2: - resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} - engines: {node: '>=0.4'} - - xxhash-wasm@1.0.2: - resolution: {integrity: sha512-ibF0Or+FivM9lNrg+HGJfVX8WJqgo+kCLDc4vx6xMeTce7Aj+DLttKbxxRR/gNLSAelRc1omAPlJ77N/Jem07A==} - - y18n@5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} - engines: {node: '>=10'} - - yallist@4.0.0: - resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} - - yaml@2.4.2: - resolution: {integrity: sha512-B3VqDZ+JAg1nZpaEmWtTXUlBneoGx6CPM9b0TENK6aoSu5t73dItudwdgmi6tHlIZZId4dZ9skcAQ2UbcyAeVA==} - engines: {node: '>= 14'} - hasBin: true - - yargs-parser@21.1.1: - resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} - engines: {node: '>=12'} - - yargs@17.7.2: - resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} - engines: {node: '>=12'} - - yocto-queue@0.1.0: - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} - engines: {node: '>=10'} - - yocto-queue@1.0.0: - resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==} - engines: {node: '>=12.20'} - - youch@3.3.3: - resolution: {integrity: sha512-qSFXUk3UZBLfggAW3dJKg0BMblG5biqSF8M34E06o5CSsZtH92u9Hqmj2RzGiHDi64fhe83+4tENFP2DB6t6ZA==} - - zod@3.23.8: - resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} - - zx@7.2.3: - resolution: {integrity: sha512-QODu38nLlYXg/B/Gw7ZKiZrvPkEsjPN3LQ5JFXM7h0JvwhEdPNNl+4Ao1y4+o3CLNiDUNcwzQYZ4/Ko7kKzCMA==} - engines: {node: '>= 16.0.0'} - hasBin: true - -snapshots: - - '@andrewbranch/untar.js@1.0.3': {} - - '@arethetypeswrong/cli@0.15.3': - dependencies: - '@arethetypeswrong/core': 0.15.1 - chalk: 4.1.2 - cli-table3: 0.6.5 - commander: 10.0.1 - marked: 9.1.6 - marked-terminal: 6.2.0(marked@9.1.6) - semver: 7.6.2 - - '@arethetypeswrong/core@0.15.1': - dependencies: - '@andrewbranch/untar.js': 1.0.3 - fflate: 0.8.2 - semver: 7.6.2 - ts-expose-internals-conditionally: 1.0.0-empty.0 - typescript: 5.3.3 - validate-npm-package-name: 5.0.1 - - '@aws-crypto/ie11-detection@3.0.0': - dependencies: - tslib: 1.14.1 - - '@aws-crypto/sha256-browser@3.0.0': - dependencies: - '@aws-crypto/ie11-detection': 3.0.0 - '@aws-crypto/sha256-js': 3.0.0 - '@aws-crypto/supports-web-crypto': 3.0.0 - '@aws-crypto/util': 3.0.0 - '@aws-sdk/types': 3.577.0 - '@aws-sdk/util-locate-window': 3.568.0 - '@aws-sdk/util-utf8-browser': 3.259.0 - tslib: 1.14.1 - - '@aws-crypto/sha256-js@3.0.0': - dependencies: - '@aws-crypto/util': 3.0.0 - '@aws-sdk/types': 3.577.0 - tslib: 1.14.1 - - '@aws-crypto/supports-web-crypto@3.0.0': - dependencies: - tslib: 1.14.1 - - '@aws-crypto/util@3.0.0': - dependencies: - '@aws-sdk/types': 3.577.0 - '@aws-sdk/util-utf8-browser': 3.259.0 - tslib: 1.14.1 - - '@aws-sdk/client-rds-data@3.577.0': - dependencies: - '@aws-crypto/sha256-browser': 3.0.0 - '@aws-crypto/sha256-js': 3.0.0 - '@aws-sdk/client-sso-oidc': 3.577.0(@aws-sdk/client-sts@3.577.0) - '@aws-sdk/client-sts': 3.577.0 - '@aws-sdk/core': 3.576.0 - '@aws-sdk/credential-provider-node': 3.577.0(@aws-sdk/client-sso-oidc@3.577.0(@aws-sdk/client-sts@3.577.0))(@aws-sdk/client-sts@3.577.0) - '@aws-sdk/middleware-host-header': 3.577.0 - '@aws-sdk/middleware-logger': 3.577.0 - '@aws-sdk/middleware-recursion-detection': 3.577.0 - '@aws-sdk/middleware-user-agent': 3.577.0 - '@aws-sdk/region-config-resolver': 3.577.0 - '@aws-sdk/types': 3.577.0 - '@aws-sdk/util-endpoints': 3.577.0 - '@aws-sdk/util-user-agent-browser': 3.577.0 - '@aws-sdk/util-user-agent-node': 3.577.0 - '@smithy/config-resolver': 3.0.0 - '@smithy/core': 2.0.1 - '@smithy/fetch-http-handler': 3.0.1 - '@smithy/hash-node': 3.0.0 - '@smithy/invalid-dependency': 3.0.0 - '@smithy/middleware-content-length': 3.0.0 - '@smithy/middleware-endpoint': 3.0.0 - '@smithy/middleware-retry': 3.0.1 - '@smithy/middleware-serde': 3.0.0 - '@smithy/middleware-stack': 3.0.0 - '@smithy/node-config-provider': 3.0.0 - '@smithy/node-http-handler': 3.0.0 - '@smithy/protocol-http': 4.0.0 - '@smithy/smithy-client': 3.0.1 - '@smithy/types': 3.0.0 - '@smithy/url-parser': 3.0.0 - '@smithy/util-base64': 3.0.0 - '@smithy/util-body-length-browser': 3.0.0 - '@smithy/util-body-length-node': 3.0.0 - '@smithy/util-defaults-mode-browser': 3.0.1 - '@smithy/util-defaults-mode-node': 3.0.1 - '@smithy/util-endpoints': 2.0.0 - '@smithy/util-middleware': 3.0.0 - '@smithy/util-retry': 3.0.0 - '@smithy/util-utf8': 3.0.0 - tslib: 2.6.2 - transitivePeerDependencies: - - aws-crt - - '@aws-sdk/client-sso-oidc@3.577.0(@aws-sdk/client-sts@3.577.0)': - dependencies: - '@aws-crypto/sha256-browser': 3.0.0 - '@aws-crypto/sha256-js': 3.0.0 - '@aws-sdk/client-sts': 3.577.0 - '@aws-sdk/core': 3.576.0 - '@aws-sdk/credential-provider-node': 3.577.0(@aws-sdk/client-sso-oidc@3.577.0(@aws-sdk/client-sts@3.577.0))(@aws-sdk/client-sts@3.577.0) - '@aws-sdk/middleware-host-header': 3.577.0 - '@aws-sdk/middleware-logger': 3.577.0 - '@aws-sdk/middleware-recursion-detection': 3.577.0 - '@aws-sdk/middleware-user-agent': 3.577.0 - '@aws-sdk/region-config-resolver': 3.577.0 - '@aws-sdk/types': 3.577.0 - '@aws-sdk/util-endpoints': 3.577.0 - '@aws-sdk/util-user-agent-browser': 3.577.0 - '@aws-sdk/util-user-agent-node': 3.577.0 - '@smithy/config-resolver': 3.0.0 - '@smithy/core': 2.0.1 - '@smithy/fetch-http-handler': 3.0.1 - '@smithy/hash-node': 3.0.0 - '@smithy/invalid-dependency': 3.0.0 - '@smithy/middleware-content-length': 3.0.0 - '@smithy/middleware-endpoint': 3.0.0 - '@smithy/middleware-retry': 3.0.1 - '@smithy/middleware-serde': 3.0.0 - '@smithy/middleware-stack': 3.0.0 - '@smithy/node-config-provider': 3.0.0 - '@smithy/node-http-handler': 3.0.0 - '@smithy/protocol-http': 4.0.0 - '@smithy/smithy-client': 3.0.1 - '@smithy/types': 3.0.0 - '@smithy/url-parser': 3.0.0 - '@smithy/util-base64': 3.0.0 - '@smithy/util-body-length-browser': 3.0.0 - '@smithy/util-body-length-node': 3.0.0 - '@smithy/util-defaults-mode-browser': 3.0.1 - '@smithy/util-defaults-mode-node': 3.0.1 - '@smithy/util-endpoints': 2.0.0 - '@smithy/util-middleware': 3.0.0 - '@smithy/util-retry': 3.0.0 - '@smithy/util-utf8': 3.0.0 - tslib: 2.6.2 - transitivePeerDependencies: - - '@aws-sdk/client-sts' - - aws-crt - - '@aws-sdk/client-sso@3.577.0': - dependencies: - '@aws-crypto/sha256-browser': 3.0.0 - '@aws-crypto/sha256-js': 3.0.0 - '@aws-sdk/core': 3.576.0 - '@aws-sdk/middleware-host-header': 3.577.0 - '@aws-sdk/middleware-logger': 3.577.0 - '@aws-sdk/middleware-recursion-detection': 3.577.0 - '@aws-sdk/middleware-user-agent': 3.577.0 - '@aws-sdk/region-config-resolver': 3.577.0 - '@aws-sdk/types': 3.577.0 - '@aws-sdk/util-endpoints': 3.577.0 - '@aws-sdk/util-user-agent-browser': 3.577.0 - '@aws-sdk/util-user-agent-node': 3.577.0 - '@smithy/config-resolver': 3.0.0 - '@smithy/core': 2.0.1 - '@smithy/fetch-http-handler': 3.0.1 - '@smithy/hash-node': 3.0.0 - '@smithy/invalid-dependency': 3.0.0 - '@smithy/middleware-content-length': 3.0.0 - '@smithy/middleware-endpoint': 3.0.0 - '@smithy/middleware-retry': 3.0.1 - '@smithy/middleware-serde': 3.0.0 - '@smithy/middleware-stack': 3.0.0 - '@smithy/node-config-provider': 3.0.0 - '@smithy/node-http-handler': 3.0.0 - '@smithy/protocol-http': 4.0.0 - '@smithy/smithy-client': 3.0.1 - '@smithy/types': 3.0.0 - '@smithy/url-parser': 3.0.0 - '@smithy/util-base64': 3.0.0 - '@smithy/util-body-length-browser': 3.0.0 - '@smithy/util-body-length-node': 3.0.0 - '@smithy/util-defaults-mode-browser': 3.0.1 - '@smithy/util-defaults-mode-node': 3.0.1 - '@smithy/util-endpoints': 2.0.0 - '@smithy/util-middleware': 3.0.0 - '@smithy/util-retry': 3.0.0 - '@smithy/util-utf8': 3.0.0 - tslib: 2.6.2 - transitivePeerDependencies: - - aws-crt - - '@aws-sdk/client-sts@3.577.0': - dependencies: - '@aws-crypto/sha256-browser': 3.0.0 - '@aws-crypto/sha256-js': 3.0.0 - '@aws-sdk/client-sso-oidc': 3.577.0(@aws-sdk/client-sts@3.577.0) - '@aws-sdk/core': 3.576.0 - '@aws-sdk/credential-provider-node': 3.577.0(@aws-sdk/client-sso-oidc@3.577.0(@aws-sdk/client-sts@3.577.0))(@aws-sdk/client-sts@3.577.0) - '@aws-sdk/middleware-host-header': 3.577.0 - '@aws-sdk/middleware-logger': 3.577.0 - '@aws-sdk/middleware-recursion-detection': 3.577.0 - '@aws-sdk/middleware-user-agent': 3.577.0 - '@aws-sdk/region-config-resolver': 3.577.0 - '@aws-sdk/types': 3.577.0 - '@aws-sdk/util-endpoints': 3.577.0 - '@aws-sdk/util-user-agent-browser': 3.577.0 - '@aws-sdk/util-user-agent-node': 3.577.0 - '@smithy/config-resolver': 3.0.0 - '@smithy/core': 2.0.1 - '@smithy/fetch-http-handler': 3.0.1 - '@smithy/hash-node': 3.0.0 - '@smithy/invalid-dependency': 3.0.0 - '@smithy/middleware-content-length': 3.0.0 - '@smithy/middleware-endpoint': 3.0.0 - '@smithy/middleware-retry': 3.0.1 - '@smithy/middleware-serde': 3.0.0 - '@smithy/middleware-stack': 3.0.0 - '@smithy/node-config-provider': 3.0.0 - '@smithy/node-http-handler': 3.0.0 - '@smithy/protocol-http': 4.0.0 - '@smithy/smithy-client': 3.0.1 - '@smithy/types': 3.0.0 - '@smithy/url-parser': 3.0.0 - '@smithy/util-base64': 3.0.0 - '@smithy/util-body-length-browser': 3.0.0 - '@smithy/util-body-length-node': 3.0.0 - '@smithy/util-defaults-mode-browser': 3.0.1 - '@smithy/util-defaults-mode-node': 3.0.1 - '@smithy/util-endpoints': 2.0.0 - '@smithy/util-middleware': 3.0.0 - '@smithy/util-retry': 3.0.0 - '@smithy/util-utf8': 3.0.0 - tslib: 2.6.2 - transitivePeerDependencies: - - aws-crt - - '@aws-sdk/core@3.576.0': - dependencies: - '@smithy/core': 2.0.1 - '@smithy/protocol-http': 4.0.0 - '@smithy/signature-v4': 3.0.0 - '@smithy/smithy-client': 3.0.1 - '@smithy/types': 3.0.0 - fast-xml-parser: 4.2.5 - tslib: 2.6.2 - - '@aws-sdk/credential-provider-env@3.577.0': - dependencies: - '@aws-sdk/types': 3.577.0 - '@smithy/property-provider': 3.0.0 - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@aws-sdk/credential-provider-http@3.577.0': - dependencies: - '@aws-sdk/types': 3.577.0 - '@smithy/fetch-http-handler': 3.0.1 - '@smithy/node-http-handler': 3.0.0 - '@smithy/property-provider': 3.0.0 - '@smithy/protocol-http': 4.0.0 - '@smithy/smithy-client': 3.0.1 - '@smithy/types': 3.0.0 - '@smithy/util-stream': 3.0.1 - tslib: 2.6.2 - - '@aws-sdk/credential-provider-ini@3.577.0(@aws-sdk/client-sso-oidc@3.577.0(@aws-sdk/client-sts@3.577.0))(@aws-sdk/client-sts@3.577.0)': - dependencies: - '@aws-sdk/client-sts': 3.577.0 - '@aws-sdk/credential-provider-env': 3.577.0 - '@aws-sdk/credential-provider-process': 3.577.0 - '@aws-sdk/credential-provider-sso': 3.577.0(@aws-sdk/client-sso-oidc@3.577.0(@aws-sdk/client-sts@3.577.0)) - '@aws-sdk/credential-provider-web-identity': 3.577.0(@aws-sdk/client-sts@3.577.0) - '@aws-sdk/types': 3.577.0 - '@smithy/credential-provider-imds': 3.0.0 - '@smithy/property-provider': 3.0.0 - '@smithy/shared-ini-file-loader': 3.0.0 - '@smithy/types': 3.0.0 - tslib: 2.6.2 - transitivePeerDependencies: - - '@aws-sdk/client-sso-oidc' - - aws-crt - - '@aws-sdk/credential-provider-node@3.577.0(@aws-sdk/client-sso-oidc@3.577.0(@aws-sdk/client-sts@3.577.0))(@aws-sdk/client-sts@3.577.0)': - dependencies: - '@aws-sdk/credential-provider-env': 3.577.0 - '@aws-sdk/credential-provider-http': 3.577.0 - '@aws-sdk/credential-provider-ini': 3.577.0(@aws-sdk/client-sso-oidc@3.577.0(@aws-sdk/client-sts@3.577.0))(@aws-sdk/client-sts@3.577.0) - '@aws-sdk/credential-provider-process': 3.577.0 - '@aws-sdk/credential-provider-sso': 3.577.0(@aws-sdk/client-sso-oidc@3.577.0(@aws-sdk/client-sts@3.577.0)) - '@aws-sdk/credential-provider-web-identity': 3.577.0(@aws-sdk/client-sts@3.577.0) - '@aws-sdk/types': 3.577.0 - '@smithy/credential-provider-imds': 3.0.0 - '@smithy/property-provider': 3.0.0 - '@smithy/shared-ini-file-loader': 3.0.0 - '@smithy/types': 3.0.0 - tslib: 2.6.2 - transitivePeerDependencies: - - '@aws-sdk/client-sso-oidc' - - '@aws-sdk/client-sts' - - aws-crt - - '@aws-sdk/credential-provider-process@3.577.0': - dependencies: - '@aws-sdk/types': 3.577.0 - '@smithy/property-provider': 3.0.0 - '@smithy/shared-ini-file-loader': 3.0.0 - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@aws-sdk/credential-provider-sso@3.577.0(@aws-sdk/client-sso-oidc@3.577.0(@aws-sdk/client-sts@3.577.0))': - dependencies: - '@aws-sdk/client-sso': 3.577.0 - '@aws-sdk/token-providers': 3.577.0(@aws-sdk/client-sso-oidc@3.577.0(@aws-sdk/client-sts@3.577.0)) - '@aws-sdk/types': 3.577.0 - '@smithy/property-provider': 3.0.0 - '@smithy/shared-ini-file-loader': 3.0.0 - '@smithy/types': 3.0.0 - tslib: 2.6.2 - transitivePeerDependencies: - - '@aws-sdk/client-sso-oidc' - - aws-crt - - '@aws-sdk/credential-provider-web-identity@3.577.0(@aws-sdk/client-sts@3.577.0)': - dependencies: - '@aws-sdk/client-sts': 3.577.0 - '@aws-sdk/types': 3.577.0 - '@smithy/property-provider': 3.0.0 - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@aws-sdk/middleware-host-header@3.577.0': - dependencies: - '@aws-sdk/types': 3.577.0 - '@smithy/protocol-http': 4.0.0 - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@aws-sdk/middleware-logger@3.577.0': - dependencies: - '@aws-sdk/types': 3.577.0 - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@aws-sdk/middleware-recursion-detection@3.577.0': - dependencies: - '@aws-sdk/types': 3.577.0 - '@smithy/protocol-http': 4.0.0 - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@aws-sdk/middleware-user-agent@3.577.0': - dependencies: - '@aws-sdk/types': 3.577.0 - '@aws-sdk/util-endpoints': 3.577.0 - '@smithy/protocol-http': 4.0.0 - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@aws-sdk/region-config-resolver@3.577.0': - dependencies: - '@aws-sdk/types': 3.577.0 - '@smithy/node-config-provider': 3.0.0 - '@smithy/types': 3.0.0 - '@smithy/util-config-provider': 3.0.0 - '@smithy/util-middleware': 3.0.0 - tslib: 2.6.2 - - '@aws-sdk/token-providers@3.577.0(@aws-sdk/client-sso-oidc@3.577.0(@aws-sdk/client-sts@3.577.0))': - dependencies: - '@aws-sdk/client-sso-oidc': 3.577.0(@aws-sdk/client-sts@3.577.0) - '@aws-sdk/types': 3.577.0 - '@smithy/property-provider': 3.0.0 - '@smithy/shared-ini-file-loader': 3.0.0 - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@aws-sdk/types@3.577.0': - dependencies: - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@aws-sdk/util-endpoints@3.577.0': - dependencies: - '@aws-sdk/types': 3.577.0 - '@smithy/types': 3.0.0 - '@smithy/util-endpoints': 2.0.0 - tslib: 2.6.2 - - '@aws-sdk/util-locate-window@3.568.0': - dependencies: - tslib: 2.6.2 - - '@aws-sdk/util-user-agent-browser@3.577.0': - dependencies: - '@aws-sdk/types': 3.577.0 - '@smithy/types': 3.0.0 - bowser: 2.11.0 - tslib: 2.6.2 - - '@aws-sdk/util-user-agent-node@3.577.0': - dependencies: - '@aws-sdk/types': 3.577.0 - '@smithy/node-config-provider': 3.0.0 - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@aws-sdk/util-utf8-browser@3.259.0': - dependencies: - tslib: 2.6.2 - - '@balena/dockerignore@1.0.2': {} - - '@cloudflare/kv-asset-handler@0.3.2': - dependencies: - mime: 3.0.0 - - '@cloudflare/workerd-darwin-64@1.20240512.0': - optional: true - - '@cloudflare/workerd-darwin-arm64@1.20240512.0': - optional: true - - '@cloudflare/workerd-linux-64@1.20240512.0': - optional: true - - '@cloudflare/workerd-linux-arm64@1.20240512.0': - optional: true - - '@cloudflare/workerd-windows-64@1.20240512.0': - optional: true - - '@cloudflare/workers-types@4.20240512.0': {} - - '@colors/colors@1.5.0': - optional: true - - '@cspotcode/source-map-support@0.8.1': - dependencies: - '@jridgewell/trace-mapping': 0.3.9 - - '@electric-sql/pglite@0.1.5': {} - - '@esbuild-kit/core-utils@3.3.2': - dependencies: - esbuild: 0.18.20 - source-map-support: 0.5.21 - - '@esbuild-kit/esm-loader@2.6.5': - dependencies: - '@esbuild-kit/core-utils': 3.3.2 - get-tsconfig: 4.7.5 - - '@esbuild-plugins/node-globals-polyfill@0.2.3(esbuild@0.17.19)': - dependencies: - esbuild: 0.17.19 - - '@esbuild-plugins/node-modules-polyfill@0.2.2(esbuild@0.17.19)': - dependencies: - esbuild: 0.17.19 - escape-string-regexp: 4.0.0 - rollup-plugin-node-polyfills: 0.2.1 - - '@esbuild/aix-ppc64@0.19.12': - optional: true - - '@esbuild/aix-ppc64@0.20.2': - optional: true - - '@esbuild/android-arm64@0.17.19': - optional: true - - '@esbuild/android-arm64@0.18.20': - optional: true - - '@esbuild/android-arm64@0.19.12': - optional: true - - '@esbuild/android-arm64@0.20.2': - optional: true - - '@esbuild/android-arm@0.17.19': - optional: true - - '@esbuild/android-arm@0.18.20': - optional: true - - '@esbuild/android-arm@0.19.12': - optional: true - - '@esbuild/android-arm@0.20.2': - optional: true - - '@esbuild/android-x64@0.17.19': - optional: true - - '@esbuild/android-x64@0.18.20': - optional: true - - '@esbuild/android-x64@0.19.12': - optional: true - - '@esbuild/android-x64@0.20.2': - optional: true - - '@esbuild/darwin-arm64@0.17.19': - optional: true - - '@esbuild/darwin-arm64@0.18.20': - optional: true - - '@esbuild/darwin-arm64@0.19.12': - optional: true - - '@esbuild/darwin-arm64@0.20.2': - optional: true - - '@esbuild/darwin-x64@0.17.19': - optional: true - - '@esbuild/darwin-x64@0.18.20': - optional: true - - '@esbuild/darwin-x64@0.19.12': - optional: true - - '@esbuild/darwin-x64@0.20.2': - optional: true - - '@esbuild/freebsd-arm64@0.17.19': - optional: true - - '@esbuild/freebsd-arm64@0.18.20': - optional: true - - '@esbuild/freebsd-arm64@0.19.12': - optional: true - - '@esbuild/freebsd-arm64@0.20.2': - optional: true - - '@esbuild/freebsd-x64@0.17.19': - optional: true - - '@esbuild/freebsd-x64@0.18.20': - optional: true - - '@esbuild/freebsd-x64@0.19.12': - optional: true - - '@esbuild/freebsd-x64@0.20.2': - optional: true - - '@esbuild/linux-arm64@0.17.19': - optional: true - - '@esbuild/linux-arm64@0.18.20': - optional: true - - '@esbuild/linux-arm64@0.19.12': - optional: true - - '@esbuild/linux-arm64@0.20.2': - optional: true - - '@esbuild/linux-arm@0.17.19': - optional: true - - '@esbuild/linux-arm@0.18.20': - optional: true - - '@esbuild/linux-arm@0.19.12': - optional: true - - '@esbuild/linux-arm@0.20.2': - optional: true - - '@esbuild/linux-ia32@0.17.19': - optional: true - - '@esbuild/linux-ia32@0.18.20': - optional: true - - '@esbuild/linux-ia32@0.19.12': - optional: true - - '@esbuild/linux-ia32@0.20.2': - optional: true - - '@esbuild/linux-loong64@0.14.54': - optional: true - - '@esbuild/linux-loong64@0.17.19': - optional: true - - '@esbuild/linux-loong64@0.18.20': - optional: true - - '@esbuild/linux-loong64@0.19.12': - optional: true - - '@esbuild/linux-loong64@0.20.2': - optional: true - - '@esbuild/linux-mips64el@0.17.19': - optional: true - - '@esbuild/linux-mips64el@0.18.20': - optional: true - - '@esbuild/linux-mips64el@0.19.12': - optional: true - - '@esbuild/linux-mips64el@0.20.2': - optional: true - - '@esbuild/linux-ppc64@0.17.19': - optional: true - - '@esbuild/linux-ppc64@0.18.20': - optional: true - - '@esbuild/linux-ppc64@0.19.12': - optional: true - - '@esbuild/linux-ppc64@0.20.2': - optional: true - - '@esbuild/linux-riscv64@0.17.19': - optional: true - - '@esbuild/linux-riscv64@0.18.20': - optional: true - - '@esbuild/linux-riscv64@0.19.12': - optional: true - - '@esbuild/linux-riscv64@0.20.2': - optional: true - - '@esbuild/linux-s390x@0.17.19': - optional: true - - '@esbuild/linux-s390x@0.18.20': - optional: true - - '@esbuild/linux-s390x@0.19.12': - optional: true - - '@esbuild/linux-s390x@0.20.2': - optional: true - - '@esbuild/linux-x64@0.17.19': - optional: true - - '@esbuild/linux-x64@0.18.20': - optional: true - - '@esbuild/linux-x64@0.19.12': - optional: true - - '@esbuild/linux-x64@0.20.2': - optional: true - - '@esbuild/netbsd-x64@0.17.19': - optional: true - - '@esbuild/netbsd-x64@0.18.20': - optional: true - - '@esbuild/netbsd-x64@0.19.12': - optional: true - - '@esbuild/netbsd-x64@0.20.2': - optional: true - - '@esbuild/openbsd-x64@0.17.19': - optional: true - - '@esbuild/openbsd-x64@0.18.20': - optional: true - - '@esbuild/openbsd-x64@0.19.12': - optional: true - - '@esbuild/openbsd-x64@0.20.2': - optional: true - - '@esbuild/sunos-x64@0.17.19': - optional: true - - '@esbuild/sunos-x64@0.18.20': - optional: true - - '@esbuild/sunos-x64@0.19.12': - optional: true - - '@esbuild/sunos-x64@0.20.2': - optional: true - - '@esbuild/win32-arm64@0.17.19': - optional: true - - '@esbuild/win32-arm64@0.18.20': - optional: true - - '@esbuild/win32-arm64@0.19.12': - optional: true - - '@esbuild/win32-arm64@0.20.2': - optional: true - - '@esbuild/win32-ia32@0.17.19': - optional: true - - '@esbuild/win32-ia32@0.18.20': - optional: true - - '@esbuild/win32-ia32@0.19.12': - optional: true - - '@esbuild/win32-ia32@0.20.2': - optional: true - - '@esbuild/win32-x64@0.17.19': - optional: true - - '@esbuild/win32-x64@0.18.20': - optional: true - - '@esbuild/win32-x64@0.19.12': - optional: true - - '@esbuild/win32-x64@0.20.2': - optional: true - - '@eslint-community/eslint-utils@4.4.0(eslint@8.57.0)': - dependencies: - eslint: 8.57.0 - eslint-visitor-keys: 3.4.3 - - '@eslint-community/regexpp@4.10.0': {} - - '@eslint/eslintrc@2.1.4': - dependencies: - ajv: 6.12.6 - debug: 4.3.4 - espree: 9.6.1 - globals: 13.24.0 - ignore: 5.3.1 - import-fresh: 3.3.0 - js-yaml: 4.1.0 - minimatch: 3.1.2 - strip-json-comments: 3.1.1 - transitivePeerDependencies: - - supports-color - - '@eslint/js@8.57.0': {} - - '@ewoudenberg/difflib@0.1.0': - dependencies: - heap: 0.2.7 - - '@fastify/busboy@2.1.1': {} - - '@hono/node-server@1.11.1': {} - - '@hono/zod-validator@0.2.1(hono@4.3.9)(zod@3.23.8)': - dependencies: - hono: 4.3.9 - zod: 3.23.8 - - '@humanwhocodes/config-array@0.11.14': - dependencies: - '@humanwhocodes/object-schema': 2.0.3 - debug: 4.3.4 - minimatch: 3.1.2 - transitivePeerDependencies: - - supports-color - - '@humanwhocodes/module-importer@1.0.1': {} - - '@humanwhocodes/object-schema@2.0.3': {} - - '@isaacs/cliui@8.0.2': - dependencies: - string-width: 5.1.2 - string-width-cjs: string-width@4.2.3 - strip-ansi: 7.1.0 - strip-ansi-cjs: strip-ansi@6.0.1 - wrap-ansi: 8.1.0 - wrap-ansi-cjs: wrap-ansi@7.0.0 - - '@jest/schemas@29.6.3': - dependencies: - '@sinclair/typebox': 0.27.8 - - '@jridgewell/gen-mapping@0.3.5': - dependencies: - '@jridgewell/set-array': 1.2.1 - '@jridgewell/sourcemap-codec': 1.4.15 - '@jridgewell/trace-mapping': 0.3.25 - - '@jridgewell/resolve-uri@3.1.2': {} - - '@jridgewell/set-array@1.2.1': {} - - '@jridgewell/sourcemap-codec@1.4.15': {} - - '@jridgewell/trace-mapping@0.3.25': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.4.15 - - '@jridgewell/trace-mapping@0.3.9': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.4.15 - - '@libsql/client@0.4.3(bufferutil@4.0.8)(utf-8-validate@6.0.3)': - dependencies: - '@libsql/core': 0.4.3 - '@libsql/hrana-client': 0.5.6(bufferutil@4.0.8)(utf-8-validate@6.0.3) - js-base64: 3.7.7 - optionalDependencies: - libsql: 0.2.0 - transitivePeerDependencies: - - bufferutil - - encoding - - utf-8-validate - - '@libsql/core@0.4.3': - dependencies: - js-base64: 3.7.7 - - '@libsql/darwin-arm64@0.2.0': - optional: true - - '@libsql/darwin-x64@0.2.0': - optional: true - - '@libsql/hrana-client@0.5.6(bufferutil@4.0.8)(utf-8-validate@6.0.3)': - dependencies: - '@libsql/isomorphic-fetch': 0.1.12 - '@libsql/isomorphic-ws': 0.1.5(bufferutil@4.0.8)(utf-8-validate@6.0.3) - js-base64: 3.7.7 - node-fetch: 3.3.2 - transitivePeerDependencies: - - bufferutil - - encoding - - utf-8-validate - - '@libsql/isomorphic-fetch@0.1.12': - dependencies: - '@types/node-fetch': 2.6.11 - node-fetch: 2.7.0 - transitivePeerDependencies: - - encoding - - '@libsql/isomorphic-ws@0.1.5(bufferutil@4.0.8)(utf-8-validate@6.0.3)': - dependencies: - '@types/ws': 8.5.10 - ws: 8.17.0(bufferutil@4.0.8)(utf-8-validate@6.0.3) - transitivePeerDependencies: - - bufferutil - - utf-8-validate - - '@libsql/linux-arm64-gnu@0.2.0': - optional: true - - '@libsql/linux-arm64-musl@0.2.0': - optional: true - - '@libsql/linux-x64-gnu@0.2.0': - optional: true - - '@libsql/linux-x64-musl@0.2.0': - optional: true - - '@libsql/win32-x64-msvc@0.2.0': - optional: true - - '@neon-rs/load@0.0.4': - optional: true - - '@neondatabase/serverless@0.7.2': - dependencies: - '@types/pg': 8.6.6 - - '@neondatabase/serverless@0.9.3': - dependencies: - '@types/pg': 8.11.6 - - '@nodelib/fs.scandir@2.1.5': - dependencies: - '@nodelib/fs.stat': 2.0.5 - run-parallel: 1.2.0 - - '@nodelib/fs.stat@2.0.5': {} - - '@nodelib/fs.walk@1.2.8': - dependencies: - '@nodelib/fs.scandir': 2.1.5 - fastq: 1.17.1 - - '@originjs/vite-plugin-commonjs@1.0.3': - dependencies: - esbuild: 0.14.54 - - '@pkgjs/parseargs@0.11.0': - optional: true - - '@pkgr/core@0.1.1': {} - - '@planetscale/database@1.18.0': {} - - '@rollup/rollup-android-arm-eabi@4.17.2': - optional: true - - '@rollup/rollup-android-arm64@4.17.2': - optional: true - - '@rollup/rollup-darwin-arm64@4.17.2': - optional: true - - '@rollup/rollup-darwin-x64@4.17.2': - optional: true - - '@rollup/rollup-linux-arm-gnueabihf@4.17.2': - optional: true - - '@rollup/rollup-linux-arm-musleabihf@4.17.2': - optional: true - - '@rollup/rollup-linux-arm64-gnu@4.17.2': - optional: true - - '@rollup/rollup-linux-arm64-musl@4.17.2': - optional: true - - '@rollup/rollup-linux-powerpc64le-gnu@4.17.2': - optional: true - - '@rollup/rollup-linux-riscv64-gnu@4.17.2': - optional: true - - '@rollup/rollup-linux-s390x-gnu@4.17.2': - optional: true - - '@rollup/rollup-linux-x64-gnu@4.17.2': - optional: true - - '@rollup/rollup-linux-x64-musl@4.17.2': - optional: true - - '@rollup/rollup-win32-arm64-msvc@4.17.2': - optional: true - - '@rollup/rollup-win32-ia32-msvc@4.17.2': - optional: true - - '@rollup/rollup-win32-x64-msvc@4.17.2': - optional: true - - '@sinclair/typebox@0.27.8': {} - - '@sindresorhus/is@4.6.0': {} - - '@smithy/abort-controller@3.0.0': - dependencies: - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@smithy/config-resolver@3.0.0': - dependencies: - '@smithy/node-config-provider': 3.0.0 - '@smithy/types': 3.0.0 - '@smithy/util-config-provider': 3.0.0 - '@smithy/util-middleware': 3.0.0 - tslib: 2.6.2 - - '@smithy/core@2.0.1': - dependencies: - '@smithy/middleware-endpoint': 3.0.0 - '@smithy/middleware-retry': 3.0.1 - '@smithy/middleware-serde': 3.0.0 - '@smithy/protocol-http': 4.0.0 - '@smithy/smithy-client': 3.0.1 - '@smithy/types': 3.0.0 - '@smithy/util-middleware': 3.0.0 - tslib: 2.6.2 - - '@smithy/credential-provider-imds@3.0.0': - dependencies: - '@smithy/node-config-provider': 3.0.0 - '@smithy/property-provider': 3.0.0 - '@smithy/types': 3.0.0 - '@smithy/url-parser': 3.0.0 - tslib: 2.6.2 - - '@smithy/fetch-http-handler@3.0.1': - dependencies: - '@smithy/protocol-http': 4.0.0 - '@smithy/querystring-builder': 3.0.0 - '@smithy/types': 3.0.0 - '@smithy/util-base64': 3.0.0 - tslib: 2.6.2 - - '@smithy/hash-node@3.0.0': - dependencies: - '@smithy/types': 3.0.0 - '@smithy/util-buffer-from': 3.0.0 - '@smithy/util-utf8': 3.0.0 - tslib: 2.6.2 - - '@smithy/invalid-dependency@3.0.0': - dependencies: - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@smithy/is-array-buffer@3.0.0': - dependencies: - tslib: 2.6.2 - - '@smithy/middleware-content-length@3.0.0': - dependencies: - '@smithy/protocol-http': 4.0.0 - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@smithy/middleware-endpoint@3.0.0': - dependencies: - '@smithy/middleware-serde': 3.0.0 - '@smithy/node-config-provider': 3.0.0 - '@smithy/shared-ini-file-loader': 3.0.0 - '@smithy/types': 3.0.0 - '@smithy/url-parser': 3.0.0 - '@smithy/util-middleware': 3.0.0 - tslib: 2.6.2 - - '@smithy/middleware-retry@3.0.1': - dependencies: - '@smithy/node-config-provider': 3.0.0 - '@smithy/protocol-http': 4.0.0 - '@smithy/service-error-classification': 3.0.0 - '@smithy/smithy-client': 3.0.1 - '@smithy/types': 3.0.0 - '@smithy/util-middleware': 3.0.0 - '@smithy/util-retry': 3.0.0 - tslib: 2.6.2 - uuid: 9.0.1 - - '@smithy/middleware-serde@3.0.0': - dependencies: - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@smithy/middleware-stack@3.0.0': - dependencies: - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@smithy/node-config-provider@3.0.0': - dependencies: - '@smithy/property-provider': 3.0.0 - '@smithy/shared-ini-file-loader': 3.0.0 - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@smithy/node-http-handler@3.0.0': - dependencies: - '@smithy/abort-controller': 3.0.0 - '@smithy/protocol-http': 4.0.0 - '@smithy/querystring-builder': 3.0.0 - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@smithy/property-provider@3.0.0': - dependencies: - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@smithy/protocol-http@4.0.0': - dependencies: - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@smithy/querystring-builder@3.0.0': - dependencies: - '@smithy/types': 3.0.0 - '@smithy/util-uri-escape': 3.0.0 - tslib: 2.6.2 - - '@smithy/querystring-parser@3.0.0': - dependencies: - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@smithy/service-error-classification@3.0.0': - dependencies: - '@smithy/types': 3.0.0 - - '@smithy/shared-ini-file-loader@3.0.0': - dependencies: - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@smithy/signature-v4@3.0.0': - dependencies: - '@smithy/is-array-buffer': 3.0.0 - '@smithy/types': 3.0.0 - '@smithy/util-hex-encoding': 3.0.0 - '@smithy/util-middleware': 3.0.0 - '@smithy/util-uri-escape': 3.0.0 - '@smithy/util-utf8': 3.0.0 - tslib: 2.6.2 - - '@smithy/smithy-client@3.0.1': - dependencies: - '@smithy/middleware-endpoint': 3.0.0 - '@smithy/middleware-stack': 3.0.0 - '@smithy/protocol-http': 4.0.0 - '@smithy/types': 3.0.0 - '@smithy/util-stream': 3.0.1 - tslib: 2.6.2 - - '@smithy/types@3.0.0': - dependencies: - tslib: 2.6.2 - - '@smithy/url-parser@3.0.0': - dependencies: - '@smithy/querystring-parser': 3.0.0 - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@smithy/util-base64@3.0.0': - dependencies: - '@smithy/util-buffer-from': 3.0.0 - '@smithy/util-utf8': 3.0.0 - tslib: 2.6.2 - - '@smithy/util-body-length-browser@3.0.0': - dependencies: - tslib: 2.6.2 - - '@smithy/util-body-length-node@3.0.0': - dependencies: - tslib: 2.6.2 - - '@smithy/util-buffer-from@3.0.0': - dependencies: - '@smithy/is-array-buffer': 3.0.0 - tslib: 2.6.2 - - '@smithy/util-config-provider@3.0.0': - dependencies: - tslib: 2.6.2 - - '@smithy/util-defaults-mode-browser@3.0.1': - dependencies: - '@smithy/property-provider': 3.0.0 - '@smithy/smithy-client': 3.0.1 - '@smithy/types': 3.0.0 - bowser: 2.11.0 - tslib: 2.6.2 - - '@smithy/util-defaults-mode-node@3.0.1': - dependencies: - '@smithy/config-resolver': 3.0.0 - '@smithy/credential-provider-imds': 3.0.0 - '@smithy/node-config-provider': 3.0.0 - '@smithy/property-provider': 3.0.0 - '@smithy/smithy-client': 3.0.1 - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@smithy/util-endpoints@2.0.0': - dependencies: - '@smithy/node-config-provider': 3.0.0 - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@smithy/util-hex-encoding@3.0.0': - dependencies: - tslib: 2.6.2 - - '@smithy/util-middleware@3.0.0': - dependencies: - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@smithy/util-retry@3.0.0': - dependencies: - '@smithy/service-error-classification': 3.0.0 - '@smithy/types': 3.0.0 - tslib: 2.6.2 - - '@smithy/util-stream@3.0.1': - dependencies: - '@smithy/fetch-http-handler': 3.0.1 - '@smithy/node-http-handler': 3.0.0 - '@smithy/types': 3.0.0 - '@smithy/util-base64': 3.0.0 - '@smithy/util-buffer-from': 3.0.0 - '@smithy/util-hex-encoding': 3.0.0 - '@smithy/util-utf8': 3.0.0 - tslib: 2.6.2 - - '@smithy/util-uri-escape@3.0.0': - dependencies: - tslib: 2.6.2 - - '@smithy/util-utf8@3.0.0': - dependencies: - '@smithy/util-buffer-from': 3.0.0 - tslib: 2.6.2 - - '@types/better-sqlite3@7.6.10': - dependencies: - '@types/node': 18.19.33 - - '@types/docker-modem@3.0.6': - dependencies: - '@types/node': 18.19.33 - '@types/ssh2': 1.15.0 - - '@types/dockerode@3.3.29': - dependencies: - '@types/docker-modem': 3.0.6 - '@types/node': 18.19.33 - '@types/ssh2': 1.15.0 - - '@types/estree@1.0.5': {} - - '@types/fs-extra@11.0.4': - dependencies: - '@types/jsonfile': 6.1.4 - '@types/node': 18.19.33 - - '@types/glob@8.1.0': - dependencies: - '@types/minimatch': 5.1.2 - '@types/node': 18.19.33 - - '@types/json-diff@1.0.3': {} - - '@types/jsonfile@6.1.4': - dependencies: - '@types/node': 18.19.33 - - '@types/minimatch@5.1.2': {} - - '@types/minimist@1.2.5': {} - - '@types/node-fetch@2.6.11': - dependencies: - '@types/node': 18.19.33 - form-data: 4.0.0 - - '@types/node-forge@1.3.11': - dependencies: - '@types/node': 18.19.33 - - '@types/node@18.19.33': - dependencies: - undici-types: 5.26.5 - - '@types/pg@8.11.6': - dependencies: - '@types/node': 18.19.33 - pg-protocol: 1.6.1 - pg-types: 4.0.2 - - '@types/pg@8.6.6': - dependencies: - '@types/node': 18.19.33 - pg-protocol: 1.6.1 - pg-types: 2.2.0 - - '@types/pluralize@0.0.33': {} - - '@types/ps-tree@1.1.6': {} - - '@types/semver@7.5.8': {} - - '@types/ssh2@1.15.0': - dependencies: - '@types/node': 18.19.33 - - '@types/uuid@9.0.8': {} - - '@types/which@3.0.3': {} - - '@types/ws@8.5.10': - dependencies: - '@types/node': 18.19.33 - - '@typescript-eslint/eslint-plugin@7.10.0(@typescript-eslint/parser@7.10.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5)': - dependencies: - '@eslint-community/regexpp': 4.10.0 - '@typescript-eslint/parser': 7.10.0(eslint@8.57.0)(typescript@5.4.5) - '@typescript-eslint/scope-manager': 7.10.0 - '@typescript-eslint/type-utils': 7.10.0(eslint@8.57.0)(typescript@5.4.5) - '@typescript-eslint/utils': 7.10.0(eslint@8.57.0)(typescript@5.4.5) - '@typescript-eslint/visitor-keys': 7.10.0 - eslint: 8.57.0 - graphemer: 1.4.0 - ignore: 5.3.1 - natural-compare: 1.4.0 - ts-api-utils: 1.3.0(typescript@5.4.5) - optionalDependencies: - typescript: 5.4.5 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/parser@7.10.0(eslint@8.57.0)(typescript@5.4.5)': - dependencies: - '@typescript-eslint/scope-manager': 7.10.0 - '@typescript-eslint/types': 7.10.0 - '@typescript-eslint/typescript-estree': 7.10.0(typescript@5.4.5) - '@typescript-eslint/visitor-keys': 7.10.0 - debug: 4.3.4 - eslint: 8.57.0 - optionalDependencies: - typescript: 5.4.5 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/scope-manager@7.10.0': - dependencies: - '@typescript-eslint/types': 7.10.0 - '@typescript-eslint/visitor-keys': 7.10.0 - - '@typescript-eslint/type-utils@7.10.0(eslint@8.57.0)(typescript@5.4.5)': - dependencies: - '@typescript-eslint/typescript-estree': 7.10.0(typescript@5.4.5) - '@typescript-eslint/utils': 7.10.0(eslint@8.57.0)(typescript@5.4.5) - debug: 4.3.4 - eslint: 8.57.0 - ts-api-utils: 1.3.0(typescript@5.4.5) - optionalDependencies: - typescript: 5.4.5 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/types@7.10.0': {} - - '@typescript-eslint/typescript-estree@7.10.0(typescript@5.4.5)': - dependencies: - '@typescript-eslint/types': 7.10.0 - '@typescript-eslint/visitor-keys': 7.10.0 - debug: 4.3.4 - globby: 11.1.0 - is-glob: 4.0.3 - minimatch: 9.0.4 - semver: 7.6.2 - ts-api-utils: 1.3.0(typescript@5.4.5) - optionalDependencies: - typescript: 5.4.5 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/utils@7.10.0(eslint@8.57.0)(typescript@5.4.5)': - dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) - '@typescript-eslint/scope-manager': 7.10.0 - '@typescript-eslint/types': 7.10.0 - '@typescript-eslint/typescript-estree': 7.10.0(typescript@5.4.5) - eslint: 8.57.0 - transitivePeerDependencies: - - supports-color - - typescript - - '@typescript-eslint/visitor-keys@7.10.0': - dependencies: - '@typescript-eslint/types': 7.10.0 - eslint-visitor-keys: 3.4.3 - - '@ungap/structured-clone@1.2.0': {} - - '@vercel/postgres@0.8.0': - dependencies: - '@neondatabase/serverless': 0.7.2 - bufferutil: 4.0.8 - utf-8-validate: 6.0.3 - ws: 8.14.2(bufferutil@4.0.8)(utf-8-validate@6.0.3) - - '@vitest/expect@1.6.0': - dependencies: - '@vitest/spy': 1.6.0 - '@vitest/utils': 1.6.0 - chai: 4.4.1 - - '@vitest/runner@1.6.0': - dependencies: - '@vitest/utils': 1.6.0 - p-limit: 5.0.0 - pathe: 1.1.2 - - '@vitest/snapshot@1.6.0': - dependencies: - magic-string: 0.30.10 - pathe: 1.1.2 - pretty-format: 29.7.0 - - '@vitest/spy@1.6.0': - dependencies: - tinyspy: 2.2.1 - - '@vitest/utils@1.6.0': - dependencies: - diff-sequences: 29.6.3 - estree-walker: 3.0.3 - loupe: 2.3.7 - pretty-format: 29.7.0 - - acorn-jsx@5.3.2(acorn@8.11.3): - dependencies: - acorn: 8.11.3 - - acorn-walk@8.3.2: {} - - acorn@8.11.3: {} - - aggregate-error@4.0.1: - dependencies: - clean-stack: 4.2.0 - indent-string: 5.0.0 - - ajv@6.12.6: - dependencies: - fast-deep-equal: 3.1.3 - fast-json-stable-stringify: 2.1.0 - json-schema-traverse: 0.4.1 - uri-js: 4.4.1 - - ansi-escapes@6.2.1: {} - - ansi-regex@5.0.1: {} - - ansi-regex@6.0.1: {} - - ansi-styles@4.3.0: - dependencies: - color-convert: 2.0.1 - - ansi-styles@5.2.0: {} - - ansi-styles@6.2.1: {} - - ansicolors@0.3.2: {} - - any-promise@1.3.0: {} - - anymatch@3.1.3: - dependencies: - normalize-path: 3.0.0 - picomatch: 2.3.1 - - argparse@1.0.10: - dependencies: - sprintf-js: 1.0.3 - - argparse@2.0.1: {} - - array-find-index@1.0.2: {} - - array-union@2.1.0: {} - - arrgv@1.0.2: {} - - arrify@3.0.0: {} - - as-table@1.0.55: - dependencies: - printable-characters: 1.0.42 - - asn1@0.2.6: - dependencies: - safer-buffer: 2.1.2 - - assertion-error@1.1.0: {} - - asynckit@0.4.0: {} - - ava@5.3.1: - dependencies: - acorn: 8.11.3 - acorn-walk: 8.3.2 - ansi-styles: 6.2.1 - arrgv: 1.0.2 - arrify: 3.0.0 - callsites: 4.1.0 - cbor: 8.1.0 - chalk: 5.3.0 - chokidar: 3.6.0 - chunkd: 2.0.1 - ci-info: 3.9.0 - ci-parallel-vars: 1.0.1 - clean-yaml-object: 0.1.0 - cli-truncate: 3.1.0 - code-excerpt: 4.0.0 - common-path-prefix: 3.0.0 - concordance: 5.0.4 - currently-unhandled: 0.4.1 - debug: 4.3.4 - emittery: 1.0.3 - figures: 5.0.0 - globby: 13.2.2 - ignore-by-default: 2.1.0 - indent-string: 5.0.0 - is-error: 2.2.2 - is-plain-object: 5.0.0 - is-promise: 4.0.0 - matcher: 5.0.0 - mem: 9.0.2 - ms: 2.1.3 - p-event: 5.0.1 - p-map: 5.5.0 - picomatch: 2.3.1 - pkg-conf: 4.0.0 - plur: 5.1.0 - pretty-ms: 8.0.0 - resolve-cwd: 3.0.0 - stack-utils: 2.0.6 - strip-ansi: 7.1.0 - supertap: 3.0.1 - temp-dir: 3.0.0 - write-file-atomic: 5.0.1 - yargs: 17.7.2 - transitivePeerDependencies: - - supports-color - - balanced-match@1.0.2: {} - - base64-js@1.5.1: {} - - bcrypt-pbkdf@1.0.2: - dependencies: - tweetnacl: 0.14.5 - - better-sqlite3@9.6.0: - dependencies: - bindings: 1.5.0 - prebuild-install: 7.1.2 - - binary-extensions@2.3.0: {} - - bindings@1.5.0: - dependencies: - file-uri-to-path: 1.0.0 - - bl@4.1.0: - dependencies: - buffer: 5.7.1 - inherits: 2.0.4 - readable-stream: 3.6.2 - - blake3-wasm@2.1.5: {} - - blueimp-md5@2.19.0: {} - - bowser@2.11.0: {} - - brace-expansion@1.1.11: - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - - brace-expansion@2.0.1: - dependencies: - balanced-match: 1.0.2 - - braces@3.0.2: - dependencies: - fill-range: 7.1.1 - - buffer-from@1.1.2: {} - - buffer@5.7.1: - dependencies: - base64-js: 1.5.1 - ieee754: 1.2.1 - - bufferutil@4.0.8: - dependencies: - node-gyp-build: 4.8.1 - - buildcheck@0.0.6: - optional: true - - bundle-require@4.1.0(esbuild@0.19.12): - dependencies: - esbuild: 0.19.12 - load-tsconfig: 0.2.5 - - cac@6.7.14: {} - - callsites@3.1.0: {} - - callsites@4.1.0: {} - - camelcase@7.0.1: {} - - capnp-ts@0.7.0: - dependencies: - debug: 4.3.4 - tslib: 2.6.2 - transitivePeerDependencies: - - supports-color - - cardinal@2.1.1: - dependencies: - ansicolors: 0.3.2 - redeyed: 2.1.1 - - cbor@8.1.0: - dependencies: - nofilter: 3.1.0 - - chai@4.4.1: - dependencies: - assertion-error: 1.1.0 - check-error: 1.0.3 - deep-eql: 4.1.3 - get-func-name: 2.0.2 - loupe: 2.3.7 - pathval: 1.1.1 - type-detect: 4.0.8 - - chalk@4.1.2: - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 - - chalk@5.3.0: {} - - char-regex@1.0.2: {} - - check-error@1.0.3: - dependencies: - get-func-name: 2.0.2 - - chokidar@3.6.0: - dependencies: - anymatch: 3.1.3 - braces: 3.0.2 - glob-parent: 5.1.2 - is-binary-path: 2.1.0 - is-glob: 4.0.3 - normalize-path: 3.0.0 - readdirp: 3.6.0 - optionalDependencies: - fsevents: 2.3.3 - - chownr@1.1.4: {} - - chunkd@2.0.1: {} - - ci-info@3.9.0: {} - - ci-parallel-vars@1.0.1: {} - - clean-stack@4.2.0: - dependencies: - escape-string-regexp: 5.0.0 - - clean-yaml-object@0.1.0: {} - - cli-color@2.0.4: - dependencies: - d: 1.0.2 - es5-ext: 0.10.64 - es6-iterator: 2.0.3 - memoizee: 0.4.15 - timers-ext: 0.1.7 - - cli-table3@0.6.5: - dependencies: - string-width: 4.2.3 - optionalDependencies: - '@colors/colors': 1.5.0 - - cli-truncate@3.1.0: - dependencies: - slice-ansi: 5.0.0 - string-width: 5.1.2 - - cliui@8.0.1: - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 7.0.0 - - code-excerpt@4.0.0: - dependencies: - convert-to-spaces: 2.0.1 - - color-convert@2.0.1: - dependencies: - color-name: 1.1.4 - - color-name@1.1.4: {} - - colors@1.4.0: {} - - combined-stream@1.0.8: - dependencies: - delayed-stream: 1.0.0 - - commander@10.0.1: {} - - commander@12.1.0: {} - - commander@4.1.1: {} - - commander@9.5.0: {} - - common-path-prefix@3.0.0: {} - - concat-map@0.0.1: {} - - concordance@5.0.4: - dependencies: - date-time: 3.1.0 - esutils: 2.0.3 - fast-diff: 1.3.0 - js-string-escape: 1.0.1 - lodash: 4.17.21 - md5-hex: 3.0.1 - semver: 7.6.2 - well-known-symbols: 2.0.0 - - confbox@0.1.7: {} - - convert-to-spaces@2.0.1: {} - - cookie@0.5.0: {} - - copy-anything@3.0.5: - dependencies: - is-what: 4.1.16 - - cpu-features@0.0.10: - dependencies: - buildcheck: 0.0.6 - nan: 2.19.0 - optional: true - - cross-spawn@7.0.3: - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - - currently-unhandled@0.4.1: - dependencies: - array-find-index: 1.0.2 - - d@1.0.2: - dependencies: - es5-ext: 0.10.64 - type: 2.7.2 - - data-uri-to-buffer@2.0.2: {} - - data-uri-to-buffer@4.0.1: {} - - date-time@3.1.0: - dependencies: - time-zone: 1.0.0 - - debug@4.3.4: - dependencies: - ms: 2.1.2 - - decompress-response@6.0.0: - dependencies: - mimic-response: 3.1.0 - - deep-eql@4.1.3: - dependencies: - type-detect: 4.0.8 - - deep-extend@0.6.0: {} - - deep-is@0.1.4: {} - - delayed-stream@1.0.0: {} - - denque@2.1.0: {} - - detect-libc@2.0.2: - optional: true - - detect-libc@2.0.3: {} - - diff-sequences@29.6.3: {} - - difflib@0.2.4(patch_hash=jq4t3ysdpnbunjeje4v7nrqn2q): - dependencies: - heap: 0.2.7 - - dir-glob@3.0.1: - dependencies: - path-type: 4.0.0 - - docker-modem@3.0.8: - dependencies: - debug: 4.3.4 - readable-stream: 3.6.2 - split-ca: 1.0.1 - ssh2: 1.15.0 - transitivePeerDependencies: - - supports-color - - dockerode@3.3.5: - dependencies: - '@balena/dockerignore': 1.0.2 - docker-modem: 3.0.8 - tar-fs: 2.0.1 - transitivePeerDependencies: - - supports-color - - doctrine@3.0.0: - dependencies: - esutils: 2.0.3 - - dotenv@16.4.5: {} - - dreamopt@0.8.0: - dependencies: - wordwrap: 1.0.0 - - drizzle-kit@0.21.2: - dependencies: - '@esbuild-kit/esm-loader': 2.6.5 - commander: 9.5.0 - env-paths: 3.0.0 - esbuild: 0.19.12 - esbuild-register: 3.5.0(esbuild@0.19.12) - glob: 8.1.0 - hanji: 0.0.5 - json-diff: 0.9.0 - zod: 3.23.8 - transitivePeerDependencies: - - supports-color - - drizzle-orm@0.32.0-85c8008(@aws-sdk/client-rds-data@3.577.0)(@cloudflare/workers-types@4.20240512.0)(@electric-sql/pglite@0.1.5)(@libsql/client@0.4.3(bufferutil@4.0.8)(utf-8-validate@6.0.3))(@neondatabase/serverless@0.9.3)(@planetscale/database@1.18.0)(@types/better-sqlite3@7.6.10)(@types/pg@8.11.6)(@vercel/postgres@0.8.0)(better-sqlite3@9.6.0)(mysql2@2.3.3)(pg@8.11.5)(postgres@3.4.4): - optionalDependencies: - '@aws-sdk/client-rds-data': 3.577.0 - '@cloudflare/workers-types': 4.20240512.0 - '@electric-sql/pglite': 0.1.5 - '@libsql/client': 0.4.3(bufferutil@4.0.8)(utf-8-validate@6.0.3) - '@neondatabase/serverless': 0.9.3 - '@planetscale/database': 1.18.0 - '@types/better-sqlite3': 7.6.10 - '@types/pg': 8.11.6 - '@vercel/postgres': 0.8.0 - better-sqlite3: 9.6.0 - mysql2: 2.3.3 - pg: 8.11.5 - postgres: 3.4.4 - - duplexer@0.1.2: {} - - eastasianwidth@0.2.0: {} - - emittery@1.0.3: {} - - emoji-regex@8.0.0: {} - - emoji-regex@9.2.2: {} - - emojilib@2.4.0: {} - - end-of-stream@1.4.4: - dependencies: - once: 1.4.0 - - env-paths@3.0.0: {} - - es5-ext@0.10.64: - dependencies: - es6-iterator: 2.0.3 - es6-symbol: 3.1.4 - esniff: 2.0.1 - next-tick: 1.1.0 - - es6-iterator@2.0.3: - dependencies: - d: 1.0.2 - es5-ext: 0.10.64 - es6-symbol: 3.1.4 - - es6-symbol@3.1.4: - dependencies: - d: 1.0.2 - ext: 1.7.0 - - es6-weak-map@2.0.3: - dependencies: - d: 1.0.2 - es5-ext: 0.10.64 - es6-iterator: 2.0.3 - es6-symbol: 3.1.4 - - esbuild-android-64@0.14.54: - optional: true - - esbuild-android-arm64@0.14.54: - optional: true - - esbuild-darwin-64@0.14.54: - optional: true - - esbuild-darwin-arm64@0.14.54: - optional: true - - esbuild-freebsd-64@0.14.54: - optional: true - - esbuild-freebsd-arm64@0.14.54: - optional: true - - esbuild-linux-32@0.14.54: - optional: true - - esbuild-linux-64@0.14.54: - optional: true - - esbuild-linux-arm64@0.14.54: - optional: true - - esbuild-linux-arm@0.14.54: - optional: true - - esbuild-linux-mips64le@0.14.54: - optional: true - - esbuild-linux-ppc64le@0.14.54: - optional: true - - esbuild-linux-riscv64@0.14.54: - optional: true - - esbuild-linux-s390x@0.14.54: - optional: true - - esbuild-netbsd-64@0.14.54: - optional: true - - esbuild-node-externals@1.13.1(esbuild@0.19.12): - dependencies: - esbuild: 0.19.12 - find-up: 5.0.0 - tslib: 2.6.2 - - esbuild-openbsd-64@0.14.54: - optional: true - - esbuild-register@3.5.0(esbuild@0.19.12): - dependencies: - debug: 4.3.4 - esbuild: 0.19.12 - transitivePeerDependencies: - - supports-color - - esbuild-sunos-64@0.14.54: - optional: true - - esbuild-windows-32@0.14.54: - optional: true - - esbuild-windows-64@0.14.54: - optional: true - - esbuild-windows-arm64@0.14.54: - optional: true - - esbuild@0.14.54: - optionalDependencies: - '@esbuild/linux-loong64': 0.14.54 - esbuild-android-64: 0.14.54 - esbuild-android-arm64: 0.14.54 - esbuild-darwin-64: 0.14.54 - esbuild-darwin-arm64: 0.14.54 - esbuild-freebsd-64: 0.14.54 - esbuild-freebsd-arm64: 0.14.54 - esbuild-linux-32: 0.14.54 - esbuild-linux-64: 0.14.54 - esbuild-linux-arm: 0.14.54 - esbuild-linux-arm64: 0.14.54 - esbuild-linux-mips64le: 0.14.54 - esbuild-linux-ppc64le: 0.14.54 - esbuild-linux-riscv64: 0.14.54 - esbuild-linux-s390x: 0.14.54 - esbuild-netbsd-64: 0.14.54 - esbuild-openbsd-64: 0.14.54 - esbuild-sunos-64: 0.14.54 - esbuild-windows-32: 0.14.54 - esbuild-windows-64: 0.14.54 - esbuild-windows-arm64: 0.14.54 - - esbuild@0.17.19: - optionalDependencies: - '@esbuild/android-arm': 0.17.19 - '@esbuild/android-arm64': 0.17.19 - '@esbuild/android-x64': 0.17.19 - '@esbuild/darwin-arm64': 0.17.19 - '@esbuild/darwin-x64': 0.17.19 - '@esbuild/freebsd-arm64': 0.17.19 - '@esbuild/freebsd-x64': 0.17.19 - '@esbuild/linux-arm': 0.17.19 - '@esbuild/linux-arm64': 0.17.19 - '@esbuild/linux-ia32': 0.17.19 - '@esbuild/linux-loong64': 0.17.19 - '@esbuild/linux-mips64el': 0.17.19 - '@esbuild/linux-ppc64': 0.17.19 - '@esbuild/linux-riscv64': 0.17.19 - '@esbuild/linux-s390x': 0.17.19 - '@esbuild/linux-x64': 0.17.19 - '@esbuild/netbsd-x64': 0.17.19 - '@esbuild/openbsd-x64': 0.17.19 - '@esbuild/sunos-x64': 0.17.19 - '@esbuild/win32-arm64': 0.17.19 - '@esbuild/win32-ia32': 0.17.19 - '@esbuild/win32-x64': 0.17.19 - - esbuild@0.18.20: - optionalDependencies: - '@esbuild/android-arm': 0.18.20 - '@esbuild/android-arm64': 0.18.20 - '@esbuild/android-x64': 0.18.20 - '@esbuild/darwin-arm64': 0.18.20 - '@esbuild/darwin-x64': 0.18.20 - '@esbuild/freebsd-arm64': 0.18.20 - '@esbuild/freebsd-x64': 0.18.20 - '@esbuild/linux-arm': 0.18.20 - '@esbuild/linux-arm64': 0.18.20 - '@esbuild/linux-ia32': 0.18.20 - '@esbuild/linux-loong64': 0.18.20 - '@esbuild/linux-mips64el': 0.18.20 - '@esbuild/linux-ppc64': 0.18.20 - '@esbuild/linux-riscv64': 0.18.20 - '@esbuild/linux-s390x': 0.18.20 - '@esbuild/linux-x64': 0.18.20 - '@esbuild/netbsd-x64': 0.18.20 - '@esbuild/openbsd-x64': 0.18.20 - '@esbuild/sunos-x64': 0.18.20 - '@esbuild/win32-arm64': 0.18.20 - '@esbuild/win32-ia32': 0.18.20 - '@esbuild/win32-x64': 0.18.20 - - esbuild@0.19.12: - optionalDependencies: - '@esbuild/aix-ppc64': 0.19.12 - '@esbuild/android-arm': 0.19.12 - '@esbuild/android-arm64': 0.19.12 - '@esbuild/android-x64': 0.19.12 - '@esbuild/darwin-arm64': 0.19.12 - '@esbuild/darwin-x64': 0.19.12 - '@esbuild/freebsd-arm64': 0.19.12 - '@esbuild/freebsd-x64': 0.19.12 - '@esbuild/linux-arm': 0.19.12 - '@esbuild/linux-arm64': 0.19.12 - '@esbuild/linux-ia32': 0.19.12 - '@esbuild/linux-loong64': 0.19.12 - '@esbuild/linux-mips64el': 0.19.12 - '@esbuild/linux-ppc64': 0.19.12 - '@esbuild/linux-riscv64': 0.19.12 - '@esbuild/linux-s390x': 0.19.12 - '@esbuild/linux-x64': 0.19.12 - '@esbuild/netbsd-x64': 0.19.12 - '@esbuild/openbsd-x64': 0.19.12 - '@esbuild/sunos-x64': 0.19.12 - '@esbuild/win32-arm64': 0.19.12 - '@esbuild/win32-ia32': 0.19.12 - '@esbuild/win32-x64': 0.19.12 - - esbuild@0.20.2: - optionalDependencies: - '@esbuild/aix-ppc64': 0.20.2 - '@esbuild/android-arm': 0.20.2 - '@esbuild/android-arm64': 0.20.2 - '@esbuild/android-x64': 0.20.2 - '@esbuild/darwin-arm64': 0.20.2 - '@esbuild/darwin-x64': 0.20.2 - '@esbuild/freebsd-arm64': 0.20.2 - '@esbuild/freebsd-x64': 0.20.2 - '@esbuild/linux-arm': 0.20.2 - '@esbuild/linux-arm64': 0.20.2 - '@esbuild/linux-ia32': 0.20.2 - '@esbuild/linux-loong64': 0.20.2 - '@esbuild/linux-mips64el': 0.20.2 - '@esbuild/linux-ppc64': 0.20.2 - '@esbuild/linux-riscv64': 0.20.2 - '@esbuild/linux-s390x': 0.20.2 - '@esbuild/linux-x64': 0.20.2 - '@esbuild/netbsd-x64': 0.20.2 - '@esbuild/openbsd-x64': 0.20.2 - '@esbuild/sunos-x64': 0.20.2 - '@esbuild/win32-arm64': 0.20.2 - '@esbuild/win32-ia32': 0.20.2 - '@esbuild/win32-x64': 0.20.2 - - escalade@3.1.2: {} - - escape-string-regexp@2.0.0: {} - - escape-string-regexp@4.0.0: {} - - escape-string-regexp@5.0.0: {} - - eslint-config-prettier@9.1.0(eslint@8.57.0): - dependencies: - eslint: 8.57.0 - - eslint-plugin-prettier@5.1.3(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@8.57.0)(prettier@2.8.8): - dependencies: - eslint: 8.57.0 - prettier: 2.8.8 - prettier-linter-helpers: 1.0.0 - synckit: 0.8.8 - optionalDependencies: - eslint-config-prettier: 9.1.0(eslint@8.57.0) - - eslint-scope@7.2.2: - dependencies: - esrecurse: 4.3.0 - estraverse: 5.3.0 - - eslint-visitor-keys@3.4.3: {} - - eslint@8.57.0: - dependencies: - '@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.57.0 - '@humanwhocodes/config-array': 0.11.14 - '@humanwhocodes/module-importer': 1.0.1 - '@nodelib/fs.walk': 1.2.8 - '@ungap/structured-clone': 1.2.0 - ajv: 6.12.6 - chalk: 4.1.2 - cross-spawn: 7.0.3 - debug: 4.3.4 - doctrine: 3.0.0 - escape-string-regexp: 4.0.0 - eslint-scope: 7.2.2 - eslint-visitor-keys: 3.4.3 - espree: 9.6.1 - esquery: 1.5.0 - esutils: 2.0.3 - fast-deep-equal: 3.1.3 - file-entry-cache: 6.0.1 - find-up: 5.0.0 - glob-parent: 6.0.2 - globals: 13.24.0 - graphemer: 1.4.0 - ignore: 5.3.1 - imurmurhash: 0.1.4 - is-glob: 4.0.3 - is-path-inside: 3.0.3 - js-yaml: 4.1.0 - json-stable-stringify-without-jsonify: 1.0.1 - levn: 0.4.1 - lodash.merge: 4.6.2 - minimatch: 3.1.2 - natural-compare: 1.4.0 - optionator: 0.9.4 - strip-ansi: 6.0.1 - text-table: 0.2.0 - transitivePeerDependencies: - - supports-color - - esniff@2.0.1: - dependencies: - d: 1.0.2 - es5-ext: 0.10.64 - event-emitter: 0.3.5 - type: 2.7.2 - - espree@9.6.1: - dependencies: - acorn: 8.11.3 - acorn-jsx: 5.3.2(acorn@8.11.3) - eslint-visitor-keys: 3.4.3 - - esprima@4.0.1: {} - - esquery@1.5.0: - dependencies: - estraverse: 5.3.0 - - esrecurse@4.3.0: - dependencies: - estraverse: 5.3.0 - - estraverse@5.3.0: {} - - estree-walker@0.6.1: {} - - estree-walker@3.0.3: - dependencies: - '@types/estree': 1.0.5 - - esutils@2.0.3: {} - - event-emitter@0.3.5: - dependencies: - d: 1.0.2 - es5-ext: 0.10.64 - - event-stream@3.3.4: - dependencies: - duplexer: 0.1.2 - from: 0.1.7 - map-stream: 0.1.0 - pause-stream: 0.0.11 - split: 0.3.3 - stream-combiner: 0.0.4 - through: 2.3.8 - - execa@5.1.1: - dependencies: - cross-spawn: 7.0.3 - get-stream: 6.0.1 - human-signals: 2.1.0 - is-stream: 2.0.1 - merge-stream: 2.0.0 - npm-run-path: 4.0.1 - onetime: 5.1.2 - signal-exit: 3.0.7 - strip-final-newline: 2.0.0 - - execa@8.0.1: - dependencies: - cross-spawn: 7.0.3 - get-stream: 8.0.1 - human-signals: 5.0.0 - is-stream: 3.0.0 - merge-stream: 2.0.0 - npm-run-path: 5.3.0 - onetime: 6.0.0 - signal-exit: 4.1.0 - strip-final-newline: 3.0.0 - - exit-hook@2.2.1: {} - - expand-template@2.0.3: {} - - ext@1.7.0: - dependencies: - type: 2.7.2 - - fast-deep-equal@3.1.3: {} - - fast-diff@1.3.0: {} - - fast-glob@3.3.2: - dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.5 - - fast-json-stable-stringify@2.1.0: {} - - fast-levenshtein@2.0.6: {} - - fast-xml-parser@4.2.5: - dependencies: - strnum: 1.0.5 - - fastq@1.17.1: - dependencies: - reusify: 1.0.4 - - fetch-blob@3.2.0: - dependencies: - node-domexception: 1.0.0 - web-streams-polyfill: 3.3.3 - - fflate@0.8.2: {} - - figures@5.0.0: - dependencies: - escape-string-regexp: 5.0.0 - is-unicode-supported: 1.3.0 - - file-entry-cache@6.0.1: - dependencies: - flat-cache: 3.2.0 - - file-uri-to-path@1.0.0: {} - - fill-range@7.1.1: - dependencies: - to-regex-range: 5.0.1 - - find-up@5.0.0: - dependencies: - locate-path: 6.0.0 - path-exists: 4.0.0 - - find-up@6.3.0: - dependencies: - locate-path: 7.2.0 - path-exists: 5.0.0 - - flat-cache@3.2.0: - dependencies: - flatted: 3.3.1 - keyv: 4.5.4 - rimraf: 3.0.2 - - flatted@3.3.1: {} - - foreground-child@3.1.1: - dependencies: - cross-spawn: 7.0.3 - signal-exit: 4.1.0 - - form-data@4.0.0: - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - mime-types: 2.1.35 - - formdata-polyfill@4.0.10: - dependencies: - fetch-blob: 3.2.0 - - from@0.1.7: {} - - fs-constants@1.0.0: {} - - fs-extra@11.2.0: - dependencies: - graceful-fs: 4.2.11 - jsonfile: 6.1.0 - universalify: 2.0.1 - - fs.realpath@1.0.0: {} - - fsevents@2.3.3: - optional: true - - function-bind@1.1.2: {} - - fx@34.0.0: {} - - generate-function@2.3.1: - dependencies: - is-property: 1.0.2 - - get-caller-file@2.0.5: {} - - get-func-name@2.0.2: {} - - get-port@6.1.2: {} - - get-source@2.0.12: - dependencies: - data-uri-to-buffer: 2.0.2 - source-map: 0.6.1 - - get-stream@6.0.1: {} - - get-stream@8.0.1: {} - - get-tsconfig@4.7.5: - dependencies: - resolve-pkg-maps: 1.0.0 - - github-from-package@0.0.0: {} - - glob-parent@5.1.2: - dependencies: - is-glob: 4.0.3 - - glob-parent@6.0.2: - dependencies: - is-glob: 4.0.3 - - glob-to-regexp@0.4.1: {} - - glob@10.3.15: - dependencies: - foreground-child: 3.1.1 - jackspeak: 2.3.6 - minimatch: 9.0.4 - minipass: 7.1.1 - path-scurry: 1.11.1 - - glob@7.2.3: - dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 3.1.2 - once: 1.4.0 - path-is-absolute: 1.0.1 - - glob@8.1.0: - dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 5.1.6 - once: 1.4.0 - - globals@13.24.0: - dependencies: - type-fest: 0.20.2 - - globby@11.1.0: - dependencies: - array-union: 2.1.0 - dir-glob: 3.0.1 - fast-glob: 3.3.2 - ignore: 5.3.1 - merge2: 1.4.1 - slash: 3.0.0 - - globby@13.2.2: - dependencies: - dir-glob: 3.0.1 - fast-glob: 3.3.2 - ignore: 5.3.1 - merge2: 1.4.1 - slash: 4.0.0 - - globrex@0.1.2: {} - - graceful-fs@4.2.11: {} - - graphemer@1.4.0: {} - - hanji@0.0.5: - dependencies: - lodash.throttle: 4.1.1 - sisteransi: 1.0.5 - - has-flag@4.0.0: {} - - hasown@2.0.2: - dependencies: - function-bind: 1.1.2 - - heap@0.2.7: {} - - hono@4.3.9: {} - - human-signals@2.1.0: {} - - human-signals@5.0.0: {} - - iconv-lite@0.6.3: - dependencies: - safer-buffer: 2.1.2 - - ieee754@1.2.1: {} - - ignore-by-default@2.1.0: {} - - ignore@5.3.1: {} - - import-fresh@3.3.0: - dependencies: - parent-module: 1.0.1 - resolve-from: 4.0.0 - - imurmurhash@0.1.4: {} - - indent-string@5.0.0: {} - - inflight@1.0.6: - dependencies: - once: 1.4.0 - wrappy: 1.0.2 - - inherits@2.0.4: {} - - ini@1.3.8: {} - - irregular-plurals@3.5.0: {} - - is-binary-path@2.1.0: - dependencies: - binary-extensions: 2.3.0 - - is-core-module@2.13.1: - dependencies: - hasown: 2.0.2 - - is-error@2.2.2: {} - - is-extglob@2.1.1: {} - - is-fullwidth-code-point@3.0.0: {} - - is-fullwidth-code-point@4.0.0: {} - - is-glob@4.0.3: - dependencies: - is-extglob: 2.1.1 - - is-number@7.0.0: {} - - is-path-inside@3.0.3: {} - - is-plain-object@5.0.0: {} - - is-promise@2.2.2: {} - - is-promise@4.0.0: {} - - is-property@1.0.2: {} - - is-stream@2.0.1: {} - - is-stream@3.0.0: {} - - is-unicode-supported@1.3.0: {} - - is-what@4.1.16: {} - - isexe@2.0.0: {} - - jackspeak@2.3.6: - dependencies: - '@isaacs/cliui': 8.0.2 - optionalDependencies: - '@pkgjs/parseargs': 0.11.0 - - joycon@3.1.1: {} - - js-base64@3.7.7: {} - - js-string-escape@1.0.1: {} - - js-tokens@9.0.0: {} - - js-yaml@3.14.1: - dependencies: - argparse: 1.0.10 - esprima: 4.0.1 - - js-yaml@4.1.0: - dependencies: - argparse: 2.0.1 - - json-buffer@3.0.1: {} - - json-diff@0.9.0: - dependencies: - cli-color: 2.0.4 - difflib: 0.2.4(patch_hash=jq4t3ysdpnbunjeje4v7nrqn2q) - dreamopt: 0.8.0 - - json-diff@1.0.6: - dependencies: - '@ewoudenberg/difflib': 0.1.0 - colors: 1.4.0 - dreamopt: 0.8.0 - - json-schema-traverse@0.4.1: {} - - json-stable-stringify-without-jsonify@1.0.1: {} - - jsonfile@6.1.0: - dependencies: - universalify: 2.0.1 - optionalDependencies: - graceful-fs: 4.2.11 - - keyv@4.5.4: - dependencies: - json-buffer: 3.0.1 - - levn@0.4.1: - dependencies: - prelude-ls: 1.2.1 - type-check: 0.4.0 - - libsql@0.2.0: - dependencies: - '@neon-rs/load': 0.0.4 - detect-libc: 2.0.2 - optionalDependencies: - '@libsql/darwin-arm64': 0.2.0 - '@libsql/darwin-x64': 0.2.0 - '@libsql/linux-arm64-gnu': 0.2.0 - '@libsql/linux-arm64-musl': 0.2.0 - '@libsql/linux-x64-gnu': 0.2.0 - '@libsql/linux-x64-musl': 0.2.0 - '@libsql/win32-x64-msvc': 0.2.0 - optional: true - - lilconfig@3.1.1: {} - - lines-and-columns@1.2.4: {} - - load-json-file@7.0.1: {} - - load-tsconfig@0.2.5: {} - - local-pkg@0.5.0: - dependencies: - mlly: 1.7.0 - pkg-types: 1.1.1 - - locate-path@6.0.0: - dependencies: - p-locate: 5.0.0 - - locate-path@7.2.0: - dependencies: - p-locate: 6.0.0 - - lodash.merge@4.6.2: {} - - lodash.sortby@4.7.0: {} - - lodash.throttle@4.1.1: {} - - lodash@4.17.21: {} - - long@4.0.0: {} - - loupe@2.3.7: - dependencies: - get-func-name: 2.0.2 - - lru-cache@10.2.2: {} - - lru-cache@6.0.0: - dependencies: - yallist: 4.0.0 - - lru-cache@7.18.3: {} - - lru-queue@0.1.0: - dependencies: - es5-ext: 0.10.64 - - magic-string@0.25.9: - dependencies: - sourcemap-codec: 1.4.8 - - magic-string@0.30.10: - dependencies: - '@jridgewell/sourcemap-codec': 1.4.15 - - map-age-cleaner@0.1.3: - dependencies: - p-defer: 1.0.0 - - map-stream@0.1.0: {} - - marked-terminal@6.2.0(marked@9.1.6): - dependencies: - ansi-escapes: 6.2.1 - cardinal: 2.1.1 - chalk: 5.3.0 - cli-table3: 0.6.5 - marked: 9.1.6 - node-emoji: 2.1.3 - supports-hyperlinks: 3.0.0 - - marked@9.1.6: {} - - matcher@5.0.0: - dependencies: - escape-string-regexp: 5.0.0 - - md5-hex@3.0.1: - dependencies: - blueimp-md5: 2.19.0 - - mem@9.0.2: - dependencies: - map-age-cleaner: 0.1.3 - mimic-fn: 4.0.0 - - memoizee@0.4.15: - dependencies: - d: 1.0.2 - es5-ext: 0.10.64 - es6-weak-map: 2.0.3 - event-emitter: 0.3.5 - is-promise: 2.2.2 - lru-queue: 0.1.0 - next-tick: 1.1.0 - timers-ext: 0.1.7 - - merge-stream@2.0.0: {} - - merge2@1.4.1: {} - - micromatch@4.0.5: - dependencies: - braces: 3.0.2 - picomatch: 2.3.1 - - mime-db@1.52.0: {} - - mime-types@2.1.35: - dependencies: - mime-db: 1.52.0 - - mime@3.0.0: {} - - mimic-fn@2.1.0: {} - - mimic-fn@4.0.0: {} - - mimic-response@3.1.0: {} - - miniflare@3.20240512.0(bufferutil@4.0.8)(utf-8-validate@6.0.3): - dependencies: - '@cspotcode/source-map-support': 0.8.1 - acorn: 8.11.3 - acorn-walk: 8.3.2 - capnp-ts: 0.7.0 - exit-hook: 2.2.1 - glob-to-regexp: 0.4.1 - stoppable: 1.1.0 - undici: 5.28.4 - workerd: 1.20240512.0 - ws: 8.17.0(bufferutil@4.0.8)(utf-8-validate@6.0.3) - youch: 3.3.3 - zod: 3.23.8 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - - minimatch@3.1.2: - dependencies: - brace-expansion: 1.1.11 - - minimatch@5.1.6: - dependencies: - brace-expansion: 2.0.1 - - minimatch@7.4.6: - dependencies: - brace-expansion: 2.0.1 - - minimatch@9.0.4: - dependencies: - brace-expansion: 2.0.1 - - minimist@1.2.8: {} - - minipass@7.1.1: {} - - mkdirp-classic@0.5.3: {} - - mlly@1.7.0: - dependencies: - acorn: 8.11.3 - pathe: 1.1.2 - pkg-types: 1.1.1 - ufo: 1.5.3 - - ms@2.1.2: {} - - ms@2.1.3: {} - - mustache@4.2.0: {} - - mysql2@2.3.3: - dependencies: - denque: 2.1.0 - generate-function: 2.3.1 - iconv-lite: 0.6.3 - long: 4.0.0 - lru-cache: 6.0.0 - named-placeholders: 1.1.3 - seq-queue: 0.0.5 - sqlstring: 2.3.3 - - mz@2.7.0: - dependencies: - any-promise: 1.3.0 - object-assign: 4.1.1 - thenify-all: 1.6.0 - - named-placeholders@1.1.3: - dependencies: - lru-cache: 7.18.3 - - nan@2.19.0: - optional: true - - nanoid@3.3.7: {} - - napi-build-utils@1.0.2: {} - - natural-compare@1.4.0: {} - - next-tick@1.1.0: {} - - node-abi@3.62.0: - dependencies: - semver: 7.6.2 - - node-domexception@1.0.0: {} - - node-emoji@2.1.3: - dependencies: - '@sindresorhus/is': 4.6.0 - char-regex: 1.0.2 - emojilib: 2.4.0 - skin-tone: 2.0.0 - - node-fetch@2.7.0: - dependencies: - whatwg-url: 5.0.0 - - node-fetch@3.3.1: - dependencies: - data-uri-to-buffer: 4.0.1 - fetch-blob: 3.2.0 - formdata-polyfill: 4.0.10 - - node-fetch@3.3.2: - dependencies: - data-uri-to-buffer: 4.0.1 - fetch-blob: 3.2.0 - formdata-polyfill: 4.0.10 - - node-forge@1.3.1: {} - - node-gyp-build@4.8.1: {} - - nofilter@3.1.0: {} - - normalize-path@3.0.0: {} - - npm-run-path@4.0.1: - dependencies: - path-key: 3.1.1 - - npm-run-path@5.3.0: - dependencies: - path-key: 4.0.0 - - object-assign@4.1.1: {} - - obuf@1.1.2: {} - - once@1.4.0: - dependencies: - wrappy: 1.0.2 - - onetime@5.1.2: - dependencies: - mimic-fn: 2.1.0 - - onetime@6.0.0: - dependencies: - mimic-fn: 4.0.0 - - optionator@0.9.4: - dependencies: - deep-is: 0.1.4 - fast-levenshtein: 2.0.6 - levn: 0.4.1 - prelude-ls: 1.2.1 - type-check: 0.4.0 - word-wrap: 1.2.5 - - p-defer@1.0.0: {} - - p-event@5.0.1: - dependencies: - p-timeout: 5.1.0 - - p-limit@3.1.0: - dependencies: - yocto-queue: 0.1.0 - - p-limit@4.0.0: - dependencies: - yocto-queue: 1.0.0 - - p-limit@5.0.0: - dependencies: - yocto-queue: 1.0.0 - - p-locate@5.0.0: - dependencies: - p-limit: 3.1.0 - - p-locate@6.0.0: - dependencies: - p-limit: 4.0.0 - - p-map@5.5.0: - dependencies: - aggregate-error: 4.0.1 - - p-timeout@5.1.0: {} - - parent-module@1.0.1: - dependencies: - callsites: 3.1.0 - - parse-ms@3.0.0: {} - - path-exists@4.0.0: {} - - path-exists@5.0.0: {} - - path-is-absolute@1.0.1: {} - - path-key@3.1.1: {} - - path-key@4.0.0: {} - - path-parse@1.0.7: {} - - path-scurry@1.11.1: - dependencies: - lru-cache: 10.2.2 - minipass: 7.1.1 - - path-to-regexp@6.2.2: {} - - path-type@4.0.0: {} - - pathe@1.1.2: {} - - pathval@1.1.1: {} - - pause-stream@0.0.11: - dependencies: - through: 2.3.8 - - pg-cloudflare@1.1.1: - optional: true - - pg-connection-string@2.6.4: {} - - pg-int8@1.0.1: {} - - pg-numeric@1.0.2: {} - - pg-pool@3.6.2(pg@8.11.5): - dependencies: - pg: 8.11.5 - - pg-protocol@1.6.1: {} - - pg-types@2.2.0: - dependencies: - pg-int8: 1.0.1 - postgres-array: 2.0.0 - postgres-bytea: 1.0.0 - postgres-date: 1.0.7 - postgres-interval: 1.2.0 - - pg-types@4.0.2: - dependencies: - pg-int8: 1.0.1 - pg-numeric: 1.0.2 - postgres-array: 3.0.2 - postgres-bytea: 3.0.0 - postgres-date: 2.1.0 - postgres-interval: 3.0.0 - postgres-range: 1.1.4 - - pg@8.11.5: - dependencies: - pg-connection-string: 2.6.4 - pg-pool: 3.6.2(pg@8.11.5) - pg-protocol: 1.6.1 - pg-types: 2.2.0 - pgpass: 1.0.5 - optionalDependencies: - pg-cloudflare: 1.1.1 - - pgpass@1.0.5: - dependencies: - split2: 4.2.0 - - picocolors@1.0.1: {} - - picomatch@2.3.1: {} - - pirates@4.0.6: {} - - pkg-conf@4.0.0: - dependencies: - find-up: 6.3.0 - load-json-file: 7.0.1 - - pkg-types@1.1.1: - dependencies: - confbox: 0.1.7 - mlly: 1.7.0 - pathe: 1.1.2 - - plur@5.1.0: - dependencies: - irregular-plurals: 3.5.0 - - pluralize@8.0.0: {} - - postcss-load-config@4.0.2(postcss@8.4.38): - dependencies: - lilconfig: 3.1.1 - yaml: 2.4.2 - optionalDependencies: - postcss: 8.4.38 - - postcss@8.4.38: - dependencies: - nanoid: 3.3.7 - picocolors: 1.0.1 - source-map-js: 1.2.0 - - postgres-array@2.0.0: {} - - postgres-array@3.0.2: {} - - postgres-bytea@1.0.0: {} - - postgres-bytea@3.0.0: - dependencies: - obuf: 1.1.2 - - postgres-date@1.0.7: {} - - postgres-date@2.1.0: {} - - postgres-interval@1.2.0: - dependencies: - xtend: 4.0.2 - - postgres-interval@3.0.0: {} - - postgres-range@1.1.4: {} - - postgres@3.4.4: {} - - prebuild-install@7.1.2: - dependencies: - detect-libc: 2.0.3 - expand-template: 2.0.3 - github-from-package: 0.0.0 - minimist: 1.2.8 - mkdirp-classic: 0.5.3 - napi-build-utils: 1.0.2 - node-abi: 3.62.0 - pump: 3.0.0 - rc: 1.2.8 - simple-get: 4.0.1 - tar-fs: 2.1.1 - tunnel-agent: 0.6.0 - - prelude-ls@1.2.1: {} - - prettier-linter-helpers@1.0.0: - dependencies: - fast-diff: 1.3.0 - - prettier@2.8.8: {} - - pretty-format@29.7.0: - dependencies: - '@jest/schemas': 29.6.3 - ansi-styles: 5.2.0 - react-is: 18.3.1 - - pretty-ms@8.0.0: - dependencies: - parse-ms: 3.0.0 - - printable-characters@1.0.42: {} - - ps-tree@1.2.0: - dependencies: - event-stream: 3.3.4 - - pump@3.0.0: - dependencies: - end-of-stream: 1.4.4 - once: 1.4.0 - - punycode@2.3.1: {} - - queue-microtask@1.2.3: {} - - rc@1.2.8: - dependencies: - deep-extend: 0.6.0 - ini: 1.3.8 - minimist: 1.2.8 - strip-json-comments: 2.0.1 - - react-is@18.3.1: {} - - readable-stream@3.6.2: - dependencies: - inherits: 2.0.4 - string_decoder: 1.3.0 - util-deprecate: 1.0.2 - - readdirp@3.6.0: - dependencies: - picomatch: 2.3.1 - - redeyed@2.1.1: - dependencies: - esprima: 4.0.1 - - require-directory@2.1.1: {} - - resolve-cwd@3.0.0: - dependencies: - resolve-from: 5.0.0 - - resolve-from@4.0.0: {} - - resolve-from@5.0.0: {} - - resolve-pkg-maps@1.0.0: {} - - resolve.exports@2.0.2: {} - - resolve@1.22.8: - dependencies: - is-core-module: 2.13.1 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - - reusify@1.0.4: {} - - rimraf@3.0.2: - dependencies: - glob: 7.2.3 - - rollup-plugin-inject@3.0.2: - dependencies: - estree-walker: 0.6.1 - magic-string: 0.25.9 - rollup-pluginutils: 2.8.2 - - rollup-plugin-node-polyfills@0.2.1: - dependencies: - rollup-plugin-inject: 3.0.2 - - rollup-pluginutils@2.8.2: - dependencies: - estree-walker: 0.6.1 - - rollup@4.17.2: - dependencies: - '@types/estree': 1.0.5 - optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.17.2 - '@rollup/rollup-android-arm64': 4.17.2 - '@rollup/rollup-darwin-arm64': 4.17.2 - '@rollup/rollup-darwin-x64': 4.17.2 - '@rollup/rollup-linux-arm-gnueabihf': 4.17.2 - '@rollup/rollup-linux-arm-musleabihf': 4.17.2 - '@rollup/rollup-linux-arm64-gnu': 4.17.2 - '@rollup/rollup-linux-arm64-musl': 4.17.2 - '@rollup/rollup-linux-powerpc64le-gnu': 4.17.2 - '@rollup/rollup-linux-riscv64-gnu': 4.17.2 - '@rollup/rollup-linux-s390x-gnu': 4.17.2 - '@rollup/rollup-linux-x64-gnu': 4.17.2 - '@rollup/rollup-linux-x64-musl': 4.17.2 - '@rollup/rollup-win32-arm64-msvc': 4.17.2 - '@rollup/rollup-win32-ia32-msvc': 4.17.2 - '@rollup/rollup-win32-x64-msvc': 4.17.2 - fsevents: 2.3.3 - - run-parallel@1.2.0: - dependencies: - queue-microtask: 1.2.3 - - safe-buffer@5.2.1: {} - - safer-buffer@2.1.2: {} - - selfsigned@2.4.1: - dependencies: - '@types/node-forge': 1.3.11 - node-forge: 1.3.1 - - semver@7.6.2: {} - - seq-queue@0.0.5: {} - - serialize-error@7.0.1: - dependencies: - type-fest: 0.13.1 - - shebang-command@2.0.0: - dependencies: - shebang-regex: 3.0.0 - - shebang-regex@3.0.0: {} - - siginfo@2.0.0: {} - - signal-exit@3.0.7: {} - - signal-exit@4.1.0: {} - - simple-concat@1.0.1: {} - - simple-get@4.0.1: - dependencies: - decompress-response: 6.0.0 - once: 1.4.0 - simple-concat: 1.0.1 - - sisteransi@1.0.5: {} - - skin-tone@2.0.0: - dependencies: - unicode-emoji-modifier-base: 1.0.0 - - slash@3.0.0: {} - - slash@4.0.0: {} - - slice-ansi@5.0.0: - dependencies: - ansi-styles: 6.2.1 - is-fullwidth-code-point: 4.0.0 - - source-map-js@1.2.0: {} - - source-map-support@0.5.21: - dependencies: - buffer-from: 1.1.2 - source-map: 0.6.1 - - source-map@0.6.1: {} - - source-map@0.8.0-beta.0: - dependencies: - whatwg-url: 7.1.0 - - sourcemap-codec@1.4.8: {} - - split-ca@1.0.1: {} - - split2@4.2.0: {} - - split@0.3.3: - dependencies: - through: 2.3.8 - - sprintf-js@1.0.3: {} - - sqlstring@2.3.3: {} - - ssh2@1.15.0: - dependencies: - asn1: 0.2.6 - bcrypt-pbkdf: 1.0.2 - optionalDependencies: - cpu-features: 0.0.10 - nan: 2.19.0 - - stack-utils@2.0.6: - dependencies: - escape-string-regexp: 2.0.0 - - stackback@0.0.2: {} - - stacktracey@2.1.8: - dependencies: - as-table: 1.0.55 - get-source: 2.0.12 - - std-env@3.7.0: {} - - stoppable@1.1.0: {} - - stream-combiner@0.0.4: - dependencies: - duplexer: 0.1.2 - - string-width@4.2.3: - dependencies: - emoji-regex: 8.0.0 - is-fullwidth-code-point: 3.0.0 - strip-ansi: 6.0.1 - - string-width@5.1.2: - dependencies: - eastasianwidth: 0.2.0 - emoji-regex: 9.2.2 - strip-ansi: 7.1.0 - - string_decoder@1.3.0: - dependencies: - safe-buffer: 5.2.1 - - strip-ansi@6.0.1: - dependencies: - ansi-regex: 5.0.1 - - strip-ansi@7.1.0: - dependencies: - ansi-regex: 6.0.1 - - strip-final-newline@2.0.0: {} - - strip-final-newline@3.0.0: {} - - strip-json-comments@2.0.1: {} - - strip-json-comments@3.1.1: {} - - strip-literal@2.1.0: - dependencies: - js-tokens: 9.0.0 - - strnum@1.0.5: {} - - sucrase@3.35.0: - dependencies: - '@jridgewell/gen-mapping': 0.3.5 - commander: 4.1.1 - glob: 10.3.15 - lines-and-columns: 1.2.4 - mz: 2.7.0 - pirates: 4.0.6 - ts-interface-checker: 0.1.13 - - superjson@2.2.1: - dependencies: - copy-anything: 3.0.5 - - supertap@3.0.1: - dependencies: - indent-string: 5.0.0 - js-yaml: 3.14.1 - serialize-error: 7.0.1 - strip-ansi: 7.1.0 - - supports-color@7.2.0: - dependencies: - has-flag: 4.0.0 - - supports-hyperlinks@3.0.0: - dependencies: - has-flag: 4.0.0 - supports-color: 7.2.0 - - supports-preserve-symlinks-flag@1.0.0: {} - - synckit@0.8.8: - dependencies: - '@pkgr/core': 0.1.1 - tslib: 2.6.2 - - tar-fs@2.0.1: - dependencies: - chownr: 1.1.4 - mkdirp-classic: 0.5.3 - pump: 3.0.0 - tar-stream: 2.2.0 - - tar-fs@2.1.1: - dependencies: - chownr: 1.1.4 - mkdirp-classic: 0.5.3 - pump: 3.0.0 - tar-stream: 2.2.0 - - tar-stream@2.2.0: - dependencies: - bl: 4.1.0 - end-of-stream: 1.4.4 - fs-constants: 1.0.0 - inherits: 2.0.4 - readable-stream: 3.6.2 - - temp-dir@3.0.0: {} - - text-table@0.2.0: {} - - thenify-all@1.6.0: - dependencies: - thenify: 3.3.1 - - thenify@3.3.1: - dependencies: - any-promise: 1.3.0 - - through@2.3.8: {} - - time-zone@1.0.0: {} - - timers-ext@0.1.7: - dependencies: - es5-ext: 0.10.64 - next-tick: 1.1.0 - - tinybench@2.8.0: {} - - tinypool@0.8.4: {} - - tinyspy@2.2.1: {} - - to-regex-range@5.0.1: - dependencies: - is-number: 7.0.0 - - tr46@0.0.3: {} - - tr46@1.0.1: - dependencies: - punycode: 2.3.1 - - tree-kill@1.2.2: {} - - ts-api-utils@1.3.0(typescript@5.4.5): - dependencies: - typescript: 5.4.5 - - ts-expose-internals-conditionally@1.0.0-empty.0: {} - - ts-interface-checker@0.1.13: {} - - tsconfck@3.0.3(typescript@5.4.5): - optionalDependencies: - typescript: 5.4.5 - - tslib@1.14.1: {} - - tslib@2.6.2: {} - - tsup@8.0.2(postcss@8.4.38)(typescript@5.4.5): - dependencies: - bundle-require: 4.1.0(esbuild@0.19.12) - cac: 6.7.14 - chokidar: 3.6.0 - debug: 4.3.4 - esbuild: 0.19.12 - execa: 5.1.1 - globby: 11.1.0 - joycon: 3.1.1 - postcss-load-config: 4.0.2(postcss@8.4.38) - resolve-from: 5.0.0 - rollup: 4.17.2 - source-map: 0.8.0-beta.0 - sucrase: 3.35.0 - tree-kill: 1.2.2 - optionalDependencies: - postcss: 8.4.38 - typescript: 5.4.5 - transitivePeerDependencies: - - supports-color - - ts-node - - tsx@3.14.0: - dependencies: - esbuild: 0.18.20 - get-tsconfig: 4.7.5 - source-map-support: 0.5.21 - optionalDependencies: - fsevents: 2.3.3 - - tunnel-agent@0.6.0: - dependencies: - safe-buffer: 5.2.1 - - tweetnacl@0.14.5: {} - - type-check@0.4.0: - dependencies: - prelude-ls: 1.2.1 - - type-detect@4.0.8: {} - - type-fest@0.13.1: {} - - type-fest@0.20.2: {} - - type@2.7.2: {} - - typescript@5.3.3: {} - - typescript@5.4.5: {} - - ufo@1.5.3: {} - - undici-types@5.26.5: {} - - undici@5.28.4: - dependencies: - '@fastify/busboy': 2.1.1 - - unicode-emoji-modifier-base@1.0.0: {} - - universalify@2.0.1: {} - - uri-js@4.4.1: - dependencies: - punycode: 2.3.1 - - utf-8-validate@6.0.3: - dependencies: - node-gyp-build: 4.8.1 - - util-deprecate@1.0.2: {} - - uuid@9.0.1: {} - - validate-npm-package-name@5.0.1: {} - - vite-node@1.6.0(@types/node@18.19.33): - dependencies: - cac: 6.7.14 - debug: 4.3.4 - pathe: 1.1.2 - picocolors: 1.0.1 - vite: 5.2.11(@types/node@18.19.33) - transitivePeerDependencies: - - '@types/node' - - less - - lightningcss - - sass - - stylus - - sugarss - - supports-color - - terser - - vite-tsconfig-paths@4.3.2(typescript@5.4.5)(vite@5.2.11(@types/node@18.19.33)): - dependencies: - debug: 4.3.4 - globrex: 0.1.2 - tsconfck: 3.0.3(typescript@5.4.5) - optionalDependencies: - vite: 5.2.11(@types/node@18.19.33) - transitivePeerDependencies: - - supports-color - - typescript - - vite@5.2.11(@types/node@18.19.33): - dependencies: - esbuild: 0.20.2 - postcss: 8.4.38 - rollup: 4.17.2 - optionalDependencies: - '@types/node': 18.19.33 - fsevents: 2.3.3 - - vitest@1.6.0(@types/node@18.19.33): - dependencies: - '@vitest/expect': 1.6.0 - '@vitest/runner': 1.6.0 - '@vitest/snapshot': 1.6.0 - '@vitest/spy': 1.6.0 - '@vitest/utils': 1.6.0 - acorn-walk: 8.3.2 - chai: 4.4.1 - debug: 4.3.4 - execa: 8.0.1 - local-pkg: 0.5.0 - magic-string: 0.30.10 - pathe: 1.1.2 - picocolors: 1.0.1 - std-env: 3.7.0 - strip-literal: 2.1.0 - tinybench: 2.8.0 - tinypool: 0.8.4 - vite: 5.2.11(@types/node@18.19.33) - vite-node: 1.6.0(@types/node@18.19.33) - why-is-node-running: 2.2.2 - optionalDependencies: - '@types/node': 18.19.33 - transitivePeerDependencies: - - less - - lightningcss - - sass - - stylus - - sugarss - - supports-color - - terser - - web-streams-polyfill@3.3.3: {} - - webidl-conversions@3.0.1: {} - - webidl-conversions@4.0.2: {} - - webpod@0.0.2: {} - - well-known-symbols@2.0.0: {} - - whatwg-url@5.0.0: - dependencies: - tr46: 0.0.3 - webidl-conversions: 3.0.1 - - whatwg-url@7.1.0: - dependencies: - lodash.sortby: 4.7.0 - tr46: 1.0.1 - webidl-conversions: 4.0.2 - - which@2.0.2: - dependencies: - isexe: 2.0.0 - - which@3.0.1: - dependencies: - isexe: 2.0.0 - - why-is-node-running@2.2.2: - dependencies: - siginfo: 2.0.0 - stackback: 0.0.2 - - word-wrap@1.2.5: {} - - wordwrap@1.0.0: {} - - workerd@1.20240512.0: - optionalDependencies: - '@cloudflare/workerd-darwin-64': 1.20240512.0 - '@cloudflare/workerd-darwin-arm64': 1.20240512.0 - '@cloudflare/workerd-linux-64': 1.20240512.0 - '@cloudflare/workerd-linux-arm64': 1.20240512.0 - '@cloudflare/workerd-windows-64': 1.20240512.0 - - wrangler@3.57.0(@cloudflare/workers-types@4.20240512.0)(bufferutil@4.0.8)(utf-8-validate@6.0.3): - dependencies: - '@cloudflare/kv-asset-handler': 0.3.2 - '@esbuild-plugins/node-globals-polyfill': 0.2.3(esbuild@0.17.19) - '@esbuild-plugins/node-modules-polyfill': 0.2.2(esbuild@0.17.19) - blake3-wasm: 2.1.5 - chokidar: 3.6.0 - esbuild: 0.17.19 - miniflare: 3.20240512.0(bufferutil@4.0.8)(utf-8-validate@6.0.3) - nanoid: 3.3.7 - path-to-regexp: 6.2.2 - resolve: 1.22.8 - resolve.exports: 2.0.2 - selfsigned: 2.4.1 - source-map: 0.6.1 - xxhash-wasm: 1.0.2 - optionalDependencies: - '@cloudflare/workers-types': 4.20240512.0 - fsevents: 2.3.3 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - - wrap-ansi@7.0.0: - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - - wrap-ansi@8.1.0: - dependencies: - ansi-styles: 6.2.1 - string-width: 5.1.2 - strip-ansi: 7.1.0 - - wrappy@1.0.2: {} - - write-file-atomic@5.0.1: - dependencies: - imurmurhash: 0.1.4 - signal-exit: 4.1.0 - - ws@8.14.2(bufferutil@4.0.8)(utf-8-validate@6.0.3): - optionalDependencies: - bufferutil: 4.0.8 - utf-8-validate: 6.0.3 - - ws@8.17.0(bufferutil@4.0.8)(utf-8-validate@6.0.3): - optionalDependencies: - bufferutil: 4.0.8 - utf-8-validate: 6.0.3 - - xtend@4.0.2: {} - - xxhash-wasm@1.0.2: {} - - y18n@5.0.8: {} - - yallist@4.0.0: {} - - yaml@2.4.2: {} - - yargs-parser@21.1.1: {} - - yargs@17.7.2: - dependencies: - cliui: 8.0.1 - escalade: 3.1.2 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - string-width: 4.2.3 - y18n: 5.0.8 - yargs-parser: 21.1.1 - - yocto-queue@0.1.0: {} - - yocto-queue@1.0.0: {} - - youch@3.3.3: - dependencies: - cookie: 0.5.0 - mustache: 4.2.0 - stacktracey: 2.1.8 - - zod@3.23.8: {} - - zx@7.2.3: - dependencies: - '@types/fs-extra': 11.0.4 - '@types/minimist': 1.2.5 - '@types/node': 18.19.33 - '@types/ps-tree': 1.1.6 - '@types/which': 3.0.3 - chalk: 5.3.0 - fs-extra: 11.2.0 - fx: 34.0.0 - globby: 13.2.2 - minimist: 1.2.8 - node-fetch: 3.3.1 - ps-tree: 1.2.0 - webpod: 0.0.2 - which: 3.0.1 - yaml: 2.4.2 diff --git a/drizzle-kit/src/api.ts b/drizzle-kit/src/api.ts index a5b8bfe69..83b7139ad 100644 --- a/drizzle-kit/src/api.ts +++ b/drizzle-kit/src/api.ts @@ -5,7 +5,10 @@ import { PgDatabase } from 'drizzle-orm/pg-core'; import { columnsResolver, enumsResolver, + indPolicyResolver, mySqlViewsResolver, + policyResolver, + roleResolver, schemasResolver, sequencesResolver, sqliteViewsResolver, @@ -47,6 +50,8 @@ export const generateDrizzleJson = ( prepared.enums, prepared.schemas, prepared.sequences, + prepared.roles, + prepared.policies, prepared.views, prepared.matViews, casing, @@ -78,6 +83,9 @@ export const generateMigration = async ( schemasResolver, enumsResolver, sequencesResolver, + policyResolver, + indPolicyResolver, + roleResolver, tablesResolver, columnsResolver, viewsResolver, @@ -108,6 +116,7 @@ export const pushSchema = async ( db, [], schemaFilters ?? ['public'], + undefined, ); const validatedPrev = pgSchema.parse(prev); @@ -122,6 +131,9 @@ export const pushSchema = async ( schemasResolver, enumsResolver, sequencesResolver, + policyResolver, + indPolicyResolver, + roleResolver, tablesResolver, columnsResolver, viewsResolver, diff --git a/drizzle-kit/src/cli/commands/introspect.ts b/drizzle-kit/src/cli/commands/introspect.ts index 257150dc0..db250d005 100644 --- a/drizzle-kit/src/cli/commands/introspect.ts +++ b/drizzle-kit/src/cli/commands/introspect.ts @@ -21,6 +21,7 @@ import { applySqliteSnapshotsDiff, } from '../../snapshotsDiffer'; import { prepareOutFolder } from '../../utils'; +import { Entities } from '../validations/cli'; import type { Casing, Prefix } from '../validations/common'; import { LibSQLCredentials } from '../validations/libsql'; import type { MysqlCredentials } from '../validations/mysql'; @@ -30,7 +31,10 @@ import { IntrospectProgress } from '../views'; import { columnsResolver, enumsResolver, + indPolicyResolver, mySqlViewsResolver, + policyResolver, + roleResolver, schemasResolver, sequencesResolver, sqliteViewsResolver, @@ -47,6 +51,7 @@ export const introspectPostgres = async ( tablesFilter: string[], schemasFilter: string[], prefix: Prefix, + entities: Entities, ) => { const { preparePostgresDB } = await import('../connections'); const db = await preparePostgresDB(credentials); @@ -79,11 +84,18 @@ export const introspectPostgres = async ( }; const progress = new IntrospectProgress(true); + const res = await renderWithTask( progress, - fromPostgresDatabase(db, filter, schemasFilter, (stage, count, status) => { - progress.update(stage, count, status); - }), + fromPostgresDatabase( + db, + filter, + schemasFilter, + entities, + (stage, count, status) => { + progress.update(stage, count, status); + }, + ), ); const schema = { id: originUUID, prevId: '', ...res } as PgSchema; @@ -106,6 +118,9 @@ export const introspectPostgres = async ( schemasResolver, enumsResolver, sequencesResolver, + policyResolver, + indPolicyResolver, + roleResolver, tablesResolver, columnsResolver, viewsResolver, diff --git a/drizzle-kit/src/cli/commands/migrate.ts b/drizzle-kit/src/cli/commands/migrate.ts index c4f1e65d1..8d1e6205f 100644 --- a/drizzle-kit/src/cli/commands/migrate.ts +++ b/drizzle-kit/src/cli/commands/migrate.ts @@ -14,7 +14,7 @@ import path, { join } from 'path'; import { TypeOf } from 'zod'; import type { CommonSchema } from '../../schemaValidator'; import { MySqlSchema, mysqlSchema, squashMysqlScheme, ViewSquashed } from '../../serializer/mysqlSchema'; -import { PgSchema, pgSchema, squashPgScheme, View } from '../../serializer/pgSchema'; +import { PgSchema, pgSchema, Policy, Role, squashPgScheme, View } from '../../serializer/pgSchema'; import { SQLiteSchema, sqliteSchema, squashSqliteScheme, View as SQLiteView } from '../../serializer/sqliteSchema'; import { applyLibSQLSnapshotsDiff, @@ -25,11 +25,17 @@ import { ColumnsResolverInput, ColumnsResolverOutput, Enum, + PolicyResolverInput, + PolicyResolverOutput, ResolverInput, ResolverOutput, ResolverOutputWithMoved, + RolesResolverInput, + RolesResolverOutput, Sequence, Table, + TablePolicyResolverInput, + TablePolicyResolverOutput, } from '../../snapshotsDiffer'; import { assertV1OutFolder, Journal, prepareMigrationFolder } from '../../utils'; import { prepareMigrationMetadata } from '../../utils/words'; @@ -41,6 +47,7 @@ import { ResolveColumnSelect, ResolveSchemasSelect, ResolveSelect, + ResolveSelectNamed, schema, } from '../views'; import { GenerateConfig } from './utils'; @@ -180,6 +187,53 @@ export const sequencesResolver = async ( } }; +export const roleResolver = async ( + input: RolesResolverInput, +): Promise> => { + const result = await promptNamedConflict( + input.created, + input.deleted, + 'role', + ); + return { + created: result.created, + deleted: result.deleted, + renamed: result.renamed, + }; +}; + +export const policyResolver = async ( + input: TablePolicyResolverInput, +): Promise> => { + const result = await promptColumnsConflicts( + input.tableName, + input.created, + input.deleted, + ); + return { + tableName: input.tableName, + schema: input.schema, + created: result.created, + deleted: result.deleted, + renamed: result.renamed, + }; +}; + +export const indPolicyResolver = async ( + input: PolicyResolverInput, +): Promise> => { + const result = await promptNamedConflict( + input.created, + input.deleted, + 'policy', + ); + return { + created: result.created, + deleted: result.deleted, + renamed: result.renamed, + }; +}; + export const enumsResolver = async ( input: ResolverInput, ): Promise> => { @@ -264,6 +318,9 @@ export const prepareAndMigratePg = async (config: GenerateConfig) => { schemasResolver, enumsResolver, sequencesResolver, + policyResolver, + indPolicyResolver, + roleResolver, tablesResolver, columnsResolver, viewsResolver, @@ -310,6 +367,9 @@ export const preparePgPush = async ( schemasResolver, enumsResolver, sequencesResolver, + policyResolver, + indPolicyResolver, + roleResolver, tablesResolver, columnsResolver, viewsResolver, @@ -736,6 +796,78 @@ export const promptColumnsConflicts = async ( return result; }; +export const promptNamedConflict = async ( + newItems: T[], + missingItems: T[], + entity: 'role' | 'policy', +): Promise<{ + created: T[]; + renamed: { from: T; to: T }[]; + deleted: T[]; +}> => { + if (missingItems.length === 0 || newItems.length === 0) { + return { + created: newItems, + renamed: [], + deleted: missingItems, + }; + } + + const result: { + created: T[]; + renamed: { from: T; to: T }[]; + deleted: T[]; + } = { created: [], renamed: [], deleted: [] }; + let index = 0; + let leftMissing = [...missingItems]; + do { + const created = newItems[index]; + const renames: RenamePropmtItem[] = leftMissing.map((it) => { + return { from: it, to: created }; + }); + + const promptData: (RenamePropmtItem | T)[] = [created, ...renames]; + + const { status, data } = await render( + new ResolveSelectNamed(created, promptData, entity), + ); + if (status === 'aborted') { + console.error('ERROR'); + process.exit(1); + } + + if (isRenamePromptItem(data)) { + console.log( + `${chalk.yellow('~')} ${data.from.name} › ${data.to.name} ${ + chalk.gray( + `${entity} will be renamed/moved`, + ) + }`, + ); + + if (data.from.name !== data.to.name) { + result.renamed.push(data); + } + + delete leftMissing[leftMissing.indexOf(data.from)]; + leftMissing = leftMissing.filter(Boolean); + } else { + console.log( + `${chalk.green('+')} ${data.name} ${ + chalk.gray( + `${entity} will be created`, + ) + }`, + ); + result.created.push(created); + } + index += 1; + } while (index < newItems.length); + console.log(chalk.gray(`--- all ${entity} conflicts resolved ---\n`)); + result.deleted.push(...leftMissing); + return result; +}; + export const promptNamedWithSchemasConflict = async ( newItems: T[], missingItems: T[], diff --git a/drizzle-kit/src/cli/commands/mysqlUp.ts b/drizzle-kit/src/cli/commands/mysqlUp.ts index 6c7d2ebe5..8b467090b 100644 --- a/drizzle-kit/src/cli/commands/mysqlUp.ts +++ b/drizzle-kit/src/cli/commands/mysqlUp.ts @@ -82,6 +82,7 @@ export const upMySqlHandlerV4toV5 = (obj: MySqlSchemaV4): MySqlSchemaV5 => { columns: mappedColumns, compositePrimaryKeys: {}, uniqueConstraints: {}, + checkConstraint: {}, }; } diff --git a/drizzle-kit/src/cli/commands/pgIntrospect.ts b/drizzle-kit/src/cli/commands/pgIntrospect.ts index dbd3ba238..2d3fd75ce 100644 --- a/drizzle-kit/src/cli/commands/pgIntrospect.ts +++ b/drizzle-kit/src/cli/commands/pgIntrospect.ts @@ -4,12 +4,14 @@ import { originUUID } from '../../global'; import type { PgSchema } from '../../serializer/pgSchema'; import { fromDatabase } from '../../serializer/pgSerializer'; import type { DB } from '../../utils'; +import { Entities } from '../validations/cli'; import { ProgressView } from '../views'; export const pgPushIntrospect = async ( db: DB, filters: string[], schemaFilters: string[], + entities: Entities, ) => { const matchers = filters.map((it) => { return new Minimatch(it); @@ -43,7 +45,7 @@ export const pgPushIntrospect = async ( ); const res = await renderWithTask( progress, - fromDatabase(db, filter, schemaFilters), + fromDatabase(db, filter, schemaFilters, entities), ); const schema = { id: originUUID, prevId: '', ...res } as PgSchema; diff --git a/drizzle-kit/src/cli/commands/pgPushUtils.ts b/drizzle-kit/src/cli/commands/pgPushUtils.ts index a8e2570df..b53fec3e7 100644 --- a/drizzle-kit/src/cli/commands/pgPushUtils.ts +++ b/drizzle-kit/src/cli/commands/pgPushUtils.ts @@ -252,18 +252,12 @@ export const pgSuggestions = async (db: DB, statements: JsonStatement[]) => { } const stmnt = fromJson([statement], 'postgresql'); if (typeof stmnt !== 'undefined') { - if (statement.type === 'drop_table') { - statementsToExecute.push( - `DROP TABLE ${concatSchemaAndTableName(statement.schema, statement.tableName)} CASCADE;`, - ); - } else { - statementsToExecute.push(...stmnt); - } + statementsToExecute.push(...stmnt); } } return { - statementsToExecute, + statementsToExecute: [...new Set(statementsToExecute)], shouldAskForApprove, infoToPrint, matViewsToRemove: [...new Set(matViewsToRemove)], diff --git a/drizzle-kit/src/cli/commands/pgUp.ts b/drizzle-kit/src/cli/commands/pgUp.ts index f3faaeb62..52a2fc4a1 100644 --- a/drizzle-kit/src/cli/commands/pgUp.ts +++ b/drizzle-kit/src/cli/commands/pgUp.ts @@ -93,7 +93,7 @@ export const updateUpToV7 = (json: Record): PgSchema => { return [idx[0], { columns: mappedColumns, with: {}, ...rest }]; }), ); - return [it[0], { ...table, indexes: mappedIndexes }]; + return [it[0], { ...table, indexes: mappedIndexes, policies: {}, isRLSEnabled: false, checkConstraints: {} }]; }), ); @@ -103,6 +103,9 @@ export const updateUpToV7 = (json: Record): PgSchema => { dialect: 'postgresql', sequences: {}, tables: tables, + policies: {}, + views: {}, + roles: {}, }; }; diff --git a/drizzle-kit/src/cli/commands/push.ts b/drizzle-kit/src/cli/commands/push.ts index f84f84d9c..7ef690d81 100644 --- a/drizzle-kit/src/cli/commands/push.ts +++ b/drizzle-kit/src/cli/commands/push.ts @@ -2,6 +2,7 @@ import chalk from 'chalk'; import { render } from 'hanji'; import { fromJson } from '../../sqlgenerator'; import { Select } from '../selector-ui'; +import { Entities } from '../validations/cli'; import { CasingType } from '../validations/common'; import { LibSQLCredentials } from '../validations/libsql'; import type { MysqlCredentials } from '../validations/mysql'; @@ -160,6 +161,7 @@ export const pgPush = async ( credentials: PostgresCredentials, tablesFilter: string[], schemasFilter: string[], + entities: Entities, force: boolean, casing: CasingType | undefined, ) => { @@ -167,7 +169,7 @@ export const pgPush = async ( const { pgPushIntrospect } = await import('./pgIntrospect'); const db = await preparePostgresDB(credentials); - const { schema } = await pgPushIntrospect(db, tablesFilter, schemasFilter); + const { schema } = await pgPushIntrospect(db, tablesFilter, schemasFilter, entities); const { preparePgPush } = await import('./migrate'); diff --git a/drizzle-kit/src/cli/commands/sqliteUp.ts b/drizzle-kit/src/cli/commands/sqliteUp.ts index b76b9e2cd..aaa1fa7b9 100644 --- a/drizzle-kit/src/cli/commands/sqliteUp.ts +++ b/drizzle-kit/src/cli/commands/sqliteUp.ts @@ -47,5 +47,6 @@ const updateUpToV6 = (json: Record): SQLiteSchema => { version: '6', dialect: 'sqlite', tables: tables, + views: {}, }; }; diff --git a/drizzle-kit/src/cli/commands/utils.ts b/drizzle-kit/src/cli/commands/utils.ts index e58e23435..203e38cca 100644 --- a/drizzle-kit/src/cli/commands/utils.ts +++ b/drizzle-kit/src/cli/commands/utils.ts @@ -6,7 +6,7 @@ import { object, string } from 'zod'; import { assertUnreachable } from '../../global'; import { type Dialect, dialect } from '../../schemaValidator'; import { prepareFilenames } from '../../serializer'; -import { pullParams, pushParams } from '../validations/cli'; +import { Entities, pullParams, pushParams } from '../validations/cli'; import { Casing, CasingType, @@ -229,6 +229,7 @@ export const preparePushConfig = async ( tablesFilter: string[]; schemasFilter: string[]; casing?: CasingType; + entities?: Entities; } > => { const raw = flattenDatabaseCredentials( @@ -300,6 +301,7 @@ export const preparePushConfig = async ( casing: config.casing, tablesFilter, schemasFilter, + entities: config.entities, }; } @@ -391,6 +393,7 @@ export const preparePullConfig = async ( tablesFilter: string[]; schemasFilter: string[]; prefix: Prefix; + entities: Entities; } > => { const raw = flattenPull( @@ -450,6 +453,7 @@ export const preparePullConfig = async ( tablesFilter, schemasFilter, prefix: config.migrations?.prefix || 'index', + entities: config.entities, }; } @@ -468,6 +472,7 @@ export const preparePullConfig = async ( tablesFilter, schemasFilter, prefix: config.migrations?.prefix || 'index', + entities: config.entities, }; } @@ -486,6 +491,7 @@ export const preparePullConfig = async ( tablesFilter, schemasFilter, prefix: config.migrations?.prefix || 'index', + entities: config.entities, }; } @@ -504,6 +510,7 @@ export const preparePullConfig = async ( tablesFilter, schemasFilter, prefix: config.migrations?.prefix || 'index', + entities: config.entities, }; } diff --git a/drizzle-kit/src/cli/connections.ts b/drizzle-kit/src/cli/connections.ts index 6c4b44634..aab1d0ef7 100644 --- a/drizzle-kit/src/cli/connections.ts +++ b/drizzle-kit/src/cli/connections.ts @@ -57,7 +57,7 @@ export const preparePostgresDB = async ( ); const db = drizzle(rdsClient, config); - const migrateFn = async (config: string | MigrationConfig) => { + const migrateFn = async (config: MigrationConfig) => { return migrate(db, config); }; @@ -104,7 +104,7 @@ export const preparePostgresDB = async ( if (driver === 'pglite') { assertPackages('@electric-sql/pglite'); - const { PGlite } = await import('@electric-sql/pglite'); + const { PGlite, types } = await import('@electric-sql/pglite'); const { drizzle } = await import('drizzle-orm/pglite'); const { migrate } = await import('drizzle-orm/pglite/migrator'); @@ -115,25 +115,26 @@ export const preparePostgresDB = async ( return migrate(drzl, config); }; + const parsers = { + [types.TIMESTAMP]: (value: any) => value, + [types.TIMESTAMPTZ]: (value: any) => value, + [types.INTERVAL]: (value: any) => value, + [types.DATE]: (value: any) => value, + }; + const query = async (sql: string, params: any[] = []) => { - const result = await pglite.query(sql, params); + const result = await pglite.query(sql, params, { + parsers, + }); return result.rows as T[]; }; const proxy = async (params: ProxyParams) => { const preparedParams = preparePGliteParams(params.params); - if ( - params.method === 'values' - || params.method === 'get' - || params.method === 'all' - ) { - const result = await pglite.query(params.sql, preparedParams, { - rowMode: params.mode, - }); - return result.rows; - } - - const result = await pglite.query(params.sql, preparedParams); + const result = await pglite.query(params.sql, preparedParams, { + rowMode: params.mode, + parsers, + }); return result.rows; }; @@ -145,7 +146,7 @@ export const preparePostgresDB = async ( if (await checkPackage('pg')) { console.log(withStyle.info(`Using 'pg' driver for database querying`)); - const pg = await import('pg'); + const { default: pg } = await import('pg'); const { drizzle } = await import('drizzle-orm/node-postgres'); const { migrate } = await import('drizzle-orm/node-postgres/migrator'); @@ -159,17 +160,42 @@ export const preparePostgresDB = async ( : credentials.ssl : {}; + // Override pg default date parsers + const types: { getTypeParser: typeof pg.types.getTypeParser } = { + // @ts-ignore + getTypeParser: (typeId, format) => { + if (typeId === pg.types.builtins.TIMESTAMPTZ) { + return (val) => val; + } + if (typeId === pg.types.builtins.TIMESTAMP) { + return (val) => val; + } + if (typeId === pg.types.builtins.DATE) { + return (val) => val; + } + if (typeId === pg.types.builtins.INTERVAL) { + return (val) => val; + } + // @ts-ignore + return pg.types.getTypeParser(typeId, format); + }, + }; + const client = 'url' in credentials - ? new pg.default.Pool({ connectionString: credentials.url, max: 1 }) - : new pg.default.Pool({ ...credentials, ssl, max: 1 }); + ? new pg.Pool({ connectionString: credentials.url, max: 1 }) + : new pg.Pool({ ...credentials, ssl, max: 1 }); const db = drizzle(client); - const migrateFn = async (config: string | MigrationConfig) => { + const migrateFn = async (config: MigrationConfig) => { return migrate(db, config); }; const query = async (sql: string, params?: any[]) => { - const result = await client.query(sql, params ?? []); + const result = await client.query({ + text: sql, + values: params ?? [], + types, + }); return result.rows; }; @@ -178,6 +204,7 @@ export const preparePostgresDB = async ( text: params.sql, values: params.params, ...(params.mode === 'array' && { rowMode: 'array' }), + types, }); return result.rows; }; @@ -198,8 +225,18 @@ export const preparePostgresDB = async ( ? postgres.default(credentials.url, { max: 1 }) : postgres.default({ ...credentials, max: 1 }); + const transparentParser = (val: any) => val; + + // Override postgres.js default date parsers: https://github.com/porsager/postgres/discussions/761 + for (const type of ['1184', '1082', '1083', '1114']) { + client.options.parsers[type as any] = transparentParser; + client.options.serializers[type as any] = transparentParser; + } + client.options.serializers['114'] = transparentParser; + client.options.serializers['3802'] = transparentParser; + const db = drizzle(client); - const migrateFn = async (config: string | MigrationConfig) => { + const migrateFn = async (config: MigrationConfig) => { return migrate(db, config); }; @@ -227,7 +264,7 @@ export const preparePostgresDB = async ( "'@vercel/postgres' can only connect to remote Neon/Vercel Postgres/Supabase instances through a websocket", ), ); - const { VercelPool } = await import('@vercel/postgres'); + const { VercelPool, types: pgTypes } = await import('@vercel/postgres'); const { drizzle } = await import('drizzle-orm/vercel-postgres'); const { migrate } = await import('drizzle-orm/vercel-postgres/migrator'); const ssl = 'ssl' in credentials @@ -240,6 +277,27 @@ export const preparePostgresDB = async ( : credentials.ssl : {}; + // Override @vercel/postgres default date parsers + const types: { getTypeParser: typeof pgTypes.getTypeParser } = { + // @ts-ignore + getTypeParser: (typeId, format) => { + if (typeId === pgTypes.builtins.TIMESTAMPTZ) { + return (val: any) => val; + } + if (typeId === pgTypes.builtins.TIMESTAMP) { + return (val: any) => val; + } + if (typeId === pgTypes.builtins.DATE) { + return (val: any) => val; + } + if (typeId === pgTypes.builtins.INTERVAL) { + return (val: any) => val; + } + // @ts-ignore + return pgTypes.getTypeParser(typeId, format); + }, + }; + const client = 'url' in credentials ? new VercelPool({ connectionString: credentials.url }) : new VercelPool({ ...credentials, ssl }); @@ -247,12 +305,16 @@ export const preparePostgresDB = async ( await client.connect(); const db = drizzle(client); - const migrateFn = async (config: string | MigrationConfig) => { + const migrateFn = async (config: MigrationConfig) => { return migrate(db, config); }; const query = async (sql: string, params?: any[]) => { - const result = await client.query(sql, params ?? []); + const result = await client.query({ + text: sql, + values: params ?? [], + types, + }); return result.rows; }; @@ -261,6 +323,7 @@ export const preparePostgresDB = async ( text: params.sql, values: params.params, ...(params.mode === 'array' && { rowMode: 'array' }), + types, }); return result.rows; }; @@ -279,7 +342,7 @@ export const preparePostgresDB = async ( "'@neondatabase/serverless' can only connect to remote Neon/Vercel Postgres/Supabase instances through a websocket", ), ); - const { Pool, neonConfig } = await import('@neondatabase/serverless'); + const { Pool, neonConfig, types: pgTypes } = await import('@neondatabase/serverless'); const { drizzle } = await import('drizzle-orm/neon-serverless'); const { migrate } = await import('drizzle-orm/neon-serverless/migrator'); @@ -293,18 +356,43 @@ export const preparePostgresDB = async ( : credentials.ssl : {}; + // Override @neondatabase/serverless default date parsers + const types: { getTypeParser: typeof pgTypes.getTypeParser } = { + // @ts-ignore + getTypeParser: (typeId, format) => { + if (typeId === pgTypes.builtins.TIMESTAMPTZ) { + return (val: any) => val; + } + if (typeId === pgTypes.builtins.TIMESTAMP) { + return (val: any) => val; + } + if (typeId === pgTypes.builtins.DATE) { + return (val: any) => val; + } + if (typeId === pgTypes.builtins.INTERVAL) { + return (val: any) => val; + } + // @ts-ignore + return pgTypes.getTypeParser(typeId, format); + }, + }; + const client = 'url' in credentials ? new Pool({ connectionString: credentials.url, max: 1 }) : new Pool({ ...credentials, max: 1, ssl }); neonConfig.webSocketConstructor = ws; const db = drizzle(client); - const migrateFn = async (config: string | MigrationConfig) => { + const migrateFn = async (config: MigrationConfig) => { return migrate(db, config); }; const query = async (sql: string, params?: any[]) => { - const result = await client.query(sql, params ?? []); + const result = await client.query({ + text: sql, + values: params ?? [], + types, + }); return result.rows; }; @@ -313,6 +401,7 @@ export const preparePostgresDB = async ( text: params.sql, values: params.params, ...(params.mode === 'array' && { rowMode: 'array' }), + types, }); return result.rows; }; @@ -373,12 +462,23 @@ export const connectToMySQL = async ( return migrate(db, config); }; + const typeCast = (field: any, next: any) => { + if (field.type === 'TIMESTAMP' || field.type === 'DATETIME' || field.type === 'DATE') { + return field.string(); + } + return next(); + }; + await connection.connect(); const query: DB['query'] = async ( sql: string, params?: any[], ): Promise => { - const res = await connection.execute(sql, params); + const res = await connection.execute({ + sql, + values: params, + typeCast, + }); return res[0] as any; }; @@ -387,6 +487,7 @@ export const connectToMySQL = async ( sql: params.sql, values: params.params, rowsAsArray: params.mode === 'array', + typeCast, }); return result[0] as any[]; }; @@ -400,13 +501,13 @@ export const connectToMySQL = async ( } if (await checkPackage('@planetscale/database')) { - const { connect } = await import('@planetscale/database'); + const { Client } = await import('@planetscale/database'); const { drizzle } = await import('drizzle-orm/planetscale-serverless'); const { migrate } = await import( 'drizzle-orm/planetscale-serverless/migrator' ); - const connection = connect(result); + const connection = new Client(result); const db = drizzle(connection); const migrateFn = async (config: MigrationConfig) => { diff --git a/drizzle-kit/src/cli/schema.ts b/drizzle-kit/src/cli/schema.ts index aaded5cdf..64ceb5841 100644 --- a/drizzle-kit/src/cli/schema.ts +++ b/drizzle-kit/src/cli/schema.ts @@ -269,6 +269,7 @@ export const push = command({ schemasFilter, force, casing, + entities, } = config; try { @@ -313,6 +314,7 @@ export const push = command({ credentials, tablesFilter, schemasFilter, + entities, force, casing, ); @@ -450,6 +452,7 @@ export const pull = command({ tablesFilter, schemasFilter, prefix, + entities, } = config; mkdirSync(out, { recursive: true }); @@ -496,6 +499,7 @@ export const pull = command({ tablesFilter, schemasFilter, prefix, + entities, ); } else if (dialect === 'mysql') { const { introspectMysql } = await import('./commands/introspect'); diff --git a/drizzle-kit/src/cli/utils.ts b/drizzle-kit/src/cli/utils.ts index 4f665ec05..a4c28851e 100644 --- a/drizzle-kit/src/cli/utils.ts +++ b/drizzle-kit/src/cli/utils.ts @@ -74,7 +74,7 @@ export const assertEitherPackage = async ( process.exit(1); }; -const requiredApiVersion = 9; +const requiredApiVersion = 10; export const assertOrmCoreVersion = async () => { try { const { compatibilityVersion } = await import('drizzle-orm/version'); diff --git a/drizzle-kit/src/cli/validations/cli.ts b/drizzle-kit/src/cli/validations/cli.ts index aa92f7c6d..a2a5ad81f 100644 --- a/drizzle-kit/src/cli/validations/cli.ts +++ b/drizzle-kit/src/cli/validations/cli.ts @@ -1,4 +1,4 @@ -import { boolean, intersection, literal, object, string, TypeOf, union } from 'zod'; +import { array, boolean, intersection, literal, object, string, TypeOf, union } from 'zod'; import { dialect } from '../../schemaValidator'; import { casing, casingType, prefix } from './common'; @@ -26,6 +26,13 @@ export const pushParams = object({ extensionsFilters: literal('postgis').array().optional(), verbose: boolean().optional(), strict: boolean().optional(), + entities: object({ + roles: boolean().or(object({ + provider: string().optional(), + include: string().array().optional(), + exclude: string().array().optional(), + })).optional().default(false), + }).optional(), }).passthrough(); export type PushParams = TypeOf; @@ -44,8 +51,17 @@ export const pullParams = object({ migrations: object({ prefix: prefix.optional().default('index'), }).optional(), + entities: object({ + roles: boolean().or(object({ + provider: string().optional(), + include: string().array().optional(), + exclude: string().array().optional(), + })).optional().default(false), + }).optional(), }).passthrough(); +export type Entities = TypeOf['entities']; + export type PullParams = TypeOf; export const configCheck = object({ diff --git a/drizzle-kit/src/cli/views.ts b/drizzle-kit/src/cli/views.ts index fd4a68d71..3ec04a588 100644 --- a/drizzle-kit/src/cli/views.ts +++ b/drizzle-kit/src/cli/views.ts @@ -158,6 +158,77 @@ export const tableKey = (it: NamedWithSchema) => { : `${it.schema}.${it.name}`; }; +export class ResolveSelectNamed extends Prompt< + RenamePropmtItem | T +> { + private readonly state: SelectState | T>; + + constructor( + private readonly base: T, + data: (RenamePropmtItem | T)[], + private readonly entityType: 'role' | 'policy', + ) { + super(); + this.on('attach', (terminal) => terminal.toggleCursor('hide')); + this.state = new SelectState(data); + this.state.bind(this); + this.base = base; + } + + render(status: 'idle' | 'submitted' | 'aborted'): string { + if (status === 'submitted' || status === 'aborted') { + return ''; + } + const key = this.base.name; + + let text = `\nIs ${chalk.bold.blue(key)} ${this.entityType} created or renamed from another ${this.entityType}?\n`; + + const isSelectedRenamed = isRenamePromptItem( + this.state.items[this.state.selectedIdx], + ); + + const selectedPrefix = isSelectedRenamed + ? chalk.yellow('❯ ') + : chalk.green('❯ '); + + const labelLength: number = this.state.items + .filter((it) => isRenamePromptItem(it)) + .map((_) => { + const it = _ as RenamePropmtItem; + const keyFrom = it.from.name; + return key.length + 3 + keyFrom.length; + }) + .reduce((a, b) => { + if (a > b) { + return a; + } + return b; + }, 0); + + const entityType = this.entityType; + this.state.items.forEach((it, idx) => { + const isSelected = idx === this.state.selectedIdx; + const isRenamed = isRenamePromptItem(it); + + const title = isRenamed + ? `${it.from.name} › ${it.to.name}`.padEnd(labelLength, ' ') + : it.name.padEnd(labelLength, ' '); + + const label = isRenamed + ? `${chalk.yellow('~')} ${title} ${chalk.gray(`rename ${entityType}`)}` + : `${chalk.green('+')} ${title} ${chalk.gray(`create ${entityType}`)}`; + + text += isSelected ? `${selectedPrefix}${label}` : ` ${label}`; + text += idx != this.state.items.length - 1 ? '\n' : ''; + }); + return text; + } + + result(): RenamePropmtItem | T { + return this.state.items[this.state.selectedIdx]!; + } +} + export class ResolveSelect extends Prompt< RenamePropmtItem | T > { @@ -166,7 +237,7 @@ export class ResolveSelect extends Prompt< constructor( private readonly base: T, data: (RenamePropmtItem | T)[], - private readonly entityType: 'table' | 'enum' | 'sequence' | 'view', + private readonly entityType: 'table' | 'enum' | 'sequence' | 'view' | 'role', ) { super(); this.on('attach', (terminal) => terminal.toggleCursor('hide')); @@ -330,9 +401,11 @@ export type IntrospectStage = | 'columns' | 'enums' | 'indexes' + | 'policies' | 'checks' | 'fks' | 'views'; + type IntrospectState = { [key in IntrospectStage]: { count: number; @@ -371,6 +444,11 @@ export class IntrospectProgress extends TaskView { name: 'foreign keys', status: 'fetching', }, + policies: { + count: 0, + name: 'policies', + status: 'fetching', + }, checks: { count: 0, name: 'check constraints', @@ -434,6 +512,7 @@ export class IntrospectProgress extends TaskView { info += this.hasEnums ? this.statusText(spin, this.state.enums) : ''; info += this.statusText(spin, this.state.indexes); info += this.statusText(spin, this.state.fks); + info += this.statusText(spin, this.state.policies); info += this.statusText(spin, this.state.checks); info += this.statusText(spin, this.state.views); diff --git a/drizzle-kit/src/index.ts b/drizzle-kit/src/index.ts index 750d491ac..4a57e59e3 100644 --- a/drizzle-kit/src/index.ts +++ b/drizzle-kit/src/index.ts @@ -126,6 +126,9 @@ export type Config = introspect?: { casing: 'camel' | 'preserve'; }; + entities?: { + roles?: boolean | { provider?: 'supabase' | 'neon' | string & {}; exclude?: string[]; include?: string[] }; + }; } & ( | { diff --git a/drizzle-kit/src/introspect-pg.ts b/drizzle-kit/src/introspect-pg.ts index 1b57f0115..ed26e8117 100644 --- a/drizzle-kit/src/introspect-pg.ts +++ b/drizzle-kit/src/introspect-pg.ts @@ -20,6 +20,7 @@ import { Index, PgKitInternals, PgSchemaInternal, + Policy, PrimaryKey, UniqueConstraint, } from './serializer/pgSchema'; @@ -339,6 +340,10 @@ export const schemaToTypeScript = (schema: PgSchemaInternal, casing: Casing) => (it) => 'check', ); + const policiesImports = Object.values(it.policies).map( + (it) => 'pgPolicy', + ); + if (it.schema && it.schema !== 'public' && it.schema !== '') { res.pg.push('pgSchema'); } @@ -347,6 +352,7 @@ export const schemaToTypeScript = (schema: PgSchemaInternal, casing: Casing) => res.pg.push(...fkImpots); res.pg.push(...pkImports); res.pg.push(...uniqueImports); + res.pg.push(...policiesImports); res.pg.push(...checkImports); const columnImports = Object.values(it.columns) @@ -417,6 +423,10 @@ export const schemaToTypeScript = (schema: PgSchemaInternal, casing: Casing) => } }); + if (Object.keys(schema.roles).length > 0) { + imports.pg.push('pgRole'); + } + const enumStatements = Object.values(schema.enums) .map((it) => { const enumSchema = schemas[it.schema]; @@ -468,7 +478,7 @@ export const schemaToTypeScript = (schema: PgSchemaInternal, casing: Casing) => })\n`; }) .join('') - .concat('\n'); + .concat(''); const schemaStatements = Object.entries(schemas) // .filter((it) => it[0] !== "public") @@ -477,6 +487,24 @@ export const schemaToTypeScript = (schema: PgSchemaInternal, casing: Casing) => }) .join(''); + const rolesNameToTsKey: Record = {}; + + const rolesStatements = Object.entries(schema.roles) + .map((it) => { + const fields = it[1]; + rolesNameToTsKey[fields.name] = it[0]; + return `export const ${withCasing(it[0], casing)} = pgRole("${fields.name}", ${ + !fields.createDb && !fields.createRole && fields.inherit + ? '' + : `${ + `, { ${fields.createDb ? `createDb: true,` : ''}${fields.createRole ? ` createRole: true,` : ''}${ + !fields.inherit ? ` inherit: false ` : '' + }`.trimChar(',') + }}` + } );\n`; + }) + .join(''); + const tableStatements = Object.values(schema.tables).map((table) => { const tableSchema = schemas[table.schema]; const paramName = paramNameFor(table.name, tableSchema); @@ -503,11 +531,12 @@ export const schemaToTypeScript = (schema: PgSchemaInternal, casing: Casing) => if ( Object.keys(table.indexes).length > 0 || Object.values(table.foreignKeys).length > 0 + || Object.values(table.policies).length > 0 || Object.keys(table.compositePrimaryKeys).length > 0 || Object.keys(table.uniqueConstraints).length > 0 || Object.keys(table.checkConstraints).length > 0 ) { - statement += ',\n'; + statement += ', '; statement += '(table) => {\n'; statement += '\treturn {\n'; statement += createTableIndexes(table.name, Object.values(table.indexes), casing); @@ -520,6 +549,11 @@ export const schemaToTypeScript = (schema: PgSchemaInternal, casing: Casing) => Object.values(table.uniqueConstraints), casing, ); + statement += createTablePolicies( + Object.values(table.policies), + casing, + rolesNameToTsKey, + ); statement += createTableChecks( Object.values(table.checkConstraints), casing, @@ -571,10 +605,15 @@ export const schemaToTypeScript = (schema: PgSchemaInternal, casing: Casing) => const uniquePgImports = ['pgTable', ...new Set(imports.pg)]; - const importsTs = `import { ${uniquePgImports.join(', ')} } from "drizzle-orm/pg-core" - import { sql } from "drizzle-orm"\n\n`; + const importsTs = `import { ${ + uniquePgImports.join( + ', ', + ) + } } from "drizzle-orm/pg-core" +import { sql } from "drizzle-orm"\n\n`; let decalrations = schemaStatements; + decalrations += rolesStatements; decalrations += enumStatements; decalrations += sequencesStatements; decalrations += '\n'; @@ -1227,7 +1266,39 @@ const createTablePKs = (pks: PrimaryKey[], casing: Casing): string => { return statement; }; -const createTableUniques = (unqs: UniqueConstraint[], casing: Casing): string => { +// get a map of db role name to ts key +// if to by key is in this map - no quotes, otherwise - quotes + +const createTablePolicies = ( + policies: Policy[], + casing: Casing, + rolesNameToTsKey: Record = {}, +): string => { + let statement = ''; + + policies.forEach((it) => { + const idxKey = withCasing(it.name, casing); + + const mappedItTo = it.to?.map((v) => { + return rolesNameToTsKey[v] ? withCasing(rolesNameToTsKey[v], casing) : `"${v}"`; + }); + + statement += `\t\t${idxKey}: `; + statement += 'pgPolicy('; + statement += `"${it.name}", { `; + statement += `as: "${it.as?.toLowerCase()}", for: "${it.for?.toLowerCase()}", to: [${mappedItTo?.join(', ')}]${ + it.using ? `, using: sql\`${it.using}\`` : '' + }${it.withCheck ? `, withCheck: sql\`${it.withCheck}\` ` : ''}`; + statement += ` }),\n`; + }); + + return statement; +}; + +const createTableUniques = ( + unqs: UniqueConstraint[], + casing: Casing, +): string => { let statement = ''; unqs.forEach((it) => { diff --git a/drizzle-kit/src/jsonDiffer.js b/drizzle-kit/src/jsonDiffer.js index b5a0e3652..da8284979 100644 --- a/drizzle-kit/src/jsonDiffer.js +++ b/drizzle-kit/src/jsonDiffer.js @@ -103,6 +103,22 @@ export function diffSchemasOrTables(left, right) { return { added, deleted }; } +export function diffIndPolicies(left, right) { + left = JSON.parse(JSON.stringify(left)); + right = JSON.parse(JSON.stringify(right)); + + const result = Object.entries(diff(left, right) ?? {}); + + const added = result + .filter((it) => it[0].endsWith('__added')) + .map((it) => it[1]); + const deleted = result + .filter((it) => it[0].endsWith('__deleted')) + .map((it) => it[1]); + + return { added, deleted }; +} + export function diffColumns(left, right) { left = JSON.parse(JSON.stringify(left)); right = JSON.parse(JSON.stringify(right)); @@ -146,6 +162,49 @@ export function diffColumns(left, right) { return alteredTables; } +export function diffPolicies(left, right) { + left = JSON.parse(JSON.stringify(left)); + right = JSON.parse(JSON.stringify(right)); + const result = diff(left, right) ?? {}; + + const alteredTables = Object.fromEntries( + Object.entries(result) + .filter((it) => { + return !(it[0].includes('__added') || it[0].includes('__deleted')); + }) + .map((tableEntry) => { + // const entry = { name: it, ...result[it] } + const deletedPolicies = Object.entries(tableEntry[1].policies ?? {}) + .filter((it) => { + return it[0].endsWith('__deleted'); + }) + .map((it) => { + return it[1]; + }); + + const addedPolicies = Object.entries(tableEntry[1].policies ?? {}) + .filter((it) => { + return it[0].endsWith('__added'); + }) + .map((it) => { + return it[1]; + }); + + tableEntry[1].policies = { + added: addedPolicies, + deleted: deletedPolicies, + }; + const table = left[tableEntry[0]]; + return [ + tableEntry[0], + { name: table.name, schema: table.schema, ...tableEntry[1] }, + ]; + }), + ); + + return alteredTables; +} + export function applyJsonDiff(json1, json2) { json1 = JSON.parse(JSON.stringify(json1)); json2 = JSON.parse(JSON.stringify(json2)); @@ -158,6 +217,8 @@ export function applyJsonDiff(json1, json2) { difference.tables = difference.tables || {}; difference.enums = difference.enums || {}; difference.sequences = difference.sequences || {}; + difference.roles = difference.roles || {}; + difference.policies = difference.policies || {}; difference.views = difference.views || {}; // remove added/deleted schemas @@ -240,6 +301,20 @@ export function applyJsonDiff(json1, json2) { return json2.sequences[it[0]]; }); + const rolesEntries = Object.entries(difference.roles); + const alteredRoles = rolesEntries + .filter((it) => !(it[0].includes('__added') || it[0].includes('__deleted'))) + .map((it) => { + return json2.roles[it[0]]; + }); + + const policiesEntries = Object.entries(difference.policies); + const alteredPolicies = policiesEntries + .filter((it) => !(it[0].includes('__added') || it[0].includes('__deleted'))) + .map((it) => { + return json2.policies[it[0]]; + }); + const viewsEntries = Object.entries(difference.views); const alteredViews = viewsEntries.filter((it) => !(it[0].includes('__added') || it[0].includes('__deleted'))).map( @@ -329,7 +404,9 @@ export function applyJsonDiff(json1, json2) { alteredTablesWithColumns, alteredEnums, alteredSequences, + alteredRoles, alteredViews, + alteredPolicies, }; } @@ -367,6 +444,28 @@ const findAlternationsInTable = (table) => { }), ); + const deletedPolicies = Object.fromEntries( + Object.entries(table.policies__deleted || {}) + .concat( + Object.entries(table.policies || {}).filter((it) => it[0].includes('__deleted')), + ) + .map((entry) => [entry[0].replace('__deleted', ''), entry[1]]), + ); + + const addedPolicies = Object.fromEntries( + Object.entries(table.policies__added || {}) + .concat( + Object.entries(table.policies || {}).filter((it) => it[0].includes('__added')), + ) + .map((entry) => [entry[0].replace('__added', ''), entry[1]]), + ); + + const alteredPolicies = Object.fromEntries( + Object.entries(table.policies || {}).filter((it) => { + return !it[0].endsWith('__deleted') && !it[0].endsWith('__added'); + }), + ); + const deletedForeignKeys = Object.fromEntries( Object.entries(table.foreignKeys__deleted || {}) .concat( @@ -463,6 +562,9 @@ const findAlternationsInTable = (table) => { addedUniqueConstraints, deletedUniqueConstraints, alteredUniqueConstraints, + deletedPolicies, + addedPolicies, + alteredPolicies, addedCheckConstraints, deletedCheckConstraints, alteredCheckConstraints, diff --git a/drizzle-kit/src/jsonStatements.ts b/drizzle-kit/src/jsonStatements.ts index 4285c4687..9359b1a8d 100644 --- a/drizzle-kit/src/jsonStatements.ts +++ b/drizzle-kit/src/jsonStatements.ts @@ -3,7 +3,16 @@ import { getNewTableName } from './cli/commands/sqlitePushUtils'; import { warning } from './cli/views'; import { CommonSquashedSchema } from './schemaValidator'; import { MySqlKitInternals, MySqlSchema, MySqlSquasher, View as MySqlView } from './serializer/mysqlSchema'; -import { Index, MatViewWithOption, PgSchema, PgSquasher, View as PgView, ViewWithOption } from './serializer/pgSchema'; +import { + Index, + MatViewWithOption, + PgSchema, + PgSquasher, + Policy, + Role, + View as PgView, + ViewWithOption, +} from './serializer/pgSchema'; import { SQLiteKitInternals, SQLiteSchemaInternal, @@ -39,8 +48,10 @@ export interface JsonCreateTableStatement { compositePKs: string[]; compositePkName?: string; uniqueConstraints?: string[]; + policies?: string[]; checkConstraints?: string[]; internals?: MySqlKitInternals; + isRLSEnabled?: boolean; } export interface JsonRecreateTableStatement { @@ -65,6 +76,7 @@ export interface JsonDropTableStatement { type: 'drop_table'; tableName: string; schema: string; + policies?: string[]; } export interface JsonRenameTableStatement { @@ -110,6 +122,40 @@ export interface JsonAddValueToEnumStatement { before: string; } +////// + +export interface JsonCreateRoleStatement { + type: 'create_role'; + name: string; + values: { + inherit?: boolean; + createDb?: boolean; + createRole?: boolean; + }; +} + +export interface JsonDropRoleStatement { + type: 'drop_role'; + name: string; +} +export interface JsonRenameRoleStatement { + type: 'rename_role'; + nameFrom: string; + nameTo: string; +} + +export interface JsonAlterRoleStatement { + type: 'alter_role'; + name: string; + values: { + inherit?: boolean; + createDb?: boolean; + createRole?: boolean; + }; +} + +////// + export interface JsonDropValueFromEnumStatement { type: 'alter_type_drop_value'; name: string; @@ -188,6 +234,73 @@ export interface JsonSqliteAddColumnStatement { referenceData?: string; } +export interface JsonCreatePolicyStatement { + type: 'create_policy'; + tableName: string; + data: Policy; + schema: string; +} + +export interface JsonCreateIndPolicyStatement { + type: 'create_ind_policy'; + tableName: string; + data: Policy; +} + +export interface JsonDropPolicyStatement { + type: 'drop_policy'; + tableName: string; + data: Policy; + schema: string; +} + +export interface JsonDropIndPolicyStatement { + type: 'drop_ind_policy'; + tableName: string; + data: Policy; +} + +export interface JsonRenamePolicyStatement { + type: 'rename_policy'; + tableName: string; + oldName: string; + newName: string; + schema: string; +} + +export interface JsonIndRenamePolicyStatement { + type: 'rename_ind_policy'; + tableKey: string; + oldName: string; + newName: string; +} + +export interface JsonEnableRLSStatement { + type: 'enable_rls'; + tableName: string; + schema: string; +} + +export interface JsonDisableRLSStatement { + type: 'disable_rls'; + tableName: string; + schema: string; +} + +export interface JsonAlterPolicyStatement { + type: 'alter_policy'; + tableName: string; + oldData: string; + newData: string; + schema: string; +} + +export interface JsonAlterIndPolicyStatement { + type: 'alter_ind_policy'; + oldData: Policy; + newData: Policy; +} + export interface JsonCreateIndexStatement { type: 'create_index'; tableName: string; @@ -709,6 +822,16 @@ export type JsonStatement = | JsonCreateSequenceStatement | JsonMoveSequenceStatement | JsonRenameSequenceStatement + | JsonDropPolicyStatement + | JsonCreatePolicyStatement + | JsonAlterPolicyStatement + | JsonRenamePolicyStatement + | JsonEnableRLSStatement + | JsonDisableRLSStatement + | JsonRenameRoleStatement + | JsonCreateRoleStatement + | JsonDropRoleStatement + | JsonAlterRoleStatement | JsonCreatePgViewStatement | JsonDropViewStatement | JsonRenameViewStatement @@ -718,14 +841,19 @@ export type JsonStatement = | JsonCreateSqliteViewStatement | JsonCreateCheckConstraint | JsonDeleteCheckConstraint - | JsonDropValueFromEnumStatement; + | JsonDropValueFromEnumStatement + | JsonIndRenamePolicyStatement + | JsonDropIndPolicyStatement + | JsonCreateIndPolicyStatement + | JsonAlterIndPolicyStatement; export const preparePgCreateTableJson = ( table: Table, // TODO: remove? json2: PgSchema, ): JsonCreateTableStatement => { - const { name, schema, columns, compositePrimaryKeys, uniqueConstraints, checkConstraints } = table; + const { name, schema, columns, compositePrimaryKeys, uniqueConstraints, checkConstraints, policies, isRLSEnabled } = + table; const tableKey = `${schema || 'public'}.${name}`; // TODO: @AndriiSherman. We need this, will add test cases @@ -743,7 +871,9 @@ export const preparePgCreateTableJson = ( compositePKs: Object.values(compositePrimaryKeys), compositePkName: compositePkName, uniqueConstraints: Object.values(uniqueConstraints), + policies: Object.values(policies), checkConstraints: Object.values(checkConstraints), + isRLSEnabled: isRLSEnabled ?? false, }; }; @@ -810,6 +940,7 @@ export const prepareDropTableJson = (table: Table): JsonDropTableStatement => { type: 'drop_table', tableName: table.name, schema: table.schema, + policies: table.policies ? Object.values(table.policies) : [], }; }; @@ -990,6 +1121,56 @@ export const prepareRenameSequenceJson = ( //////////// +export const prepareCreateRoleJson = ( + role: Role, +): JsonCreateRoleStatement => { + return { + type: 'create_role', + name: role.name, + values: { + createDb: role.createDb, + createRole: role.createRole, + inherit: role.inherit, + }, + }; +}; + +export const prepareAlterRoleJson = ( + role: Role, +): JsonAlterRoleStatement => { + return { + type: 'alter_role', + name: role.name, + values: { + createDb: role.createDb, + createRole: role.createRole, + inherit: role.inherit, + }, + }; +}; + +export const prepareDropRoleJson = ( + name: string, +): JsonDropRoleStatement => { + return { + type: 'drop_role', + name: name, + }; +}; + +export const prepareRenameRoleJson = ( + nameFrom: string, + nameTo: string, +): JsonRenameRoleStatement => { + return { + type: 'rename_role', + nameFrom, + nameTo, + }; +}; + +////////// + export const prepareCreateSchemasJson = ( values: string[], ): JsonCreateSchema[] => { @@ -2128,6 +2309,121 @@ export const prepareSqliteAlterColumns = ( return [...dropPkStatements, ...setPkStatements, ...statements]; }; +export const prepareRenamePolicyJsons = ( + tableName: string, + schema: string, + renames: { + from: Policy; + to: Policy; + }[], +): JsonRenamePolicyStatement[] => { + return renames.map((it) => { + return { + type: 'rename_policy', + tableName: tableName, + oldName: it.from.name, + newName: it.to.name, + schema, + }; + }); +}; + +export const prepareRenameIndPolicyJsons = ( + renames: { + from: Policy; + to: Policy; + }[], +): JsonIndRenamePolicyStatement[] => { + return renames.map((it) => { + return { + type: 'rename_ind_policy', + tableKey: it.from.on!, + oldName: it.from.name, + newName: it.to.name, + }; + }); +}; + +export const prepareCreatePolicyJsons = ( + tableName: string, + schema: string, + policies: Policy[], +): JsonCreatePolicyStatement[] => { + return policies.map((it) => { + return { + type: 'create_policy', + tableName, + data: it, + schema, + }; + }); +}; + +export const prepareCreateIndPolicyJsons = ( + policies: Policy[], +): JsonCreateIndPolicyStatement[] => { + return policies.map((it) => { + return { + type: 'create_ind_policy', + tableName: it.on!, + data: it, + }; + }); +}; + +export const prepareDropPolicyJsons = ( + tableName: string, + schema: string, + policies: Policy[], +): JsonDropPolicyStatement[] => { + return policies.map((it) => { + return { + type: 'drop_policy', + tableName, + data: it, + schema, + }; + }); +}; + +export const prepareDropIndPolicyJsons = ( + policies: Policy[], +): JsonDropIndPolicyStatement[] => { + return policies.map((it) => { + return { + type: 'drop_ind_policy', + tableName: it.on!, + data: it, + }; + }); +}; + +export const prepareAlterPolicyJson = ( + tableName: string, + schema: string, + oldPolicy: string, + newPolicy: string, +): JsonAlterPolicyStatement => { + return { + type: 'alter_policy', + tableName, + oldData: oldPolicy, + newData: newPolicy, + schema, + }; +}; + +export const prepareAlterIndPolicyJson = ( + oldPolicy: Policy, + newPolicy: Policy, +): JsonAlterIndPolicyStatement => { + return { + type: 'alter_ind_policy', + oldData: oldPolicy, + newData: newPolicy, + }; +}; + export const preparePgCreateIndexesJson = ( tableName: string, schema: string, diff --git a/drizzle-kit/src/serializer/index.ts b/drizzle-kit/src/serializer/index.ts index 05e4a6f37..cf2ee625a 100644 --- a/drizzle-kit/src/serializer/index.ts +++ b/drizzle-kit/src/serializer/index.ts @@ -1,6 +1,4 @@ import chalk from 'chalk'; -import { SQL, Table } from 'drizzle-orm'; -import { CasingCache } from 'drizzle-orm/casing'; import fs from 'fs'; import * as glob from 'glob'; import Path from 'path'; @@ -10,36 +8,6 @@ import type { MySqlSchemaInternal } from './mysqlSchema'; import type { PgSchemaInternal } from './pgSchema'; import type { SQLiteSchemaInternal } from './sqliteSchema'; -export const sqlToStr = (sql: SQL, casing: CasingType | undefined) => { - return sql.toQuery({ - escapeName: () => { - throw new Error("we don't support params for `sql` default values"); - }, - escapeParam: () => { - throw new Error("we don't support params for `sql` default values"); - }, - escapeString: () => { - throw new Error("we don't support params for `sql` default values"); - }, - casing: new CasingCache(casing), - }).sql; -}; - -export const sqlToStrGenerated = (sql: SQL, casing: CasingType | undefined) => { - return sql.toQuery({ - escapeName: () => { - throw new Error("we don't support params for `sql` default values"); - }, - escapeParam: () => { - throw new Error("we don't support params for `sql` default values"); - }, - escapeString: () => { - throw new Error("we don't support params for `sql` default values"); - }, - casing: new CasingCache(casing), - }).sql; -}; - export const serializeMySql = async ( path: string | string[], casing: CasingType | undefined, @@ -66,11 +34,11 @@ export const serializePg = async ( const { prepareFromPgImports } = await import('./pgImports'); const { generatePgSnapshot } = await import('./pgSerializer'); - const { tables, enums, schemas, sequences, views, matViews } = await prepareFromPgImports( + const { tables, enums, schemas, sequences, views, matViews, roles, policies } = await prepareFromPgImports( filenames, ); - return generatePgSnapshot(tables, enums, schemas, sequences, views, matViews, casing, schemaFilter); + return generatePgSnapshot(tables, enums, schemas, sequences, roles, policies, views, matViews, casing, schemaFilter); }; export const serializeSQLite = async ( diff --git a/drizzle-kit/src/serializer/mysqlSerializer.ts b/drizzle-kit/src/serializer/mysqlSerializer.ts index 5ac717525..f7fa7f3f0 100644 --- a/drizzle-kit/src/serializer/mysqlSerializer.ts +++ b/drizzle-kit/src/serializer/mysqlSerializer.ts @@ -1,9 +1,15 @@ import chalk from 'chalk'; -import { getTableName, is } from 'drizzle-orm'; -import { SQL } from 'drizzle-orm'; -import { getViewConfig, MySqlColumn, MySqlView } from 'drizzle-orm/mysql-core'; -import { AnyMySqlTable, MySqlDialect, type PrimaryKey as PrimaryKeyORM, uniqueKeyName } from 'drizzle-orm/mysql-core'; -import { getTableConfig } from 'drizzle-orm/mysql-core'; +import { getTableName, is, SQL } from 'drizzle-orm'; +import { + AnyMySqlTable, + getTableConfig, + getViewConfig, + MySqlColumn, + MySqlDialect, + MySqlView, + type PrimaryKey as PrimaryKeyORM, + uniqueKeyName, +} from 'drizzle-orm/mysql-core'; import { RowDataPacket } from 'mysql2/promise'; import { CasingType } from 'src/cli/validations/common'; import { withStyle } from '../cli/validations/outputs'; @@ -20,8 +26,8 @@ import { UniqueConstraint, View, } from '../serializer/mysqlSchema'; -import { type DB, getColumnCasing } from '../utils'; -import { sqlToStr } from '.'; +import type { DB } from '../utils'; +import { getColumnCasing, sqlToStr } from './utils'; export const indexName = (tableName: string, columns: string[]) => { return `${tableName}_${columns.join('_')}_index`; diff --git a/drizzle-kit/src/serializer/pgImports.ts b/drizzle-kit/src/serializer/pgImports.ts index e0b3fb743..40e54616a 100644 --- a/drizzle-kit/src/serializer/pgImports.ts +++ b/drizzle-kit/src/serializer/pgImports.ts @@ -7,6 +7,8 @@ import { isPgView, PgEnum, PgMaterializedView, + PgPolicy, + PgRole, PgSchema, PgSequence, PgTable, @@ -19,6 +21,8 @@ export const prepareFromExports = (exports: Record) => { const enums: PgEnum[] = []; const schemas: PgSchema[] = []; const sequences: PgSequence[] = []; + const roles: PgRole[] = []; + const policies: PgPolicy[] = []; const views: PgView[] = []; const matViews: PgMaterializedView[] = []; @@ -47,9 +51,17 @@ export const prepareFromExports = (exports: Record) => { if (isPgSequence(t)) { sequences.push(t); } + + if (is(t, PgRole)) { + roles.push(t); + } + + if (is(t, PgPolicy)) { + policies.push(t); + } }); - return { tables, enums, schemas, sequences, views, matViews }; + return { tables, enums, schemas, sequences, views, matViews, roles, policies }; }; export const prepareFromPgImports = async (imports: string[]) => { @@ -58,6 +70,8 @@ export const prepareFromPgImports = async (imports: string[]) => { const schemas: PgSchema[] = []; const sequences: PgSequence[] = []; const views: PgView[] = []; + const roles: PgRole[] = []; + const policies: PgPolicy[] = []; const matViews: PgMaterializedView[] = []; const { unregister } = await safeRegister(); @@ -73,8 +87,10 @@ export const prepareFromPgImports = async (imports: string[]) => { sequences.push(...prepared.sequences); views.push(...prepared.views); matViews.push(...prepared.matViews); + roles.push(...prepared.roles); + policies.push(...prepared.policies); } unregister(); - return { tables: Array.from(new Set(tables)), enums, schemas, sequences, views, matViews }; + return { tables: Array.from(new Set(tables)), enums, schemas, sequences, views, matViews, roles, policies }; }; diff --git a/drizzle-kit/src/serializer/pgSchema.ts b/drizzle-kit/src/serializer/pgSchema.ts index d4d27cb86..50d712dc4 100644 --- a/drizzle-kit/src/serializer/pgSchema.ts +++ b/drizzle-kit/src/serializer/pgSchema.ts @@ -148,6 +148,13 @@ export const sequenceSchema = object({ schema: string(), }).strict(); +export const roleSchema = object({ + name: string(), + createDb: boolean().optional(), + createRole: boolean().optional(), + inherit: boolean().optional(), +}).strict(); + export const sequenceSquashed = object({ name: string(), schema: string(), @@ -225,6 +232,21 @@ const uniqueConstraint = object({ nullsNotDistinct: boolean(), }).strict(); +export const policy = object({ + name: string(), + as: enumType(['PERMISSIVE', 'RESTRICTIVE']).optional(), + for: enumType(['ALL', 'SELECT', 'INSERT', 'UPDATE', 'DELETE']).optional(), + to: string().array().optional(), + using: string().optional(), + withCheck: string().optional(), + on: string().optional(), +}).strict(); + +export const policySquashed = object({ + name: string(), + values: string(), +}).strict(); + const viewWithOption = object({ checkOption: enumType(['local', 'cascaded']).optional(), securityBarrier: boolean().optional(), @@ -313,7 +335,9 @@ const table = object({ foreignKeys: record(string(), fk), compositePrimaryKeys: record(string(), compositePK), uniqueConstraints: record(string(), uniqueConstraint).default({}), + policies: record(string(), policy).default({}), checkConstraints: record(string(), checkConstraint).default({}), + isRLSEnabled: boolean().default(false), }).strict(); const schemaHash = object({ @@ -418,6 +442,8 @@ export const pgSchemaInternal = object({ schemas: record(string(), string()), views: record(string(), view).default({}), sequences: record(string(), sequenceSchema).default({}), + roles: record(string(), roleSchema).default({}), + policies: record(string(), policy).default({}), _meta: object({ schemas: record(string(), string()), tables: record(string(), string()), @@ -434,7 +460,9 @@ const tableSquashed = object({ foreignKeys: record(string(), string()), compositePrimaryKeys: record(string(), string()), uniqueConstraints: record(string(), string()), + policies: record(string(), string()), checkConstraints: record(string(), string()), + isRLSEnabled: boolean().default(false), }).strict(); const tableSquashedV4 = object({ @@ -469,6 +497,8 @@ export const pgSchemaSquashed = object({ schemas: record(string(), string()), views: record(string(), view), sequences: record(string(), sequenceSquashed), + roles: record(string(), roleSchema).default({}), + policies: record(string(), policySquashed).default({}), }).strict(); export const pgSchemaV3 = pgSchemaInternalV3.merge(schemaHash); @@ -480,6 +510,7 @@ export const pgSchema = pgSchemaInternal.merge(schemaHash); export type Enum = TypeOf; export type Sequence = TypeOf; +export type Role = TypeOf; export type Column = TypeOf; export type TableV3 = TypeOf; export type TableV4 = TypeOf; @@ -496,6 +527,7 @@ export type Index = TypeOf; export type ForeignKey = TypeOf; export type PrimaryKey = TypeOf; export type UniqueConstraint = TypeOf; +export type Policy = TypeOf; export type View = TypeOf; export type MatViewWithOption = TypeOf; export type ViewWithOption = TypeOf; @@ -605,6 +637,26 @@ export const PgSquasher = { fk.onUpdate ?? '' };${fk.onDelete ?? ''};${fk.schemaTo || 'public'}`; }, + squashPolicy: (policy: Policy) => { + return `${policy.name}--${policy.as}--${policy.for}--${ + policy.to?.join(',') + }--${policy.using}--${policy.withCheck}--${policy.on}`; + }, + unsquashPolicy: (policy: string): Policy => { + const splitted = policy.split('--'); + return { + name: splitted[0], + as: splitted[1] as Policy['as'], + for: splitted[2] as Policy['for'], + to: splitted[3].split(','), + using: splitted[4] !== 'undefined' ? splitted[4] : undefined, + withCheck: splitted[5] !== 'undefined' ? splitted[5] : undefined, + on: splitted[6] !== 'undefined' ? splitted[6] : undefined, + }; + }, + squashPolicyPush: (policy: Policy) => { + return `${policy.name}--${policy.as}--${policy.for}--${policy.to?.join(',')}--${policy.on}`; + }, squashPK: (pk: PrimaryKey) => { return `${pk.columns.join(',')};${pk.name}`; }, @@ -738,6 +790,11 @@ export const squashPgScheme = ( }, ); + const squashedPolicies = mapValues(it[1].policies, (policy) => { + return action === 'push' + ? PgSquasher.squashPolicyPush(policy) + : PgSquasher.squashPolicy(policy); + }); const squashedChecksContraints = mapValues( it[1].checkConstraints, (check) => { @@ -755,7 +812,9 @@ export const squashPgScheme = ( foreignKeys: squashedFKs, compositePrimaryKeys: squashedPKs, uniqueConstraints: squashedUniqueConstraints, + policies: squashedPolicies, checkConstraints: squashedChecksContraints, + isRLSEnabled: it[1].isRLSEnabled ?? false, }, ]; }), @@ -774,6 +833,20 @@ export const squashPgScheme = ( }), ); + const mappedPolicies = Object.fromEntries( + Object.entries(json.policies).map((it) => { + return [ + it[0], + { + name: it[1].name, + values: action === 'push' + ? PgSquasher.squashPolicyPush(it[1]) + : PgSquasher.squashPolicy(it[1]), + }, + ]; + }), + ); + return { version: '7', dialect: json.dialect, @@ -781,7 +854,9 @@ export const squashPgScheme = ( enums: json.enums, schemas: json.schemas, views: json.views, + policies: mappedPolicies, sequences: mappedSequences, + roles: json.roles, }; }; @@ -793,6 +868,8 @@ export const dryPg = pgSchema.parse({ tables: {}, enums: {}, schemas: {}, + policies: {}, + roles: {}, sequences: {}, _meta: { schemas: {}, diff --git a/drizzle-kit/src/serializer/pgSerializer.ts b/drizzle-kit/src/serializer/pgSerializer.ts index 3c54b01f4..c6f6c0391 100644 --- a/drizzle-kit/src/serializer/pgSerializer.ts +++ b/drizzle-kit/src/serializer/pgSerializer.ts @@ -1,10 +1,9 @@ import chalk from 'chalk'; import { getTableName, is, SQL } from 'drizzle-orm'; -import { toCamelCase, toSnakeCase } from 'drizzle-orm/casing'; import { AnyPgTable, - ExtraConfigColumn, getMaterializedViewConfig, + getTableConfig, getViewConfig, IndexedColumn, PgColumn, @@ -12,33 +11,36 @@ import { PgEnum, PgEnumColumn, PgMaterializedView, + PgPolicy, + PgRole, PgSchema, PgSequence, PgView, uniqueKeyName, } from 'drizzle-orm/pg-core'; -import { getTableConfig } from 'drizzle-orm/pg-core'; import { CasingType } from 'src/cli/validations/common'; import { vectorOps } from 'src/extensions/vector'; import { withStyle } from '../cli/validations/outputs'; import type { IntrospectStage, IntrospectStatus } from '../cli/views'; import type { CheckConstraint, - Column as Column, + Column, Enum, ForeignKey, Index, IndexColumnType, PgKitInternals, PgSchemaInternal, + Policy, PrimaryKey, + Role, Sequence, Table, UniqueConstraint, View, } from '../serializer/pgSchema'; -import { type DB, getColumnCasing, isPgArrayType } from '../utils'; -import { sqlToStr } from '.'; +import { type DB, isPgArrayType } from '../utils'; +import { getColumnCasing, sqlToStr } from './utils'; export const indexName = (tableName: string, columns: string[]) => { return `${tableName}_${columns.join('_')}_index`; @@ -53,7 +55,7 @@ function maxRangeForIdentityBasedOn(columnType: string) { } function minRangeForIdentityBasedOn(columnType: string) { - return columnType === 'integer' ? '-2147483648' : columnType === 'bitint' ? '-9223372036854775808' : '-32768'; + return columnType === 'integer' ? '-2147483648' : columnType === 'bigint' ? '-9223372036854775808' : '-32768'; } function stringFromDatabaseIdentityProperty(field: any): string | undefined { @@ -66,7 +68,7 @@ function stringFromDatabaseIdentityProperty(field: any): string | undefined { : String(field); } -function buildArrayString(array: any[], sqlType: string): string { +export function buildArrayString(array: any[], sqlType: string): string { sqlType = sqlType.split('[')[0]; const values = array .map((value) => { @@ -100,6 +102,8 @@ export const generatePgSnapshot = ( enums: PgEnum[], schemas: PgSchema[], sequences: PgSequence[], + roles: PgRole[], + policies: PgPolicy[], views: PgView[], matViews: PgMaterializedView[], casing: CasingType | undefined, @@ -109,9 +113,13 @@ export const generatePgSnapshot = ( const result: Record = {}; const resultViews: Record = {}; const sequencesToReturn: Record = {}; + const rolesToReturn: Record = {}; + // this policies are a separate objects that were linked to a table outside of it + const policiesToReturn: Record = {}; // This object stores unique names for indexes and will be used to detect if you have the same names for indexes // within the same PostgreSQL schema + const indexesInSchema: Record = {}; for (const table of tables) { @@ -119,8 +127,18 @@ export const generatePgSnapshot = ( // within the same PostgreSQL table const checksInTable: Record = {}; - const { name: tableName, columns, indexes, foreignKeys, checks, schema, primaryKeys, uniqueConstraints } = - getTableConfig(table); + const { + name: tableName, + columns, + indexes, + foreignKeys, + checks, + schema, + primaryKeys, + uniqueConstraints, + policies, + enableRLS, + } = getTableConfig(table); if (schemaFilter && !schemaFilter.includes(schema ?? 'public')) { continue; @@ -132,6 +150,7 @@ export const generatePgSnapshot = ( const foreignKeysObject: Record = {}; const primaryKeysObject: Record = {}; const uniqueConstraintObject: Record = {}; + const policiesObject: Record = {}; columns.forEach((column) => { const name = getColumnCasing(column, casing); @@ -459,6 +478,54 @@ export const generatePgSnapshot = ( }; }); + policies.forEach((policy) => { + const mappedTo = []; + + if (!policy.to) { + mappedTo.push('public'); + } else { + if (policy.to && typeof policy.to === 'string') { + mappedTo.push(policy.to); + } else if (policy.to && is(policy.to, PgRole)) { + mappedTo.push(policy.to.name); + } else if (policy.to && Array.isArray(policy.to)) { + policy.to.forEach((it) => { + if (typeof it === 'string') { + mappedTo.push(it); + } else if (is(it, PgRole)) { + mappedTo.push(it.name); + } + }); + } + } + + if (policiesObject[policy.name] !== undefined) { + console.log( + `\n${ + withStyle.errorWarning( + `We\'ve found duplicated policy name across ${ + chalk.underline.blue(tableKey) + } table. Please rename one of the policies with ${ + chalk.underline.blue( + policy.name, + ) + } name`, + ) + }`, + ); + process.exit(1); + } + + policiesObject[policy.name] = { + name: policy.name, + as: policy.as?.toUpperCase() as Policy['as'] ?? 'PERMISSIVE', + for: policy.for?.toUpperCase() as Policy['for'] ?? 'ALL', + to: mappedTo.sort(), + using: is(policy.using, SQL) ? dialect.sqlToQuery(policy.using).sql : undefined, + withCheck: is(policy.withCheck, SQL) ? dialect.sqlToQuery(policy.withCheck).sql : undefined, + }; + }); + checks.forEach((check) => { const checkName = check.name; @@ -506,8 +573,88 @@ export const generatePgSnapshot = ( foreignKeys: foreignKeysObject, compositePrimaryKeys: primaryKeysObject, uniqueConstraints: uniqueConstraintObject, + policies: policiesObject, checkConstraints: checksObject, + isRLSEnabled: enableRLS, + }; + } + + for (const policy of policies) { + // @ts-ignore + if (!policy._linkedTable) { + console.log( + `\n${ + withStyle.errorWarning( + `"Policy ${policy.name} was skipped because it was not linked to any table. You should either include the policy in a table or use .link() on the policy to link it to any table you have. For more information, please check:`, + ) + }`, + ); + continue; + } + + // @ts-ignore + const tableConfig = getTableConfig(policy._linkedTable); + + const tableKey = `${tableConfig.schema ?? 'public'}.${tableConfig.name}`; + + const mappedTo = []; + + if (!policy.to) { + mappedTo.push('public'); + } else { + if (policy.to && typeof policy.to === 'string') { + mappedTo.push(policy.to); + } else if (policy.to && is(policy.to, PgRole)) { + mappedTo.push(policy.to.name); + } else if (policy.to && Array.isArray(policy.to)) { + policy.to.forEach((it) => { + if (typeof it === 'string') { + mappedTo.push(it); + } else if (is(it, PgRole)) { + mappedTo.push(it.name); + } + }); + } + } + + // add separate policies object, that will be only responsible for policy creation + // but we would need to track if a policy was enabled for a specific table or not + // enable only if jsonStatements for enable rls was not already there + filter it + + if (result[tableKey]?.policies[policy.name] !== undefined || policiesToReturn[policy.name] !== undefined) { + console.log( + `\n${ + withStyle.errorWarning( + `We\'ve found duplicated policy name across ${ + chalk.underline.blue(tableKey) + } table. Please rename one of the policies with ${ + chalk.underline.blue( + policy.name, + ) + } name`, + ) + }`, + ); + process.exit(1); + } + + const mappedPolicy = { + name: policy.name, + as: policy.as?.toUpperCase() as Policy['as'] ?? 'PERMISSIVE', + for: policy.for?.toUpperCase() as Policy['for'] ?? 'ALL', + to: mappedTo.sort(), + using: is(policy.using, SQL) ? dialect.sqlToQuery(policy.using).sql : undefined, + withCheck: is(policy.withCheck, SQL) ? dialect.sqlToQuery(policy.withCheck).sql : undefined, }; + + if (result[tableKey]) { + result[tableKey].policies[policy.name] = mappedPolicy; + } else { + policiesToReturn[policy.name] = { + ...mappedPolicy, + on: `"${tableConfig.schema ?? 'public'}"."${tableConfig.name}"`, + }; + } } for (const sequence of sequences) { @@ -537,6 +684,16 @@ export const generatePgSnapshot = ( } } + for (const role of roles) { + if (!(role as any)._existing) { + rolesToReturn[role.name] = { + name: role.name, + createDb: (role as any).createDb === undefined ? false : (role as any).createDb, + createRole: (role as any).createRole === undefined ? false : (role as any).createRole, + inherit: (role as any).inherit === undefined ? true : (role as any).inherit, + }; + } + } const combinedViews = [...views, ...matViews]; for (const view of combinedViews) { let viewName; @@ -735,6 +892,8 @@ export const generatePgSnapshot = ( enums: enumsToReturn, schemas: schemasObject, sequences: sequencesToReturn, + roles: rolesToReturn, + policies: policiesToReturn, views: resultViews, _meta: { schemas: {}, @@ -755,11 +914,64 @@ const trimChar = (str: string, char: string) => { return start > 0 || end < str.length ? str.substring(start, end) : str.toString(); }; +function prepareRoles(entities?: { + roles: boolean | { + provider?: string | undefined; + include?: string[] | undefined; + exclude?: string[] | undefined; + }; +}) { + let useRoles: boolean = false; + const includeRoles: string[] = []; + const excludeRoles: string[] = []; + + if (entities && entities.roles) { + if (typeof entities.roles === 'object') { + if (entities.roles.provider) { + if (entities.roles.provider === 'supabase') { + excludeRoles.push(...[ + 'anon', + 'authenticator', + 'authenticated', + 'service_role', + 'supabase_auth_admin', + 'supabase_storage_admin', + 'dashboard_user', + 'supabase_admin', + ]); + } else if (entities.roles.provider === 'neon') { + excludeRoles.push(...['authenticated', 'anonymous']); + } + } + if (entities.roles.include) { + includeRoles.push(...entities.roles.include); + } + if (entities.roles.exclude) { + excludeRoles.push(...entities.roles.exclude); + } + } else { + useRoles = entities.roles; + } + } + return { useRoles, includeRoles, excludeRoles }; +} + export const fromDatabase = async ( db: DB, tablesFilter: (table: string) => boolean = () => true, schemaFilters: string[], - progressCallback?: (stage: IntrospectStage, count: number, status: IntrospectStatus) => void, + entities?: { + roles: boolean | { + provider?: string | undefined; + include?: string[] | undefined; + exclude?: string[] | undefined; + }; + }, + progressCallback?: ( + stage: IntrospectStage, + count: number, + status: IntrospectStatus, + ) => void, ): Promise => { const result: Record = {}; const views: Record = {}; @@ -767,7 +979,7 @@ export const fromDatabase = async ( const where = schemaFilters.map((t) => `n.nspname = '${t}'`).join(' or '); - const allTables = await db.query<{ table_schema: string; table_name: string; type: string }>( + const allTables = await db.query<{ table_schema: string; table_name: string; type: string; rls_enabled: boolean }>( `SELECT n.nspname AS table_schema, c.relname AS table_name, @@ -775,7 +987,8 @@ export const fromDatabase = async ( WHEN c.relkind = 'r' THEN 'table' WHEN c.relkind = 'v' THEN 'view' WHEN c.relkind = 'm' THEN 'materialized_view' - END AS type + END AS type, + c.relrowsecurity AS rls_enabled FROM pg_catalog.pg_class c JOIN @@ -880,6 +1093,96 @@ WHERE progressCallback('enums', Object.keys(enumsToReturn).length, 'done'); } + const allRoles = await db.query< + { rolname: string; rolinherit: boolean; rolcreatedb: boolean; rolcreaterole: boolean } + >( + `SELECT rolname, rolinherit, rolcreatedb, rolcreaterole FROM pg_roles;`, + ); + + const rolesToReturn: Record = {}; + + const preparedRoles = prepareRoles(entities); + + if ( + preparedRoles.useRoles || !(preparedRoles.includeRoles.length === 0 && preparedRoles.excludeRoles.length === 0) + ) { + for (const dbRole of allRoles) { + if ( + preparedRoles.useRoles + ) { + rolesToReturn[dbRole.rolname] = { + createDb: dbRole.rolcreatedb, + createRole: dbRole.rolcreatedb, + inherit: dbRole.rolinherit, + name: dbRole.rolname, + }; + } else { + if (preparedRoles.includeRoles.length === 0 && preparedRoles.excludeRoles.length === 0) continue; + if ( + preparedRoles.includeRoles.includes(dbRole.rolname) && preparedRoles.excludeRoles.includes(dbRole.rolname) + ) continue; + if (preparedRoles.excludeRoles.includes(dbRole.rolname)) continue; + if (!preparedRoles.includeRoles.includes(dbRole.rolname)) continue; + + rolesToReturn[dbRole.rolname] = { + createDb: dbRole.rolcreatedb, + createRole: dbRole.rolcreaterole, + inherit: dbRole.rolinherit, + name: dbRole.rolname, + }; + } + } + } + + const wherePolicies = schemaFilters + .map((t) => `schemaname = '${t}'`) + .join(' or '); + + const policiesByTable: Record> = {}; + + const allPolicies = await db.query< + { + schemaname: string; + tablename: string; + name: string; + as: string; + to: string; + for: string; + using: string; + withCheck: string; + } + >(`SELECT schemaname, tablename, policyname as name, permissive as "as", roles as to, cmd as for, qual as using, with_check as "withCheck" FROM pg_policies${ + wherePolicies === '' ? '' : ` WHERE ${wherePolicies}` + };`); + + for (const dbPolicy of allPolicies) { + const { tablename, schemaname, to, withCheck, using, ...rest } = dbPolicy; + const tableForPolicy = policiesByTable[`${schemaname}.${tablename}`]; + + const parsedTo = typeof to === 'string' ? to.slice(1, -1).split(',') : to; + + const parsedWithCheck = withCheck === null ? undefined : withCheck; + const parsedUsing = using === null ? undefined : using; + + if (tableForPolicy) { + tableForPolicy[dbPolicy.name] = { ...rest, to: parsedTo } as Policy; + } else { + policiesByTable[`${schemaname}.${tablename}`] = { + [dbPolicy.name]: { ...rest, to: parsedTo, withCheck: parsedWithCheck, using: parsedUsing } as Policy, + }; + } + } + + if (progressCallback) { + progressCallback( + 'policies', + Object.values(policiesByTable).reduce((total, innerRecord) => { + return total + Object.keys(innerRecord).length; + }, 0), + 'done', + ); + } + const sequencesInColumns: string[] = []; const all = allTables @@ -1317,7 +1620,7 @@ WHERE }, ], isUnique: indexIsUnique, - // should not be a part of diff detecs + // should not be a part of diff detects concurrently: false, method: indexMethod, where: indexWhere === null ? undefined : indexWhere, @@ -1339,6 +1642,8 @@ WHERE compositePrimaryKeys: primaryKeys, uniqueConstraints: uniqueConstrains, checkConstraints: checkConstraints, + policies: policiesByTable[`${tableSchema}.${tableName}`] ?? {}, + isRLSEnabled: row.rls_enabled, }; } catch (e) { rej(e); @@ -1601,6 +1906,8 @@ WHERE enums: enumsToReturn, schemas: schemasObject, sequences: sequencesToReturn, + roles: rolesToReturn, + policies: {}, views: views, _meta: { schemas: {}, diff --git a/drizzle-kit/src/serializer/sqliteSerializer.ts b/drizzle-kit/src/serializer/sqliteSerializer.ts index 3977705a6..1ba24b69c 100644 --- a/drizzle-kit/src/serializer/sqliteSerializer.ts +++ b/drizzle-kit/src/serializer/sqliteSerializer.ts @@ -1,8 +1,6 @@ import chalk from 'chalk'; import { getTableName, is, SQL } from 'drizzle-orm'; -import { toCamelCase, toSnakeCase } from 'drizzle-orm/casing'; import { - // AnySQLiteColumnBuilder, AnySQLiteTable, getTableConfig, getViewConfig, @@ -27,8 +25,8 @@ import type { UniqueConstraint, View, } from '../serializer/sqliteSchema'; -import { getColumnCasing, type SQLiteDB } from '../utils'; -import { sqlToStr } from '.'; +import type { SQLiteDB } from '../utils'; +import { getColumnCasing, sqlToStr } from './utils'; export const generateSqliteSnapshot = ( tables: AnySQLiteTable[], diff --git a/drizzle-kit/src/serializer/studio.ts b/drizzle-kit/src/serializer/studio.ts index e83bd21a2..d83a65b08 100644 --- a/drizzle-kit/src/serializer/studio.ts +++ b/drizzle-kit/src/serializer/studio.ts @@ -18,6 +18,7 @@ import { AnyPgTable, getTableConfig as pgTableConfig, PgTable } from 'drizzle-or import { AnySQLiteTable, getTableConfig as sqliteTableConfig, SQLiteTable } from 'drizzle-orm/sqlite-core'; import fs from 'fs'; import { Hono } from 'hono'; +import { compress } from 'hono/compress'; import { cors } from 'hono/cors'; import { createServer } from 'node:https'; import { LibSQLCredentials } from 'src/cli/validations/libsql'; @@ -492,12 +493,14 @@ export const prepareServer = async ( ): Promise => { app = app !== undefined ? app : new Hono(); - app.use(cors()); + app.use(compress()); app.use(async (ctx, next) => { await next(); // * https://wicg.github.io/private-network-access/#headers + // * https://github.com/drizzle-team/drizzle-orm/issues/1857#issuecomment-2395724232 ctx.header('Access-Control-Allow-Private-Network', 'true'); }); + app.use(cors()); app.onError((err, ctx) => { console.error(err); return ctx.json({ diff --git a/drizzle-kit/src/serializer/utils.ts b/drizzle-kit/src/serializer/utils.ts new file mode 100644 index 000000000..18d5bb9ad --- /dev/null +++ b/drizzle-kit/src/serializer/utils.ts @@ -0,0 +1,45 @@ +import { SQL } from 'drizzle-orm'; +import { CasingCache, toCamelCase, toSnakeCase } from 'drizzle-orm/casing'; +import { CasingType } from '../cli/validations/common'; + +export function getColumnCasing( + column: { keyAsName: boolean; name: string | undefined }, + casing: CasingType | undefined, +) { + if (!column.name) return ''; + return !column.keyAsName || casing === undefined + ? column.name + : casing === 'camelCase' + ? toCamelCase(column.name) + : toSnakeCase(column.name); +} + +export const sqlToStr = (sql: SQL, casing: CasingType | undefined) => { + return sql.toQuery({ + escapeName: () => { + throw new Error("we don't support params for `sql` default values"); + }, + escapeParam: () => { + throw new Error("we don't support params for `sql` default values"); + }, + escapeString: () => { + throw new Error("we don't support params for `sql` default values"); + }, + casing: new CasingCache(casing), + }).sql; +}; + +export const sqlToStrGenerated = (sql: SQL, casing: CasingType | undefined) => { + return sql.toQuery({ + escapeName: () => { + throw new Error("we don't support params for `sql` default values"); + }, + escapeParam: () => { + throw new Error("we don't support params for `sql` default values"); + }, + escapeString: () => { + throw new Error("we don't support params for `sql` default values"); + }, + casing: new CasingCache(casing), + }).sql; +}; diff --git a/drizzle-kit/src/snapshotsDiffer.ts b/drizzle-kit/src/snapshotsDiffer.ts index bae4c100a..f50ae5f6c 100644 --- a/drizzle-kit/src/snapshotsDiffer.ts +++ b/drizzle-kit/src/snapshotsDiffer.ts @@ -12,7 +12,7 @@ import { union, ZodTypeAny, } from 'zod'; -import { applyJsonDiff, diffColumns, diffSchemasOrTables } from './jsonDiffer'; +import { applyJsonDiff, diffColumns, diffIndPolicies, diffPolicies, diffSchemasOrTables } from './jsonDiffer'; import { fromJson } from './sqlgenerator'; import { @@ -21,24 +21,35 @@ import { _prepareSqliteAddColumns, JsonAddColumnStatement, JsonAlterCompositePK, + JsonAlterIndPolicyStatement, JsonAlterMySqlViewStatement, + JsonAlterPolicyStatement, JsonAlterTableSetSchema, JsonAlterUniqueConstraint, JsonAlterViewStatement, JsonCreateCheckConstraint, JsonCreateCompositePK, + JsonCreateIndPolicyStatement, JsonCreateMySqlViewStatement, JsonCreatePgViewStatement, + JsonCreatePolicyStatement, JsonCreateReferenceStatement, JsonCreateSqliteViewStatement, JsonCreateUniqueConstraint, JsonDeleteCheckConstraint, JsonDeleteCompositePK, JsonDeleteUniqueConstraint, + JsonDisableRLSStatement, JsonDropColumnStatement, + JsonDropIndPolicyStatement, + JsonDropPolicyStatement, JsonDropViewStatement, + JsonEnableRLSStatement, + JsonIndRenamePolicyStatement, JsonReferenceStatement, JsonRenameColumnStatement, + JsonRenamePolicyStatement, + JsonRenameRoleStatement, JsonRenameViewStatement, JsonSqliteAddColumnStatement, JsonStatement, @@ -52,11 +63,17 @@ import { prepareAlterCompositePrimaryKeyMySql, prepareAlterCompositePrimaryKeyPg, prepareAlterCompositePrimaryKeySqlite, + prepareAlterIndPolicyJson, + prepareAlterPolicyJson, prepareAlterReferencesJson, + prepareAlterRoleJson, prepareAlterSequenceJson, prepareCreateEnumJson, prepareCreateIndexesJson, + prepareCreateIndPolicyJsons, + prepareCreatePolicyJsons, prepareCreateReferencesJson, + prepareCreateRoleJson, prepareCreateSchemasJson, prepareCreateSequenceJson, prepareDeleteCheckConstraint, @@ -68,7 +85,10 @@ import { prepareDropEnumJson, prepareDropEnumValues, prepareDropIndexesJson, + prepareDropIndPolicyJsons, + prepareDropPolicyJsons, prepareDropReferencesJson, + prepareDropRoleJson, prepareDropSequenceJson, prepareDropTableJson, prepareDropViewJson, @@ -90,6 +110,9 @@ import { preparePgCreateViewJson, prepareRenameColumns, prepareRenameEnumJson, + prepareRenameIndPolicyJsons, + prepareRenamePolicyJsons, + prepareRenameRoleJson, prepareRenameSchemasJson, prepareRenameSequenceJson, prepareRenameTableJson, @@ -102,7 +125,19 @@ import { import { Named, NamedWithSchema } from './cli/commands/migrate'; import { mapEntries, mapKeys, mapValues } from './global'; import { MySqlSchema, MySqlSchemaSquashed, MySqlSquasher, ViewSquashed } from './serializer/mysqlSchema'; -import { mergedViewWithOption, PgSchema, PgSchemaSquashed, sequenceSquashed, View } from './serializer/pgSchema'; +import { + mergedViewWithOption, + PgSchema, + PgSchemaSquashed, + PgSquasher, + Policy, + policy, + policySquashed, + Role, + roleSchema, + sequenceSquashed, + View, +} from './serializer/pgSchema'; import { SQLiteSchema, SQLiteSchemaSquashed, SQLiteSquasher, View as SqliteView } from './serializer/sqliteSchema'; import { libSQLCombineStatements, sqliteCombineStatements } from './statementCombiner'; import { copy, prepareMigrationMeta } from './utils'; @@ -229,7 +264,9 @@ const tableScheme = object({ foreignKeys: record(string(), string()), compositePrimaryKeys: record(string(), string()).default({}), uniqueConstraints: record(string(), string()).default({}), + policies: record(string(), string()).default({}), checkConstraints: record(string(), string()).default({}), + isRLSEnabled: boolean().default(false), }).strict(); export const alteredTableScheme = object({ @@ -272,6 +309,15 @@ export const alteredTableScheme = object({ __old: string(), }), ), + addedPolicies: record(string(), string()), + deletedPolicies: record(string(), string()), + alteredPolicies: record( + string(), + object({ + __new: string(), + __old: string(), + }), + ), addedCheckConstraints: record( string(), string(), @@ -337,6 +383,8 @@ export const diffResultScheme = object({ alteredTablesWithColumns: alteredTableScheme.array(), alteredEnums: changedEnumSchema.array(), alteredSequences: sequenceSquashed.array(), + alteredRoles: roleSchema.array(), + alteredPolicies: policySquashed.array(), alteredViews: alteredPgViewSchema.array(), }).strict(); @@ -387,6 +435,43 @@ export interface ColumnsResolverInput { deleted: T[]; } +export interface TablePolicyResolverInput { + tableName: string; + schema: string; + created: T[]; + deleted: T[]; +} + +export interface TablePolicyResolverOutput { + tableName: string; + schema: string; + created: T[]; + renamed: { from: T; to: T }[]; + deleted: T[]; +} + +export interface PolicyResolverInput { + created: T[]; + deleted: T[]; +} + +export interface PolicyResolverOutput { + created: T[]; + renamed: { from: T; to: T }[]; + deleted: T[]; +} + +export interface RolesResolverInput { + created: T[]; + deleted: T[]; +} + +export interface RolesResolverOutput { + created: T[]; + renamed: { from: T; to: T }[]; + deleted: T[]; +} + export interface ColumnsResolverOutput { tableName: string; schema: string; @@ -457,6 +542,12 @@ const columnChangeFor = ( return column; }; +// resolve roles same as enums +// create new json statements +// sql generators + +// tests everything! + export const applyPgSnapshotsDiff = async ( json1: PgSchemaSquashed, json2: PgSchemaSquashed, @@ -469,6 +560,15 @@ export const applyPgSnapshotsDiff = async ( sequencesResolver: ( input: ResolverInput, ) => Promise>, + policyResolver: ( + input: TablePolicyResolverInput, + ) => Promise>, + indPolicyResolver: ( + input: PolicyResolverInput, + ) => Promise>, + roleResolver: ( + input: RolesResolverInput, + ) => Promise>, tablesResolver: ( input: ResolverInput, ) => Promise>, @@ -696,6 +796,60 @@ export const applyPgSnapshotsDiff = async ( }, ); + const rolesDiff = diffSchemasOrTables( + schemasPatchedSnap1.roles, + json2.roles, + ); + + const { + created: createdRoles, + deleted: deletedRoles, + renamed: renamedRoles, + } = await roleResolver({ + created: rolesDiff.added, + deleted: rolesDiff.deleted, + }); + + schemasPatchedSnap1.roles = mapEntries( + schemasPatchedSnap1.roles, + (_, it) => { + const { name } = nameChangeFor(it, renamedRoles); + it.name = name; + return [name, it]; + }, + ); + + const rolesChangeMap = renamedRoles.reduce( + (acc, it) => { + acc[it.from.name] = { + nameFrom: it.from.name, + nameTo: it.to.name, + }; + return acc; + }, + {} as Record< + string, + { + nameFrom: string; + nameTo: string; + } + >, + ); + + schemasPatchedSnap1.roles = mapEntries( + schemasPatchedSnap1.roles, + (roleKey, roleValue) => { + const key = roleKey; + const change = rolesChangeMap[key]; + + if (change) { + roleValue.name = change.nameTo; + } + + return [roleKey, roleValue]; + }, + ); + const tablesDiff = diffSchemasOrTables( schemasPatchedSnap1.tables as Record, json2.tables, @@ -808,7 +962,162 @@ export const applyPgSnapshotsDiff = async ( }, ); - const viewsDiff = diffSchemasOrTables(json1.views, json2.views); + //// Policies + + const policyRes = diffPolicies(tablesPatchedSnap1.tables, json2.tables); + + const policyRenames = [] as { + table: string; + schema: string; + renames: { from: Policy; to: Policy }[]; + }[]; + + const policyCreates = [] as { + table: string; + schema: string; + columns: Policy[]; + }[]; + + const policyDeletes = [] as { + table: string; + schema: string; + columns: Policy[]; + }[]; + + for (let entry of Object.values(policyRes)) { + const { renamed, created, deleted } = await policyResolver({ + tableName: entry.name, + schema: entry.schema, + deleted: entry.policies.deleted.map(PgSquasher.unsquashPolicy), + created: entry.policies.added.map(PgSquasher.unsquashPolicy), + }); + + if (created.length > 0) { + policyCreates.push({ + table: entry.name, + schema: entry.schema, + columns: created, + }); + } + + if (deleted.length > 0) { + policyDeletes.push({ + table: entry.name, + schema: entry.schema, + columns: deleted, + }); + } + + if (renamed.length > 0) { + policyRenames.push({ + table: entry.name, + schema: entry.schema, + renames: renamed, + }); + } + } + + const policyRenamesDict = columnRenames.reduce( + (acc, it) => { + acc[`${it.schema || 'public'}.${it.table}`] = it.renames; + return acc; + }, + {} as Record< + string, + { + from: Named; + to: Named; + }[] + >, + ); + + const policyPatchedSnap1 = copy(tablesPatchedSnap1); + policyPatchedSnap1.tables = mapEntries( + policyPatchedSnap1.tables, + (tableKey, tableValue) => { + const patchedPolicies = mapKeys( + tableValue.policies, + (policyKey, policy) => { + const rens = policyRenamesDict[ + `${tableValue.schema || 'public'}.${tableValue.name}` + ] || []; + + const newName = columnChangeFor(policyKey, rens); + const unsquashedPolicy = PgSquasher.unsquashPolicy(policy); + unsquashedPolicy.name = newName; + policy = PgSquasher.squashPolicy(unsquashedPolicy); + return newName; + }, + ); + + tableValue.policies = patchedPolicies; + return [tableKey, tableValue]; + }, + ); + + //// Individual policies + + const indPolicyRes = diffIndPolicies(policyPatchedSnap1.policies, json2.policies); + + const indPolicyCreates = [] as { + policies: Policy[]; + }[]; + + const indPolicyDeletes = [] as { + policies: Policy[]; + }[]; + + const { renamed: indPolicyRenames, created, deleted } = await indPolicyResolver({ + deleted: indPolicyRes.deleted.map((t) => PgSquasher.unsquashPolicy(t.values)), + created: indPolicyRes.added.map((t) => PgSquasher.unsquashPolicy(t.values)), + }); + + if (created.length > 0) { + indPolicyCreates.push({ + policies: created, + }); + } + + if (deleted.length > 0) { + indPolicyDeletes.push({ + policies: deleted, + }); + } + + const indPolicyRenamesDict = indPolicyRenames.reduce( + (acc, it) => { + acc[it.from.name] = { + nameFrom: it.from.name, + nameTo: it.to.name, + }; + return acc; + }, + {} as Record< + string, + { + nameFrom: string; + nameTo: string; + } + >, + ); + + const indPolicyPatchedSnap1 = copy(policyPatchedSnap1); + indPolicyPatchedSnap1.policies = mapEntries( + indPolicyPatchedSnap1.policies, + (policyKey, policyValue) => { + const key = policyKey; + const change = indPolicyRenamesDict[key]; + + if (change) { + policyValue.name = change.nameTo; + } + + return [policyKey, policyValue]; + }, + ); + + //// + const viewsDiff = diffSchemasOrTables(indPolicyPatchedSnap1.views, json2.views); const { created: createdViews, @@ -830,7 +1139,7 @@ export const applyPgSnapshotsDiff = async ( movedViewDic[`${it.schemaFrom}.${it.name}`] = { to: it.schemaTo, from: it.schemaFrom }; }); - const viewsPatchedSnap1 = copy(columnsPatchedSnap1); + const viewsPatchedSnap1 = copy(policyPatchedSnap1); viewsPatchedSnap1.views = mapEntries( viewsPatchedSnap1.views, (viewKey, viewValue) => { @@ -908,13 +1217,15 @@ export const applyPgSnapshotsDiff = async ( const jsonSetTableSchemas: JsonAlterTableSetSchema[] = []; - for (let it of movedTables) { - jsonSetTableSchemas.push({ - type: 'alter_table_set_schema', - tableName: it.name, - schemaFrom: it.schemaFrom || 'public', - schemaTo: it.schemaTo || 'public', - }); + if (movedTables) { + for (let it of movedTables) { + jsonSetTableSchemas.push({ + type: 'alter_table_set_schema', + tableName: it.name, + schemaFrom: it.schemaFrom || 'public', + schemaTo: it.schemaTo || 'public', + }); + } } const jsonDeletedCheckConstraints: JsonDeleteCheckConstraint[] = []; @@ -1072,7 +1383,214 @@ export const applyPgSnapshotsDiff = async ( }) .flat(); + const jsonCreatePoliciesStatements: JsonCreatePolicyStatement[] = []; + const jsonDropPoliciesStatements: JsonDropPolicyStatement[] = []; + const jsonAlterPoliciesStatements: JsonAlterPolicyStatement[] = []; + const jsonRenamePoliciesStatements: JsonRenamePolicyStatement[] = []; + + const jsonRenameIndPoliciesStatements: JsonIndRenamePolicyStatement[] = []; + const jsonCreateIndPoliciesStatements: JsonCreateIndPolicyStatement[] = []; + const jsonDropIndPoliciesStatements: JsonDropIndPolicyStatement[] = []; + const jsonAlterIndPoliciesStatements: JsonAlterIndPolicyStatement[] = []; + + const jsonEnableRLSStatements: JsonEnableRLSStatement[] = []; + const jsonDisableRLSStatements: JsonDisableRLSStatement[] = []; + + for (let it of indPolicyRenames) { + jsonRenameIndPoliciesStatements.push( + ...prepareRenameIndPolicyJsons([it]), + ); + } + + for (const it of indPolicyCreates) { + jsonCreateIndPoliciesStatements.push( + ...prepareCreateIndPolicyJsons( + it.policies, + ), + ); + } + + for (const it of indPolicyDeletes) { + jsonDropIndPoliciesStatements.push( + ...prepareDropIndPolicyJsons( + it.policies, + ), + ); + } + + typedResult.alteredPolicies.forEach(({ values }) => { + // return prepareAlterIndPolicyJson(json1.policies[it.name], json2.policies[it.name]); + + const policy = PgSquasher.unsquashPolicy(values); + + const newPolicy = PgSquasher.unsquashPolicy(json2.policies[policy.name].values); + const oldPolicy = PgSquasher.unsquashPolicy(json1.policies[policy.name].values); + + if (newPolicy.as !== oldPolicy.as) { + jsonDropIndPoliciesStatements.push( + ...prepareDropIndPolicyJsons( + [oldPolicy], + ), + ); + + jsonCreateIndPoliciesStatements.push( + ...prepareCreateIndPolicyJsons( + [newPolicy], + ), + ); + return; + } + + if (newPolicy.for !== oldPolicy.for) { + jsonDropIndPoliciesStatements.push( + ...prepareDropIndPolicyJsons( + [oldPolicy], + ), + ); + + jsonCreateIndPoliciesStatements.push( + ...prepareCreateIndPolicyJsons( + [newPolicy], + ), + ); + return; + } + + // alter + jsonAlterIndPoliciesStatements.push( + prepareAlterIndPolicyJson( + oldPolicy, + newPolicy, + ), + ); + }); + + for (let it of policyRenames) { + jsonRenamePoliciesStatements.push( + ...prepareRenamePolicyJsons(it.table, it.schema, it.renames), + ); + } + + for (const it of policyCreates) { + jsonCreatePoliciesStatements.push( + ...prepareCreatePolicyJsons( + it.table, + it.schema, + it.columns, + ), + ); + } + + for (const it of policyDeletes) { + jsonDropPoliciesStatements.push( + ...prepareDropPolicyJsons( + it.table, + it.schema, + it.columns, + ), + ); + } + alteredTables.forEach((it) => { + // handle policies + Object.keys(it.alteredPolicies).forEach((policyName: string) => { + const newPolicy = PgSquasher.unsquashPolicy(it.alteredPolicies[policyName].__new); + const oldPolicy = PgSquasher.unsquashPolicy(it.alteredPolicies[policyName].__old); + + if (newPolicy.as !== oldPolicy.as) { + jsonDropPoliciesStatements.push( + ...prepareDropPolicyJsons( + it.name, + it.schema, + [oldPolicy], + ), + ); + + jsonCreatePoliciesStatements.push( + ...prepareCreatePolicyJsons( + it.name, + it.schema, + [newPolicy], + ), + ); + return; + } + + if (newPolicy.for !== oldPolicy.for) { + jsonDropPoliciesStatements.push( + ...prepareDropPolicyJsons( + it.name, + it.schema, + [oldPolicy], + ), + ); + + jsonCreatePoliciesStatements.push( + ...prepareCreatePolicyJsons( + it.name, + it.schema, + [newPolicy], + ), + ); + return; + } + + // alter + jsonAlterPoliciesStatements.push( + prepareAlterPolicyJson( + it.name, + it.schema, + it.alteredPolicies[policyName].__old, + it.alteredPolicies[policyName].__new, + ), + ); + }); + + // Handle enabling and disabling RLS + for (const table of Object.values(json2.tables)) { + const policiesInCurrentState = Object.keys(table.policies); + const tableInPreviousState = + columnsPatchedSnap1.tables[`${table.schema === '' ? 'public' : table.schema}.${table.name}`]; + const policiesInPreviousState = tableInPreviousState ? Object.keys(tableInPreviousState.policies) : []; + + // const indPoliciesInCurrentState = Object.keys(table.policies); + // const indPoliciesInPreviousState = Object.keys(columnsPatchedSnap1.policies); + + if ( + (policiesInPreviousState.length === 0 && policiesInCurrentState.length > 0) && !table.isRLSEnabled + ) { + jsonEnableRLSStatements.push({ type: 'enable_rls', tableName: table.name, schema: table.schema }); + } + + if ( + (policiesInPreviousState.length > 0 && policiesInCurrentState.length === 0) && !table.isRLSEnabled + ) { + jsonDisableRLSStatements.push({ type: 'disable_rls', tableName: table.name, schema: table.schema }); + } + + // handle table.isRLSEnabled + if (table.isRLSEnabled !== tableInPreviousState.isRLSEnabled) { + if (table.isRLSEnabled) { + // was force enabled + jsonEnableRLSStatements.push({ type: 'enable_rls', tableName: table.name, schema: table.schema }); + } else if ( + !table.isRLSEnabled && policiesInCurrentState.length === 0 + ) { + // was force disabled + jsonDisableRLSStatements.push({ type: 'disable_rls', tableName: table.name, schema: table.schema }); + } + } + } + + for (const table of Object.values(columnsPatchedSnap1.tables)) { + const tableInCurrentState = json2.tables[`${table.schema === '' ? 'public' : table.schema}.${table.name}`]; + + if (tableInCurrentState === undefined && !table.isRLSEnabled) { + jsonDisableRLSStatements.push({ type: 'disable_rls', tableName: table.name, schema: table.schema }); + } + } + + // handle indexes const droppedIndexes = Object.keys(it.alteredIndexes).reduce( (current, item: string) => { current[item] = it.alteredIndexes[item].__old; @@ -1207,6 +1725,25 @@ export const applyPgSnapshotsDiff = async ( //////////// + const createRoles = createdRoles.map((it) => { + return prepareCreateRoleJson(it); + }) ?? []; + + const dropRoles = deletedRoles.map((it) => { + return prepareDropRoleJson(it.name); + }); + + const renameRoles = renamedRoles.map((it) => { + return prepareRenameRoleJson(it.from.name, it.to.name); + }); + + const jsonAlterRoles = typedResult.alteredRoles + .map((it) => { + return prepareAlterRoleJson(it); + }) + .flat() ?? []; + + //////////// const createSchemas = prepareCreateSchemasJson( createdSchemas.map((it) => it.name), ); @@ -1223,6 +1760,11 @@ export const applyPgSnapshotsDiff = async ( return preparePgCreateTableJson(it, curFull); }); + jsonCreatePoliciesStatements.push(...([] as JsonCreatePolicyStatement[]).concat( + ...(createdTables.map((it) => + prepareCreatePolicyJsons(it.name, it.schema, Object.values(it.policies).map(PgSquasher.unsquashPolicy)) + )), + )); const createViews: JsonCreatePgViewStatement[] = []; const dropViews: JsonDropViewStatement[] = []; const renameViews: JsonRenameViewStatement[] = []; @@ -1385,8 +1927,15 @@ export const applyPgSnapshotsDiff = async ( jsonStatements.push(...renameSequences); jsonStatements.push(...jsonAlterSequences); + jsonStatements.push(...renameRoles); + jsonStatements.push(...dropRoles); + jsonStatements.push(...createRoles); + jsonStatements.push(...jsonAlterRoles); + jsonStatements.push(...createTables); + jsonStatements.push(...jsonEnableRLSStatements); + jsonStatements.push(...jsonDisableRLSStatements); jsonStatements.push(...dropViews); jsonStatements.push(...renameViews); jsonStatements.push(...alterViews); @@ -1425,6 +1974,16 @@ export const applyPgSnapshotsDiff = async ( jsonStatements.push(...jsonAlteredUniqueConstraints); jsonStatements.push(...jsonAlterEnumsWithDroppedValues); + jsonStatements.push(...jsonRenamePoliciesStatements); + jsonStatements.push(...jsonDropPoliciesStatements); + jsonStatements.push(...jsonCreatePoliciesStatements); + jsonStatements.push(...jsonAlterPoliciesStatements); + + jsonStatements.push(...jsonRenameIndPoliciesStatements); + jsonStatements.push(...jsonDropIndPoliciesStatements); + jsonStatements.push(...jsonCreateIndPoliciesStatements); + jsonStatements.push(...jsonAlterIndPoliciesStatements); + jsonStatements.push(...createViews); jsonStatements.push(...dropEnums); diff --git a/drizzle-kit/src/sqlgenerator.ts b/drizzle-kit/src/sqlgenerator.ts index 586175e28..da4dcdf56 100644 --- a/drizzle-kit/src/sqlgenerator.ts +++ b/drizzle-kit/src/sqlgenerator.ts @@ -20,8 +20,11 @@ import { JsonAlterColumnSetPrimaryKeyStatement, JsonAlterColumnTypeStatement, JsonAlterCompositePK, + JsonAlterIndPolicyStatement, JsonAlterMySqlViewStatement, + JsonAlterPolicyStatement, JsonAlterReferenceStatement, + JsonAlterRoleStatement, JsonAlterSequenceStatement, JsonAlterTableRemoveFromSchema, JsonAlterTableSetNewSchema, @@ -35,9 +38,12 @@ import { JsonCreateCompositePK, JsonCreateEnumStatement, JsonCreateIndexStatement, + JsonCreateIndPolicyStatement, JsonCreateMySqlViewStatement, JsonCreatePgViewStatement, + JsonCreatePolicyStatement, JsonCreateReferenceStatement, + JsonCreateRoleStatement, JsonCreateSchema, JsonCreateSequenceStatement, JsonCreateSqliteViewStatement, @@ -47,19 +53,27 @@ import { JsonDeleteCompositePK, JsonDeleteReferenceStatement, JsonDeleteUniqueConstraint, + JsonDisableRLSStatement, JsonDropColumnStatement, JsonDropEnumStatement, JsonDropIndexStatement, + JsonDropIndPolicyStatement, + JsonDropPolicyStatement, + JsonDropRoleStatement, JsonDropSequenceStatement, JsonDropTableStatement, JsonDropValueFromEnumStatement, JsonDropViewStatement, + JsonEnableRLSStatement, + JsonIndRenamePolicyStatement, JsonMoveEnumStatement, JsonMoveSequenceStatement, JsonPgCreateIndexStatement, JsonRecreateTableStatement, JsonRenameColumnStatement, JsonRenameEnumStatement, + JsonRenamePolicyStatement, + JsonRenameRoleStatement, JsonRenameSchema, JsonRenameSequenceStatement, JsonRenameTableStatement, @@ -70,7 +84,7 @@ import { } from './jsonStatements'; import { Dialect } from './schemaValidator'; import { MySqlSquasher } from './serializer/mysqlSchema'; -import { PgSquasher } from './serializer/pgSchema'; +import { PgSquasher, policy } from './serializer/pgSchema'; import { SQLiteSchemaSquashed, SQLiteSquasher } from './serializer/sqliteSchema'; export const pgNativeTypes = new Set([ @@ -155,13 +169,232 @@ abstract class Convertor { ): string | string[]; } +class PgCreateRoleConvertor extends Convertor { + override can(statement: JsonStatement, dialect: Dialect): boolean { + return statement.type === 'create_role' && dialect === 'postgresql'; + } + override convert(statement: JsonCreateRoleStatement): string | string[] { + return `CREATE ROLE "${statement.name}"${ + statement.values.createDb || statement.values.createRole || !statement.values.inherit + ? ` WITH${statement.values.createDb ? ' CREATEDB' : ''}${statement.values.createRole ? ' CREATEROLE' : ''}${ + statement.values.inherit ? '' : ' NOINHERIT' + }` + : '' + };`; + } +} + +class PgDropRoleConvertor extends Convertor { + override can(statement: JsonStatement, dialect: Dialect): boolean { + return statement.type === 'drop_role' && dialect === 'postgresql'; + } + override convert(statement: JsonDropRoleStatement): string | string[] { + return `DROP ROLE "${statement.name}";`; + } +} + +class PgRenameRoleConvertor extends Convertor { + override can(statement: JsonStatement, dialect: Dialect): boolean { + return statement.type === 'rename_role' && dialect === 'postgresql'; + } + override convert(statement: JsonRenameRoleStatement): string | string[] { + return `ALTER ROLE "${statement.nameFrom}" RENAME TO "${statement.nameTo}";`; + } +} + +class PgAlterRoleConvertor extends Convertor { + override can(statement: JsonStatement, dialect: Dialect): boolean { + return statement.type === 'alter_role' && dialect === 'postgresql'; + } + override convert(statement: JsonAlterRoleStatement): string | string[] { + return `ALTER ROLE "${statement.name}"${` WITH${statement.values.createDb ? ' CREATEDB' : ' NOCREATEDB'}${ + statement.values.createRole ? ' CREATEROLE' : ' NOCREATEROLE' + }${statement.values.inherit ? ' INHERIT' : ' NOINHERIT'}`};`; + } +} + +///// + +class PgCreatePolicyConvertor extends Convertor { + override can(statement: JsonStatement, dialect: Dialect): boolean { + return statement.type === 'create_policy' && dialect === 'postgresql'; + } + override convert(statement: JsonCreatePolicyStatement): string | string[] { + const policy = statement.data; + + const tableNameWithSchema = statement.schema + ? `"${statement.schema}"."${statement.tableName}"` + : `"${statement.tableName}"`; + + const usingPart = policy.using ? ` USING (${policy.using})` : ''; + + const withCheckPart = policy.withCheck ? ` WITH CHECK (${policy.withCheck})` : ''; + + const policyToPart = policy.to?.map((v) => + ['current_user', 'current_role', 'session_user', 'public'].includes(v) ? v : `"${v}"` + ).join(', '); + + return `CREATE POLICY "${policy.name}" ON ${tableNameWithSchema} AS ${policy.as?.toUpperCase()} FOR ${policy.for?.toUpperCase()} TO ${policyToPart}${usingPart}${withCheckPart};`; + } +} + +class PgDropPolicyConvertor extends Convertor { + override can(statement: JsonStatement, dialect: Dialect): boolean { + return statement.type === 'drop_policy' && dialect === 'postgresql'; + } + override convert(statement: JsonDropPolicyStatement): string | string[] { + const policy = statement.data; + + const tableNameWithSchema = statement.schema + ? `"${statement.schema}"."${statement.tableName}"` + : `"${statement.tableName}"`; + + return `DROP POLICY "${policy.name}" ON ${tableNameWithSchema} CASCADE;`; + } +} + +class PgRenamePolicyConvertor extends Convertor { + override can(statement: JsonStatement, dialect: Dialect): boolean { + return statement.type === 'rename_policy' && dialect === 'postgresql'; + } + override convert(statement: JsonRenamePolicyStatement): string | string[] { + const tableNameWithSchema = statement.schema + ? `"${statement.schema}"."${statement.tableName}"` + : `"${statement.tableName}"`; + + return `ALTER POLICY "${statement.oldName}" ON ${tableNameWithSchema} RENAME TO "${statement.newName}";`; + } +} + +class PgAlterPolicyConvertor extends Convertor { + override can(statement: JsonStatement, dialect: Dialect): boolean { + return statement.type === 'alter_policy' && dialect === 'postgresql'; + } + override convert(statement: JsonAlterPolicyStatement): string | string[] { + const newPolicy = PgSquasher.unsquashPolicy(statement.newData); + const oldPolicy = PgSquasher.unsquashPolicy(statement.oldData); + + const tableNameWithSchema = statement.schema + ? `"${statement.schema}"."${statement.tableName}"` + : `"${statement.tableName}"`; + + const usingPart = newPolicy.using + ? ` USING (${newPolicy.using})` + : oldPolicy.using + ? ` USING (${oldPolicy.using})` + : ''; + + const withCheckPart = newPolicy.withCheck + ? ` WITH CHECK (${newPolicy.withCheck})` + : oldPolicy.withCheck + ? ` WITH CHECK (${oldPolicy.withCheck})` + : ''; + + return `ALTER POLICY "${oldPolicy.name}" ON ${tableNameWithSchema} TO ${newPolicy.to}${usingPart}${withCheckPart};`; + } +} + +//// + +class PgCreateIndPolicyConvertor extends Convertor { + override can(statement: JsonStatement, dialect: Dialect): boolean { + return statement.type === 'create_ind_policy' && dialect === 'postgresql'; + } + override convert(statement: JsonCreateIndPolicyStatement): string | string[] { + const policy = statement.data; + + const usingPart = policy.using ? ` USING (${policy.using})` : ''; + + const withCheckPart = policy.withCheck ? ` WITH CHECK (${policy.withCheck})` : ''; + + const policyToPart = policy.to?.map((v) => + ['current_user', 'current_role', 'session_user', 'public'].includes(v) ? v : `"${v}"` + ).join(', '); + + return `CREATE POLICY "${policy.name}" ON ${policy.on} AS ${policy.as?.toUpperCase()} FOR ${policy.for?.toUpperCase()} TO ${policyToPart}${usingPart}${withCheckPart};`; + } +} + +class PgDropIndPolicyConvertor extends Convertor { + override can(statement: JsonStatement, dialect: Dialect): boolean { + return statement.type === 'drop_ind_policy' && dialect === 'postgresql'; + } + override convert(statement: JsonDropIndPolicyStatement): string | string[] { + const policy = statement.data; + + return `DROP POLICY "${policy.name}" ON ${policy.on} CASCADE;`; + } +} + +class PgRenameIndPolicyConvertor extends Convertor { + override can(statement: JsonStatement, dialect: Dialect): boolean { + return statement.type === 'rename_ind_policy' && dialect === 'postgresql'; + } + override convert(statement: JsonIndRenamePolicyStatement): string | string[] { + return `ALTER POLICY "${statement.oldName}" ON ${statement.tableKey} RENAME TO "${statement.newName}";`; + } +} + +class PgAlterIndPolicyConvertor extends Convertor { + override can(statement: JsonStatement, dialect: Dialect): boolean { + return statement.type === 'alter_ind_policy' && dialect === 'postgresql'; + } + override convert(statement: JsonAlterIndPolicyStatement): string | string[] { + const newPolicy = statement.newData; + const oldPolicy = statement.oldData; + + const usingPart = newPolicy.using + ? ` USING (${newPolicy.using})` + : oldPolicy.using + ? ` USING (${oldPolicy.using})` + : ''; + + const withCheckPart = newPolicy.withCheck + ? ` WITH CHECK (${newPolicy.withCheck})` + : oldPolicy.withCheck + ? ` WITH CHECK (${oldPolicy.withCheck})` + : ''; + + return `ALTER POLICY "${oldPolicy.name}" ON ${oldPolicy.on} TO ${newPolicy.to}${usingPart}${withCheckPart};`; + } +} + +//// + +class PgEnableRlsConvertor extends Convertor { + override can(statement: JsonStatement, dialect: Dialect): boolean { + return statement.type === 'enable_rls' && dialect === 'postgresql'; + } + override convert(statement: JsonEnableRLSStatement): string { + const tableNameWithSchema = statement.schema + ? `"${statement.schema}"."${statement.tableName}"` + : `"${statement.tableName}"`; + + return `ALTER TABLE ${tableNameWithSchema} ENABLE ROW LEVEL SECURITY;`; + } +} + +class PgDisableRlsConvertor extends Convertor { + override can(statement: JsonStatement, dialect: Dialect): boolean { + return statement.type === 'disable_rls' && dialect === 'postgresql'; + } + override convert(statement: JsonDisableRLSStatement): string { + const tableNameWithSchema = statement.schema + ? `"${statement.schema}"."${statement.tableName}"` + : `"${statement.tableName}"`; + + return `ALTER TABLE ${tableNameWithSchema} DISABLE ROW LEVEL SECURITY;`; + } +} + class PgCreateTableConvertor extends Convertor { can(statement: JsonStatement, dialect: Dialect): boolean { return statement.type === 'create_table' && dialect === 'postgresql'; } convert(st: JsonCreateTableStatement) { - const { tableName, schema, columns, compositePKs, uniqueConstraints, checkConstraints } = st; + const { tableName, schema, columns, compositePKs, uniqueConstraints, checkConstraints, policies, isRLSEnabled } = + st; let statement = ''; const name = schema ? `"${schema}"."${tableName}"` : `"${tableName}"`; @@ -258,7 +491,13 @@ class PgCreateTableConvertor extends Convertor { statement += `\n);`; statement += `\n`; - return statement; + const enableRls = new PgEnableRlsConvertor().convert({ + type: 'enable_rls', + tableName, + schema, + }); + + return [statement, ...(policies && policies.length > 0 || isRLSEnabled ? [enableRls] : [])]; } } @@ -1170,13 +1409,26 @@ class PgDropTableConvertor extends Convertor { } convert(statement: JsonDropTableStatement) { - const { tableName, schema } = statement; + const { tableName, schema, policies } = statement; const tableNameWithSchema = schema ? `"${schema}"."${tableName}"` : `"${tableName}"`; - return `DROP TABLE ${tableNameWithSchema};`; + const dropPolicyConvertor = new PgDropPolicyConvertor(); + const droppedPolicies = policies?.map((p) => { + return dropPolicyConvertor.convert({ + type: 'drop_policy', + tableName, + data: PgSquasher.unsquashPolicy(p), + schema, + }) as string; + }) ?? []; + + return [ + ...droppedPolicies, + `DROP TABLE ${tableNameWithSchema} CASCADE;`, + ]; } } @@ -3017,6 +3269,24 @@ convertors.push(new PgAlterTableAlterColumnDropNotNullConvertor()); convertors.push(new PgAlterTableAlterColumnSetDefaultConvertor()); convertors.push(new PgAlterTableAlterColumnDropDefaultConvertor()); +convertors.push(new PgAlterPolicyConvertor()); +convertors.push(new PgCreatePolicyConvertor()); +convertors.push(new PgDropPolicyConvertor()); +convertors.push(new PgRenamePolicyConvertor()); + +convertors.push(new PgAlterIndPolicyConvertor()); +convertors.push(new PgCreateIndPolicyConvertor()); +convertors.push(new PgDropIndPolicyConvertor()); +convertors.push(new PgRenameIndPolicyConvertor()); + +convertors.push(new PgEnableRlsConvertor()); +convertors.push(new PgDisableRlsConvertor()); + +convertors.push(new PgDropRoleConvertor()); +convertors.push(new PgAlterRoleConvertor()); +convertors.push(new PgCreateRoleConvertor()); +convertors.push(new PgRenameRoleConvertor()); + /// generated convertors.push(new PgAlterTableAlterColumnSetExpressionConvertor()); convertors.push(new PgAlterTableAlterColumnDropGeneratedConvertor()); diff --git a/drizzle-kit/src/utils.ts b/drizzle-kit/src/utils.ts index c13467da3..f26624969 100644 --- a/drizzle-kit/src/utils.ts +++ b/drizzle-kit/src/utils.ts @@ -1,11 +1,9 @@ import type { RunResult } from 'better-sqlite3'; import chalk from 'chalk'; -import { toCamelCase, toSnakeCase } from 'drizzle-orm/casing'; import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from 'fs'; import { join } from 'path'; import { parse } from 'url'; import type { NamedWithSchema } from './cli/commands/migrate'; -import { CasingType } from './cli/validations/common'; import { info } from './cli/views'; import { assertUnreachable, snapshotVersion } from './global'; import type { Dialect } from './schemaValidator'; @@ -358,15 +356,3 @@ export function findAddedAndRemoved(columnNames1: string[], columnNames2: string return { addedColumns, removedColumns }; } - -export function getColumnCasing( - column: { keyAsName: boolean; name: string | undefined }, - casing: CasingType | undefined, -) { - if (!column.name) return ''; - return !column.keyAsName || casing === undefined - ? column.name - : casing === 'camelCase' - ? toCamelCase(column.name) - : toSnakeCase(column.name); -} diff --git a/drizzle-kit/tests/cli-push.test.ts b/drizzle-kit/tests/cli-push.test.ts index e6f26eeb5..f5daf2bd0 100644 --- a/drizzle-kit/tests/cli-push.test.ts +++ b/drizzle-kit/tests/cli-push.test.ts @@ -25,6 +25,7 @@ test('push #1', async (t) => { schemaPath: './schema.ts', schemasFilter: ['public'], tablesFilter: [], + entities: undefined, strict: false, verbose: false, casing: undefined, @@ -87,6 +88,7 @@ test('push #4', async (t) => { schemaPath: './schema.ts', schemasFilter: ['public'], tablesFilter: [], + entities: undefined, strict: false, verbose: false, casing: undefined, @@ -110,6 +112,7 @@ test('push #5', async (t) => { schemasFilter: ['public'], tablesFilter: [], strict: false, + entities: undefined, force: false, verbose: false, casing: undefined, diff --git a/drizzle-kit/tests/introspect/pg.test.ts b/drizzle-kit/tests/introspect/pg.test.ts index bd8b15ab9..6762ef27a 100644 --- a/drizzle-kit/tests/introspect/pg.test.ts +++ b/drizzle-kit/tests/introspect/pg.test.ts @@ -19,6 +19,8 @@ import { numeric, pgEnum, pgMaterializedView, + pgPolicy, + pgRole, pgSchema, pgTable, pgView, @@ -627,3 +629,239 @@ test('introspect materialized view #2', async () => { expect(statements.length).toBe(0); expect(sqlStatements.length).toBe(0); }); + +test('basic policy', async () => { + const client = new PGlite(); + + const schema = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test'), + })), + }; + + const { statements, sqlStatements } = await introspectPgToFile( + client, + schema, + 'basic-policy', + ); + + expect(statements.length).toBe(0); + expect(sqlStatements.length).toBe(0); +}); + +test('basic policy with "as"', async () => { + const client = new PGlite(); + + const schema = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'permissive' }), + })), + }; + + const { statements, sqlStatements } = await introspectPgToFile( + client, + schema, + 'basic-policy-as', + ); + + expect(statements.length).toBe(0); + expect(sqlStatements.length).toBe(0); +}); + +test.todo('basic policy with CURRENT_USER role', async () => { + const client = new PGlite(); + + const schema = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { to: 'current_user' }), + })), + }; + + const { statements, sqlStatements } = await introspectPgToFile( + client, + schema, + 'basic-policy', + ); + + expect(statements.length).toBe(0); + expect(sqlStatements.length).toBe(0); +}); + +test('basic policy with all fields except "using" and "with"', async () => { + const client = new PGlite(); + + const schema = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'permissive', for: 'all', to: ['postgres'] }), + })), + }; + + const { statements, sqlStatements } = await introspectPgToFile( + client, + schema, + 'basic-policy-all-fields', + ); + + expect(statements.length).toBe(0); + expect(sqlStatements.length).toBe(0); +}); + +test('basic policy with "using" and "with"', async () => { + const client = new PGlite(); + + const schema = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { using: sql`true`, withCheck: sql`true` }), + })), + }; + + const { statements, sqlStatements } = await introspectPgToFile( + client, + schema, + 'basic-policy-using-withcheck', + ); + + expect(statements.length).toBe(0); + expect(sqlStatements.length).toBe(0); +}); + +test('multiple policies', async () => { + const client = new PGlite(); + + const schema = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { using: sql`true`, withCheck: sql`true` }), + rlsPolicy: pgPolicy('newRls'), + })), + }; + + const { statements, sqlStatements } = await introspectPgToFile( + client, + schema, + 'multiple-policies', + ); + + expect(statements.length).toBe(0); + expect(sqlStatements.length).toBe(0); +}); + +test('multiple policies with roles', async () => { + const client = new PGlite(); + + client.query(`CREATE ROLE manager;`); + + const schema = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { using: sql`true`, withCheck: sql`true` }), + rlsPolicy: pgPolicy('newRls', { to: ['postgres', 'manager'] }), + })), + }; + + const { statements, sqlStatements } = await introspectPgToFile( + client, + schema, + 'multiple-policies-with-roles', + ); + + expect(statements.length).toBe(0); + expect(sqlStatements.length).toBe(0); +}); + +test('basic roles', async () => { + const client = new PGlite(); + + const schema = { + usersRole: pgRole('user'), + }; + + const { statements, sqlStatements } = await introspectPgToFile( + client, + schema, + 'basic-roles', + ['public'], + { roles: { include: ['user'] } }, + ); + + expect(statements.length).toBe(0); + expect(sqlStatements.length).toBe(0); +}); + +test('role with properties', async () => { + const client = new PGlite(); + + const schema = { + usersRole: pgRole('user', { inherit: false, createDb: true, createRole: true }), + }; + + const { statements, sqlStatements } = await introspectPgToFile( + client, + schema, + 'roles-with-properties', + ['public'], + { roles: { include: ['user'] } }, + ); + + expect(statements.length).toBe(0); + expect(sqlStatements.length).toBe(0); +}); + +test('role with a few properties', async () => { + const client = new PGlite(); + + const schema = { + usersRole: pgRole('user', { inherit: false, createRole: true }), + }; + + const { statements, sqlStatements } = await introspectPgToFile( + client, + schema, + 'roles-with-few-properties', + ['public'], + { roles: { include: ['user'] } }, + ); + + expect(statements.length).toBe(0); + expect(sqlStatements.length).toBe(0); +}); + +test('multiple policies with roles from schema', async () => { + const client = new PGlite(); + + const usersRole = pgRole('user_role', { inherit: false, createRole: true }); + + const schema = { + usersRole, + + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { using: sql`true`, withCheck: sql`true` }), + rlsPolicy: pgPolicy('newRls', { to: ['postgres', usersRole] }), + })), + }; + + const { statements, sqlStatements } = await introspectPgToFile( + client, + schema, + 'multiple-policies-with-roles-from-schema', + ['public'], + { roles: { include: ['user_role'] } }, + ); + + expect(statements.length).toBe(0); + expect(sqlStatements.length).toBe(0); +}); diff --git a/drizzle-kit/tests/mysql.test.ts b/drizzle-kit/tests/mysql.test.ts index 29f2e869a..183464ec0 100644 --- a/drizzle-kit/tests/mysql.test.ts +++ b/drizzle-kit/tests/mysql.test.ts @@ -201,6 +201,7 @@ test('add table #6', async () => { }); expect(statements[1]).toStrictEqual({ type: 'drop_table', + policies: [], tableName: 'users1', schema: undefined, }); @@ -294,6 +295,7 @@ test('change table schema #1', async () => { expect(statements.length).toBe(1); expect(statements[0]).toStrictEqual({ type: 'drop_table', + policies: [], tableName: 'users', schema: undefined, }); diff --git a/drizzle-kit/tests/pg-checks.test.ts b/drizzle-kit/tests/pg-checks.test.ts index 1f5e5e1c5..50a01a6c1 100644 --- a/drizzle-kit/tests/pg-checks.test.ts +++ b/drizzle-kit/tests/pg-checks.test.ts @@ -39,6 +39,8 @@ test('create table with check', async (t) => { checkConstraints: ['some_check_name;"users"."age" > 21'], compositePkName: '', uniqueConstraints: [], + isRLSEnabled: false, + policies: [], } as JsonCreateTableStatement); expect(sqlStatements.length).toBe(1); diff --git a/drizzle-kit/tests/pg-identity.test.ts b/drizzle-kit/tests/pg-identity.test.ts index 7e0854b67..9f6ce8ba7 100644 --- a/drizzle-kit/tests/pg-identity.test.ts +++ b/drizzle-kit/tests/pg-identity.test.ts @@ -45,6 +45,8 @@ test('create table: identity always/by default - no params', async () => { compositePKs: [], compositePkName: '', schema: '', + policies: [], + isRLSEnabled: false, tableName: 'users', type: 'create_table', uniqueConstraints: [], @@ -83,7 +85,9 @@ test('create table: identity always/by default - few params', async () => { ], compositePKs: [], compositePkName: '', + policies: [], schema: '', + isRLSEnabled: false, tableName: 'users', type: 'create_table', uniqueConstraints: [], @@ -126,6 +130,8 @@ test('create table: identity always/by default - all params', async () => { ], compositePKs: [], compositePkName: '', + policies: [], + isRLSEnabled: false, schema: '', tableName: 'users', type: 'create_table', diff --git a/drizzle-kit/tests/pg-tables.test.ts b/drizzle-kit/tests/pg-tables.test.ts index 0648459b4..1f2885f92 100644 --- a/drizzle-kit/tests/pg-tables.test.ts +++ b/drizzle-kit/tests/pg-tables.test.ts @@ -34,8 +34,10 @@ test('add table #1', async () => { schema: '', columns: [], compositePKs: [], + policies: [], uniqueConstraints: [], checkConstraints: [], + isRLSEnabled: false, compositePkName: '', }); }); @@ -63,6 +65,8 @@ test('add table #2', async () => { }, ], compositePKs: [], + isRLSEnabled: false, + policies: [], uniqueConstraints: [], checkConstraints: [], compositePkName: '', @@ -103,7 +107,9 @@ test('add table #3', async () => { }, ], compositePKs: ['id;users_pk'], + policies: [], uniqueConstraints: [], + isRLSEnabled: false, checkConstraints: [], compositePkName: 'users_pk', }); @@ -124,16 +130,20 @@ test('add table #4', async () => { schema: '', columns: [], compositePKs: [], + policies: [], uniqueConstraints: [], checkConstraints: [], + isRLSEnabled: false, compositePkName: '', }); expect(statements[1]).toStrictEqual({ type: 'create_table', tableName: 'posts', + policies: [], schema: '', columns: [], compositePKs: [], + isRLSEnabled: false, uniqueConstraints: [], checkConstraints: [], compositePkName: '', @@ -160,9 +170,11 @@ test('add table #5', async () => { schema: 'folder', columns: [], compositePKs: [], + policies: [], uniqueConstraints: [], compositePkName: '', checkConstraints: [], + isRLSEnabled: false, }); }); @@ -185,11 +197,14 @@ test('add table #6', async () => { columns: [], compositePKs: [], uniqueConstraints: [], + policies: [], compositePkName: '', checkConstraints: [], + isRLSEnabled: false, }); expect(statements[1]).toStrictEqual({ type: 'drop_table', + policies: [], tableName: 'users1', schema: '', }); @@ -216,8 +231,10 @@ test('add table #7', async () => { schema: '', columns: [], compositePKs: [], + policies: [], uniqueConstraints: [], compositePkName: '', + isRLSEnabled: false, checkConstraints: [], }); expect(statements[1]).toStrictEqual({ @@ -273,7 +290,9 @@ test('multiproject schema add table #1', async () => { }, ], compositePKs: [], + policies: [], compositePkName: '', + isRLSEnabled: false, uniqueConstraints: [], checkConstraints: [], }); @@ -296,6 +315,7 @@ test('multiproject schema drop table #1', async () => { schema: '', tableName: 'prefix_users', type: 'drop_table', + policies: [], }); }); @@ -365,8 +385,10 @@ test('add schema + table #1', async () => { type: 'create_table', tableName: 'users', schema: 'folder', + policies: [], columns: [], compositePKs: [], + isRLSEnabled: false, uniqueConstraints: [], compositePkName: '', checkConstraints: [], @@ -623,6 +645,7 @@ test('drop table + rename schema #1', async () => { type: 'drop_table', tableName: 'users', schema: 'folder2', + policies: [], }); }); diff --git a/drizzle-kit/tests/pg-views.test.ts b/drizzle-kit/tests/pg-views.test.ts index 2874caf5b..002004c47 100644 --- a/drizzle-kit/tests/pg-views.test.ts +++ b/drizzle-kit/tests/pg-views.test.ts @@ -27,8 +27,10 @@ test('create table and view #1', async () => { }], compositePKs: [], uniqueConstraints: [], + isRLSEnabled: false, compositePkName: '', checkConstraints: [], + policies: [], }); expect(statements[1]).toStrictEqual({ type: 'create_view', @@ -73,7 +75,9 @@ test('create table and view #2', async () => { }], compositePKs: [], uniqueConstraints: [], + isRLSEnabled: false, compositePkName: '', + policies: [], checkConstraints: [], }); expect(statements[1]).toStrictEqual({ @@ -130,6 +134,8 @@ test('create table and view #3', async () => { uniqueConstraints: [], compositePkName: '', checkConstraints: [], + isRLSEnabled: false, + policies: [], }); expect(statements[1]).toStrictEqual({ type: 'create_view', @@ -215,6 +221,8 @@ test('create table and view #4', async () => { compositePKs: [], uniqueConstraints: [], compositePkName: '', + isRLSEnabled: false, + policies: [], checkConstraints: [], }); expect(statements[2]).toStrictEqual({ @@ -302,6 +310,8 @@ test('create table and view #6', async () => { type: 'create_table', uniqueConstraints: [], checkConstraints: [], + isRLSEnabled: false, + policies: [], }); expect(statements[1]).toStrictEqual({ definition: 'SELECT * FROM "users"', @@ -370,6 +380,8 @@ test('create table and materialized view #1', async () => { }], compositePKs: [], uniqueConstraints: [], + isRLSEnabled: false, + policies: [], compositePkName: '', checkConstraints: [], }); @@ -417,6 +429,8 @@ test('create table and materialized view #2', async () => { compositePKs: [], uniqueConstraints: [], compositePkName: '', + isRLSEnabled: false, + policies: [], checkConstraints: [], }); expect(statements[1]).toStrictEqual({ @@ -482,7 +496,9 @@ test('create table and materialized view #3', async () => { }], compositePKs: [], uniqueConstraints: [], + isRLSEnabled: false, compositePkName: '', + policies: [], checkConstraints: [], }); expect(statements[1]).toStrictEqual({ @@ -582,6 +598,8 @@ test('create table and materialized view #5', async () => { tableName: 'users', type: 'create_table', uniqueConstraints: [], + isRLSEnabled: false, + policies: [], checkConstraints: [], }); expect(statements[1]).toEqual({ diff --git a/drizzle-kit/tests/push/libsql.test.ts b/drizzle-kit/tests/push/libsql.test.ts index 1877f34e1..460809d9e 100644 --- a/drizzle-kit/tests/push/libsql.test.ts +++ b/drizzle-kit/tests/push/libsql.test.ts @@ -655,6 +655,7 @@ test('drop table with data', async (t) => { expect(statements!.length).toBe(1); expect(statements![0]).toStrictEqual({ + policies: [], schema: undefined, tableName: 'users', type: 'drop_table', diff --git a/drizzle-kit/tests/push/pg.test.ts b/drizzle-kit/tests/push/pg.test.ts index fb2ffdc8d..67743d2ef 100644 --- a/drizzle-kit/tests/push/pg.test.ts +++ b/drizzle-kit/tests/push/pg.test.ts @@ -16,6 +16,8 @@ import { numeric, pgEnum, pgMaterializedView, + pgPolicy, + pgRole, pgSchema, pgSequence, pgTable, @@ -534,8 +536,10 @@ const pgSuite: DialectSuite = { ], compositePKs: [], compositePkName: '', + isRLSEnabled: false, schema: '', tableName: 'users', + policies: [], type: 'create_table', uniqueConstraints: [], checkConstraints: [], @@ -1208,8 +1212,10 @@ test('create table: identity always/by default - no params', async () => { compositePkName: '', schema: '', tableName: 'users', + policies: [], type: 'create_table', uniqueConstraints: [], + isRLSEnabled: false, checkConstraints: [], }, ]); @@ -1267,9 +1273,11 @@ test('create table: identity always/by default - few params', async () => { ], compositePKs: [], compositePkName: '', + policies: [], schema: '', tableName: 'users', type: 'create_table', + isRLSEnabled: false, uniqueConstraints: [], checkConstraints: [], }, @@ -1337,6 +1345,8 @@ test('create table: identity always/by default - all params', async () => { schema: '', tableName: 'users', type: 'create_table', + policies: [], + isRLSEnabled: false, uniqueConstraints: [], checkConstraints: [], }, @@ -2357,6 +2367,7 @@ test('drop mat view with data', async () => { false, ['public'], undefined, + undefined, { after: seedStatements }, ); @@ -2464,6 +2475,7 @@ test('drop view with data', async () => { false, ['public'], undefined, + undefined, { after: seedStatements }, ); @@ -2545,6 +2557,7 @@ test('enums ordering', async () => { false, ['public'], undefined, + undefined, { before: [...createEnum, ...addedValueSql], runApply: false }, ); @@ -2668,3 +2681,1313 @@ test('drop enum values', async () => { `ALTER TABLE "mySchema"."enum_table" ALTER COLUMN "id" SET DATA TYPE "public"."enum_users_customer_and_ship_to_settings_roles" USING "id"::"public"."enum_users_customer_and_ship_to_settings_roles";`, ); }); + +// Policies and Roles push test +test('full policy: no changes', async () => { + const client = new PGlite(); + + const schema1 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'permissive' }), + })), + }; + + const schema2 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'permissive' }), + })), + }; + + const { statements, sqlStatements } = await diffTestSchemasPush( + client, + schema1, + schema2, + [], + false, + ['public'], + ); + + expect(statements.length).toBe(0); + expect(sqlStatements.length).toBe(0); + + for (const st of sqlStatements) { + await client.query(st); + } +}); + +test('add policy', async () => { + const client = new PGlite(); + + const schema1 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }), + }; + + const schema2 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'permissive' }), + })), + }; + + const { statements, sqlStatements } = await diffTestSchemasPush( + client, + schema1, + schema2, + [], + false, + ['public'], + ); + + expect(statements).toStrictEqual([ + { type: 'enable_rls', tableName: 'users', schema: '' }, + { + type: 'create_policy', + tableName: 'users', + data: { + name: 'test', + as: 'PERMISSIVE', + for: 'ALL', + to: ['public'], + using: undefined, + on: undefined, + withCheck: undefined, + }, + schema: '', + }, + ]); + expect(sqlStatements).toStrictEqual([ + 'ALTER TABLE "users" ENABLE ROW LEVEL SECURITY;', + 'CREATE POLICY "test" ON "users" AS PERMISSIVE FOR ALL TO public;', + ]); + + for (const st of sqlStatements) { + await client.query(st); + } +}); + +test('drop policy', async () => { + const client = new PGlite(); + + const schema1 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'permissive' }), + })), + }; + + const schema2 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }), + }; + + const { statements, sqlStatements } = await diffTestSchemasPush( + client, + schema1, + schema2, + [], + false, + ['public'], + ); + + expect(statements).toStrictEqual([ + { type: 'disable_rls', tableName: 'users', schema: '' }, + { + schema: '', + tableName: 'users', + type: 'disable_rls', + }, + { + type: 'drop_policy', + tableName: 'users', + data: { + name: 'test', + as: 'PERMISSIVE', + for: 'ALL', + to: ['public'], + on: undefined, + using: undefined, + withCheck: undefined, + }, + schema: '', + }, + ]); + expect(sqlStatements).toStrictEqual([ + 'ALTER TABLE "users" DISABLE ROW LEVEL SECURITY;', + 'DROP POLICY "test" ON "users" CASCADE;', + ]); + + for (const st of sqlStatements) { + await client.query(st); + } +}); + +test('add policy without enable rls', async () => { + const client = new PGlite(); + + const schema1 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'permissive' }), + })), + }; + + const schema2 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'permissive' }), + newrls: pgPolicy('newRls'), + })), + }; + + const { statements, sqlStatements } = await diffTestSchemasPush( + client, + schema1, + schema2, + [], + false, + ['public'], + ); + + expect(statements).toStrictEqual([ + { + type: 'create_policy', + tableName: 'users', + data: { + name: 'newRls', + as: 'PERMISSIVE', + for: 'ALL', + to: ['public'], + using: undefined, + on: undefined, + withCheck: undefined, + }, + schema: '', + }, + ]); + expect(sqlStatements).toStrictEqual([ + 'CREATE POLICY "newRls" ON "users" AS PERMISSIVE FOR ALL TO public;', + ]); + + for (const st of sqlStatements) { + await client.query(st); + } +}); + +test('drop policy without disable rls', async () => { + const client = new PGlite(); + + const schema1 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'permissive' }), + oldRls: pgPolicy('oldRls'), + })), + }; + + const schema2 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'permissive' }), + })), + }; + + const { statements, sqlStatements } = await diffTestSchemasPush( + client, + schema1, + schema2, + [], + false, + ['public'], + ); + + expect(statements).toStrictEqual([ + { + type: 'drop_policy', + tableName: 'users', + data: { + name: 'oldRls', + as: 'PERMISSIVE', + for: 'ALL', + to: ['public'], + using: undefined, + on: undefined, + withCheck: undefined, + }, + schema: '', + }, + ]); + expect(sqlStatements).toStrictEqual([ + 'DROP POLICY "oldRls" ON "users" CASCADE;', + ]); + + for (const st of sqlStatements) { + await client.query(st); + } +}); + +//// + +test('alter policy without recreation: changing roles', async (t) => { + const client = new PGlite(); + + const schema1 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'permissive' }), + })), + }; + + const schema2 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'permissive', to: 'current_role' }), + })), + }; + + const { statements, sqlStatements } = await diffTestSchemasPush( + client, + schema1, + schema2, + [], + false, + ['public'], + ); + + expect(sqlStatements).toStrictEqual([ + 'ALTER POLICY "test" ON "users" TO current_role;', + ]); + expect(statements).toStrictEqual([ + { + newData: 'test--PERMISSIVE--ALL--current_role--undefined', + oldData: 'test--PERMISSIVE--ALL--public--undefined', + schema: '', + tableName: 'users', + type: 'alter_policy', + }, + ]); + + for (const st of sqlStatements) { + await client.query(st); + } +}); + +test('alter policy without recreation: changing using', async (t) => { + const client = new PGlite(); + + const schema1 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'permissive' }), + })), + }; + + const schema2 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'permissive', using: sql`true` }), + })), + }; + + const { statements, sqlStatements } = await diffTestSchemasPush( + client, + schema1, + schema2, + [], + false, + ['public'], + ); + + expect(sqlStatements).toStrictEqual([]); + expect(statements).toStrictEqual([]); + + for (const st of sqlStatements) { + await client.query(st); + } +}); + +test('alter policy without recreation: changing with check', async (t) => { + const client = new PGlite(); + + const schema1 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'permissive' }), + })), + }; + + const schema2 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'permissive', withCheck: sql`true` }), + })), + }; + + const { statements, sqlStatements } = await diffTestSchemasPush( + client, + schema1, + schema2, + [], + false, + ['public'], + ); + + expect(sqlStatements).toStrictEqual([]); + expect(statements).toStrictEqual([]); + + for (const st of sqlStatements) { + await client.query(st); + } +}); + +test('alter policy with recreation: changing as', async (t) => { + const client = new PGlite(); + + const schema1 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'permissive' }), + })), + }; + + const schema2 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'restrictive' }), + })), + }; + + const { statements, sqlStatements } = await diffTestSchemasPush( + client, + schema1, + schema2, + [], + false, + ['public'], + ); + + expect(sqlStatements).toStrictEqual([ + 'DROP POLICY "test" ON "users" CASCADE;', + 'CREATE POLICY "test" ON "users" AS RESTRICTIVE FOR ALL TO public;', + ]); + expect(statements).toStrictEqual([ + { + data: { + as: 'PERMISSIVE', + for: 'ALL', + name: 'test', + to: ['public'], + on: undefined, + using: undefined, + withCheck: undefined, + }, + schema: '', + tableName: 'users', + type: 'drop_policy', + }, + { + data: { + as: 'RESTRICTIVE', + for: 'ALL', + name: 'test', + to: ['public'], + on: undefined, + using: undefined, + withCheck: undefined, + }, + schema: '', + tableName: 'users', + type: 'create_policy', + }, + ]); + + for (const st of sqlStatements) { + await client.query(st); + } +}); + +test('alter policy with recreation: changing for', async (t) => { + const client = new PGlite(); + + const schema1 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'permissive' }), + })), + }; + + const schema2 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'permissive', for: 'delete' }), + })), + }; + + const { statements, sqlStatements } = await diffTestSchemasPush( + client, + schema1, + schema2, + [], + false, + ['public'], + ); + + expect(sqlStatements).toStrictEqual([ + 'DROP POLICY "test" ON "users" CASCADE;', + 'CREATE POLICY "test" ON "users" AS PERMISSIVE FOR DELETE TO public;', + ]); + expect(statements).toStrictEqual([ + { + data: { + as: 'PERMISSIVE', + for: 'ALL', + name: 'test', + to: ['public'], + on: undefined, + using: undefined, + withCheck: undefined, + }, + schema: '', + tableName: 'users', + type: 'drop_policy', + }, + { + data: { + as: 'PERMISSIVE', + for: 'DELETE', + name: 'test', + to: ['public'], + using: undefined, + on: undefined, + withCheck: undefined, + }, + schema: '', + tableName: 'users', + type: 'create_policy', + }, + ]); + + for (const st of sqlStatements) { + await client.query(st); + } +}); + +test('alter policy with recreation: changing both "as" and "for"', async (t) => { + const client = new PGlite(); + + const schema1 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'permissive' }), + })), + }; + + const schema2 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'restrictive', for: 'insert' }), + })), + }; + + const { statements, sqlStatements } = await diffTestSchemasPush( + client, + schema1, + schema2, + [], + false, + ['public'], + ); + + expect(sqlStatements).toStrictEqual([ + 'DROP POLICY "test" ON "users" CASCADE;', + 'CREATE POLICY "test" ON "users" AS RESTRICTIVE FOR INSERT TO public;', + ]); + expect(statements).toStrictEqual([ + { + data: { + as: 'PERMISSIVE', + for: 'ALL', + name: 'test', + to: ['public'], + using: undefined, + on: undefined, + withCheck: undefined, + }, + schema: '', + tableName: 'users', + type: 'drop_policy', + }, + { + data: { + as: 'RESTRICTIVE', + for: 'INSERT', + name: 'test', + to: ['public'], + using: undefined, + on: undefined, + withCheck: undefined, + }, + schema: '', + tableName: 'users', + type: 'create_policy', + }, + ]); + + for (const st of sqlStatements) { + await client.query(st); + } +}); + +test('alter policy with recreation: changing all fields', async (t) => { + const client = new PGlite(); + + const schema1 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'permissive', for: 'select', using: sql`true` }), + })), + }; + + const schema2 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'restrictive', to: 'current_role', withCheck: sql`true` }), + })), + }; + + const { statements, sqlStatements } = await diffTestSchemasPush( + client, + schema1, + schema2, + [], + false, + ['public'], + ); + + expect(sqlStatements).toStrictEqual([ + 'DROP POLICY "test" ON "users" CASCADE;', + 'CREATE POLICY "test" ON "users" AS RESTRICTIVE FOR ALL TO current_role;', + ]); + expect(statements).toStrictEqual([ + { + data: { + as: 'PERMISSIVE', + for: 'SELECT', + name: 'test', + to: ['public'], + using: undefined, + on: undefined, + withCheck: undefined, + }, + schema: '', + tableName: 'users', + type: 'drop_policy', + }, + { + data: { + as: 'RESTRICTIVE', + for: 'ALL', + name: 'test', + to: ['current_role'], + on: undefined, + using: undefined, + withCheck: undefined, + }, + schema: '', + tableName: 'users', + type: 'create_policy', + }, + ]); + + for (const st of sqlStatements) { + await client.query(st); + } +}); + +test('rename policy', async (t) => { + const client = new PGlite(); + + const schema1 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'permissive' }), + })), + }; + + const schema2 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('newName', { as: 'permissive' }), + })), + }; + + const { statements, sqlStatements } = await diffTestSchemasPush( + client, + schema1, + schema2, + ['public.users.test->public.users.newName'], + false, + ['public'], + ); + + expect(sqlStatements).toStrictEqual([ + 'ALTER POLICY "test" ON "users" RENAME TO "newName";', + ]); + expect(statements).toStrictEqual([ + { + newName: 'newName', + oldName: 'test', + schema: '', + tableName: 'users', + type: 'rename_policy', + }, + ]); + + for (const st of sqlStatements) { + await client.query(st); + } +}); + +test('rename policy in renamed table', async (t) => { + const client = new PGlite(); + + const schema1 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'permissive' }), + })), + }; + + const schema2 = { + users: pgTable('users2', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('newName', { as: 'permissive' }), + })), + }; + + const { statements, sqlStatements } = await diffTestSchemasPush( + client, + schema1, + schema2, + [ + 'public.users->public.users2', + 'public.users2.test->public.users2.newName', + ], + false, + ['public'], + ); + + expect(sqlStatements).toStrictEqual([ + 'ALTER TABLE "users" RENAME TO "users2";', + 'ALTER POLICY "test" ON "users2" RENAME TO "newName";', + ]); + expect(statements).toStrictEqual([ + { + fromSchema: '', + tableNameFrom: 'users', + tableNameTo: 'users2', + toSchema: '', + type: 'rename_table', + }, + { + newName: 'newName', + oldName: 'test', + schema: '', + tableName: 'users2', + type: 'rename_policy', + }, + ]); + + for (const st of sqlStatements) { + await client.query(st); + } +}); + +test('create table with a policy', async (t) => { + const client = new PGlite(); + + const schema1 = {}; + + const schema2 = { + users: pgTable('users2', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'permissive' }), + })), + }; + + const { statements, sqlStatements } = await diffTestSchemasPush( + client, + schema1, + schema2, + [], + false, + ['public'], + ); + + expect(sqlStatements).toStrictEqual([ + 'CREATE TABLE IF NOT EXISTS "users2" (\n\t"id" integer PRIMARY KEY NOT NULL\n);\n', + 'ALTER TABLE "users2" ENABLE ROW LEVEL SECURITY;', + 'CREATE POLICY "test" ON "users2" AS PERMISSIVE FOR ALL TO public;', + ]); + expect(statements).toStrictEqual([ + { + columns: [ + { + name: 'id', + notNull: true, + primaryKey: true, + type: 'integer', + }, + ], + checkConstraints: [], + compositePKs: [], + isRLSEnabled: false, + compositePkName: '', + policies: [ + 'test--PERMISSIVE--ALL--public--undefined', + ], + schema: '', + tableName: 'users2', + type: 'create_table', + uniqueConstraints: [], + }, + { + data: { + as: 'PERMISSIVE', + for: 'ALL', + name: 'test', + to: [ + 'public', + ], + using: undefined, + on: undefined, + withCheck: undefined, + }, + schema: '', + tableName: 'users2', + type: 'create_policy', + }, + ]); + + for (const st of sqlStatements) { + await client.query(st); + } +}); + +test('drop table with a policy', async (t) => { + const client = new PGlite(); + + const schema1 = { + users: pgTable('users2', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'permissive' }), + })), + }; + + const schema2 = {}; + + const { statements, sqlStatements } = await diffTestSchemasPush( + client, + schema1, + schema2, + [], + false, + ['public'], + ); + + expect(sqlStatements).toStrictEqual([ + 'DROP POLICY "test" ON "users2" CASCADE;', + 'DROP TABLE "users2" CASCADE;', + ]); + expect(statements).toStrictEqual([ + { + policies: [ + 'test--PERMISSIVE--ALL--public--undefined', + ], + schema: '', + tableName: 'users2', + type: 'drop_table', + }, + ]); + + for (const st of sqlStatements) { + await client.query(st); + } +}); + +test('add policy with multiple "to" roles', async (t) => { + const client = new PGlite(); + + client.query(`CREATE ROLE manager;`); + + const schema1 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }), + }; + + const role = pgRole('manager').existing(); + + const schema2 = { + role, + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { to: ['current_role', role] }), + })), + }; + + const { statements, sqlStatements } = await diffTestSchemasPush( + client, + schema1, + schema2, + [], + false, + ['public'], + ); + + expect(sqlStatements).toStrictEqual([ + 'ALTER TABLE "users" ENABLE ROW LEVEL SECURITY;', + 'CREATE POLICY "test" ON "users" AS PERMISSIVE FOR ALL TO current_role, "manager";', + ]); + expect(statements).toStrictEqual([ + { + schema: '', + tableName: 'users', + type: 'enable_rls', + }, + { + data: { + as: 'PERMISSIVE', + for: 'ALL', + name: 'test', + on: undefined, + to: ['current_role', 'manager'], + using: undefined, + withCheck: undefined, + }, + schema: '', + tableName: 'users', + type: 'create_policy', + }, + ]); + + for (const st of sqlStatements) { + await client.query(st); + } +}); + +//// + +test('create role', async (t) => { + const client = new PGlite(); + + const schema1 = {}; + + const schema2 = { + manager: pgRole('manager'), + }; + + const { statements, sqlStatements } = await diffTestSchemasPush( + client, + schema1, + schema2, + [], + false, + ['public'], + undefined, + { roles: { include: ['manager'] } }, + ); + + expect(sqlStatements).toStrictEqual(['CREATE ROLE "manager";']); + expect(statements).toStrictEqual([ + { + name: 'manager', + type: 'create_role', + values: { + createDb: false, + createRole: false, + inherit: true, + }, + }, + ]); + + for (const st of sqlStatements) { + await client.query(st); + } +}); + +test('create role with properties', async (t) => { + const client = new PGlite(); + + const schema1 = {}; + + const schema2 = { + manager: pgRole('manager', { createDb: true, inherit: false, createRole: true }), + }; + + const { statements, sqlStatements } = await diffTestSchemasPush( + client, + schema1, + schema2, + [], + false, + ['public'], + undefined, + { roles: { include: ['manager'] } }, + ); + + expect(sqlStatements).toStrictEqual(['CREATE ROLE "manager" WITH CREATEDB CREATEROLE NOINHERIT;']); + expect(statements).toStrictEqual([ + { + name: 'manager', + type: 'create_role', + values: { + createDb: true, + createRole: true, + inherit: false, + }, + }, + ]); + + for (const st of sqlStatements) { + await client.query(st); + } +}); + +test('create role with some properties', async (t) => { + const client = new PGlite(); + + const schema1 = {}; + + const schema2 = { + manager: pgRole('manager', { createDb: true, inherit: false }), + }; + + const { statements, sqlStatements } = await diffTestSchemasPush( + client, + schema1, + schema2, + [], + false, + ['public'], + undefined, + { roles: { include: ['manager'] } }, + ); + + expect(sqlStatements).toStrictEqual(['CREATE ROLE "manager" WITH CREATEDB NOINHERIT;']); + expect(statements).toStrictEqual([ + { + name: 'manager', + type: 'create_role', + values: { + createDb: true, + createRole: false, + inherit: false, + }, + }, + ]); + + for (const st of sqlStatements) { + await client.query(st); + } +}); + +test('drop role', async (t) => { + const client = new PGlite(); + + const schema1 = { manager: pgRole('manager') }; + + const schema2 = {}; + + const { statements, sqlStatements } = await diffTestSchemasPush( + client, + schema1, + schema2, + [], + false, + ['public'], + undefined, + { roles: { include: ['manager'] } }, + ); + + expect(sqlStatements).toStrictEqual(['DROP ROLE "manager";']); + expect(statements).toStrictEqual([ + { + name: 'manager', + type: 'drop_role', + }, + ]); + + for (const st of sqlStatements) { + await client.query(st); + } +}); + +test('create and drop role', async (t) => { + const client = new PGlite(); + + const schema1 = { + manager: pgRole('manager'), + }; + + const schema2 = { + admin: pgRole('admin'), + }; + + const { statements, sqlStatements } = await diffTestSchemasPush( + client, + schema1, + schema2, + [], + false, + ['public'], + undefined, + { roles: { include: ['manager', 'admin'] } }, + ); + + expect(sqlStatements).toStrictEqual(['DROP ROLE "manager";', 'CREATE ROLE "admin";']); + expect(statements).toStrictEqual([ + { + name: 'manager', + type: 'drop_role', + }, + { + name: 'admin', + type: 'create_role', + values: { + createDb: false, + createRole: false, + inherit: true, + }, + }, + ]); + + for (const st of sqlStatements) { + await client.query(st); + } +}); + +test('rename role', async (t) => { + const client = new PGlite(); + + const schema1 = { + manager: pgRole('manager'), + }; + + const schema2 = { + admin: pgRole('admin'), + }; + + const { statements, sqlStatements } = await diffTestSchemasPush( + client, + schema1, + schema2, + ['manager->admin'], + false, + ['public'], + undefined, + { roles: { include: ['manager', 'admin'] } }, + ); + + expect(sqlStatements).toStrictEqual(['ALTER ROLE "manager" RENAME TO "admin";']); + expect(statements).toStrictEqual([ + { nameFrom: 'manager', nameTo: 'admin', type: 'rename_role' }, + ]); + + for (const st of sqlStatements) { + await client.query(st); + } +}); + +test('alter all role field', async (t) => { + const client = new PGlite(); + + const schema1 = { + manager: pgRole('manager'), + }; + + const schema2 = { + manager: pgRole('manager', { createDb: true, createRole: true, inherit: false }), + }; + + const { statements, sqlStatements } = await diffTestSchemasPush( + client, + schema1, + schema2, + [], + false, + ['public'], + undefined, + { roles: { include: ['manager'] } }, + ); + + expect(sqlStatements).toStrictEqual(['ALTER ROLE "manager" WITH CREATEDB CREATEROLE NOINHERIT;']); + expect(statements).toStrictEqual([ + { + name: 'manager', + type: 'alter_role', + values: { + createDb: true, + createRole: true, + inherit: false, + }, + }, + ]); + + for (const st of sqlStatements) { + await client.query(st); + } +}); + +test('alter createdb in role', async (t) => { + const client = new PGlite(); + + const schema1 = { + manager: pgRole('manager'), + }; + + const schema2 = { + manager: pgRole('manager', { createDb: true }), + }; + + const { statements, sqlStatements } = await diffTestSchemasPush( + client, + schema1, + schema2, + [], + false, + ['public'], + undefined, + { roles: { include: ['manager'] } }, + ); + + expect(sqlStatements).toStrictEqual(['ALTER ROLE "manager" WITH CREATEDB NOCREATEROLE INHERIT;']); + expect(statements).toStrictEqual([ + { + name: 'manager', + type: 'alter_role', + values: { + createDb: true, + createRole: false, + inherit: true, + }, + }, + ]); + + for (const st of sqlStatements) { + await client.query(st); + } +}); + +test('alter createrole in role', async (t) => { + const client = new PGlite(); + + const schema1 = { + manager: pgRole('manager'), + }; + + const schema2 = { + manager: pgRole('manager', { createRole: true }), + }; + + const { statements, sqlStatements } = await diffTestSchemasPush( + client, + schema1, + schema2, + [], + false, + ['public'], + undefined, + { roles: { include: ['manager'] } }, + ); + + expect(sqlStatements).toStrictEqual(['ALTER ROLE "manager" WITH NOCREATEDB CREATEROLE INHERIT;']); + expect(statements).toStrictEqual([ + { + name: 'manager', + type: 'alter_role', + values: { + createDb: false, + createRole: true, + inherit: true, + }, + }, + ]); + + for (const st of sqlStatements) { + await client.query(st); + } +}); + +test('alter inherit in role', async (t) => { + const client = new PGlite(); + + const schema1 = { + manager: pgRole('manager'), + }; + + const schema2 = { + manager: pgRole('manager', { inherit: false }), + }; + + const { statements, sqlStatements } = await diffTestSchemasPush( + client, + schema1, + schema2, + [], + false, + ['public'], + undefined, + { roles: { include: ['manager'] } }, + ); + + expect(sqlStatements).toStrictEqual(['ALTER ROLE "manager" WITH NOCREATEDB NOCREATEROLE NOINHERIT;']); + expect(statements).toStrictEqual([ + { + name: 'manager', + type: 'alter_role', + values: { + createDb: false, + createRole: false, + inherit: false, + }, + }, + ]); + + for (const st of sqlStatements) { + await client.query(st); + } +}); diff --git a/drizzle-kit/tests/rls/pg-policy.test.ts b/drizzle-kit/tests/rls/pg-policy.test.ts new file mode 100644 index 000000000..b42385e3e --- /dev/null +++ b/drizzle-kit/tests/rls/pg-policy.test.ts @@ -0,0 +1,1658 @@ +import { sql } from 'drizzle-orm'; +import { integer, pgPolicy, pgRole, pgSchema, pgTable } from 'drizzle-orm/pg-core'; +import { diffTestSchemas } from 'tests/schemaDiffer'; +import { expect, test } from 'vitest'; + +test('add policy + enable rls', async (t) => { + const schema1 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }), + }; + + const schema2 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'permissive' }), + })), + }; + + const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []); + + expect(sqlStatements).toStrictEqual([ + 'ALTER TABLE "users" ENABLE ROW LEVEL SECURITY;', + 'CREATE POLICY "test" ON "users" AS PERMISSIVE FOR ALL TO public;', + ]); + expect(statements).toStrictEqual([ + { + schema: '', + tableName: 'users', + type: 'enable_rls', + }, + { + data: { + as: 'PERMISSIVE', + for: 'ALL', + name: 'test', + to: ['public'], + on: undefined, + using: undefined, + withCheck: undefined, + }, + schema: '', + tableName: 'users', + type: 'create_policy', + }, + ]); +}); + +test('drop policy + disable rls', async (t) => { + const schema1 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'permissive' }), + })), + }; + + const schema2 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }), + }; + + const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []); + + expect(sqlStatements).toStrictEqual([ + 'ALTER TABLE "users" DISABLE ROW LEVEL SECURITY;', + 'DROP POLICY "test" ON "users" CASCADE;', + ]); + expect(statements).toStrictEqual([ + { + schema: '', + tableName: 'users', + type: 'disable_rls', + }, + { + data: { + as: 'PERMISSIVE', + for: 'ALL', + name: 'test', + to: ['public'], + on: undefined, + using: undefined, + withCheck: undefined, + }, + schema: '', + tableName: 'users', + type: 'drop_policy', + }, + ]); +}); + +test('add policy without enable rls', async (t) => { + const schema1 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'permissive' }), + })), + }; + + const schema2 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'permissive' }), + newrls: pgPolicy('newRls'), + })), + }; + + const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []); + + expect(sqlStatements).toStrictEqual([ + 'CREATE POLICY "newRls" ON "users" AS PERMISSIVE FOR ALL TO public;', + ]); + expect(statements).toStrictEqual([ + { + data: { + as: 'PERMISSIVE', + for: 'ALL', + name: 'newRls', + to: ['public'], + on: undefined, + using: undefined, + withCheck: undefined, + }, + schema: '', + tableName: 'users', + type: 'create_policy', + }, + ]); +}); + +test('drop policy without disable rls', async (t) => { + const schema1 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'permissive' }), + oldRls: pgPolicy('oldRls'), + })), + }; + + const schema2 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'permissive' }), + })), + }; + + const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []); + + expect(sqlStatements).toStrictEqual([ + 'DROP POLICY "oldRls" ON "users" CASCADE;', + ]); + expect(statements).toStrictEqual([ + { + data: { + as: 'PERMISSIVE', + for: 'ALL', + name: 'oldRls', + to: ['public'], + using: undefined, + on: undefined, + withCheck: undefined, + }, + schema: '', + tableName: 'users', + type: 'drop_policy', + }, + ]); +}); + +test('alter policy without recreation: changing roles', async (t) => { + const schema1 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'permissive' }), + })), + }; + + const schema2 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'permissive', to: 'current_role' }), + })), + }; + + const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []); + + expect(sqlStatements).toStrictEqual([ + 'ALTER POLICY "test" ON "users" TO current_role;', + ]); + expect(statements).toStrictEqual([ + { + newData: 'test--PERMISSIVE--ALL--current_role--undefined--undefined--undefined', + oldData: 'test--PERMISSIVE--ALL--public--undefined--undefined--undefined', + schema: '', + tableName: 'users', + type: 'alter_policy', + }, + ]); +}); + +test('alter policy without recreation: changing using', async (t) => { + const schema1 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'permissive' }), + })), + }; + + const schema2 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'permissive', using: sql`true` }), + })), + }; + + const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []); + + expect(sqlStatements).toStrictEqual([ + 'ALTER POLICY "test" ON "users" TO public USING (true);', + ]); + expect(statements).toStrictEqual([ + { + newData: 'test--PERMISSIVE--ALL--public--true--undefined--undefined', + oldData: 'test--PERMISSIVE--ALL--public--undefined--undefined--undefined', + schema: '', + tableName: 'users', + type: 'alter_policy', + }, + ]); +}); + +test('alter policy without recreation: changing with check', async (t) => { + const schema1 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'permissive' }), + })), + }; + + const schema2 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'permissive', withCheck: sql`true` }), + })), + }; + + const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []); + + expect(sqlStatements).toStrictEqual([ + 'ALTER POLICY "test" ON "users" TO public WITH CHECK (true);', + ]); + expect(statements).toStrictEqual([ + { + newData: 'test--PERMISSIVE--ALL--public--undefined--true--undefined', + oldData: 'test--PERMISSIVE--ALL--public--undefined--undefined--undefined', + schema: '', + tableName: 'users', + type: 'alter_policy', + }, + ]); +}); + +/// + +test('alter policy with recreation: changing as', async (t) => { + const schema1 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'permissive' }), + })), + }; + + const schema2 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'restrictive' }), + })), + }; + + const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []); + + expect(sqlStatements).toStrictEqual([ + 'DROP POLICY "test" ON "users" CASCADE;', + 'CREATE POLICY "test" ON "users" AS RESTRICTIVE FOR ALL TO public;', + ]); + expect(statements).toStrictEqual([ + { + data: { + as: 'PERMISSIVE', + for: 'ALL', + name: 'test', + to: ['public'], + using: undefined, + on: undefined, + withCheck: undefined, + }, + schema: '', + tableName: 'users', + type: 'drop_policy', + }, + { + data: { + as: 'RESTRICTIVE', + for: 'ALL', + name: 'test', + to: ['public'], + on: undefined, + using: undefined, + withCheck: undefined, + }, + schema: '', + tableName: 'users', + type: 'create_policy', + }, + ]); +}); + +test('alter policy with recreation: changing for', async (t) => { + const schema1 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'permissive' }), + })), + }; + + const schema2 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'permissive', for: 'delete' }), + })), + }; + + const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []); + + expect(sqlStatements).toStrictEqual([ + 'DROP POLICY "test" ON "users" CASCADE;', + 'CREATE POLICY "test" ON "users" AS PERMISSIVE FOR DELETE TO public;', + ]); + expect(statements).toStrictEqual([ + { + data: { + as: 'PERMISSIVE', + for: 'ALL', + name: 'test', + to: ['public'], + on: undefined, + using: undefined, + withCheck: undefined, + }, + schema: '', + tableName: 'users', + type: 'drop_policy', + }, + { + data: { + as: 'PERMISSIVE', + for: 'DELETE', + name: 'test', + to: ['public'], + on: undefined, + using: undefined, + withCheck: undefined, + }, + schema: '', + tableName: 'users', + type: 'create_policy', + }, + ]); +}); + +test('alter policy with recreation: changing both "as" and "for"', async (t) => { + const schema1 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'permissive' }), + })), + }; + + const schema2 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'restrictive', for: 'insert' }), + })), + }; + + const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []); + + expect(sqlStatements).toStrictEqual([ + 'DROP POLICY "test" ON "users" CASCADE;', + 'CREATE POLICY "test" ON "users" AS RESTRICTIVE FOR INSERT TO public;', + ]); + expect(statements).toStrictEqual([ + { + data: { + as: 'PERMISSIVE', + for: 'ALL', + name: 'test', + to: ['public'], + using: undefined, + on: undefined, + withCheck: undefined, + }, + schema: '', + tableName: 'users', + type: 'drop_policy', + }, + { + data: { + as: 'RESTRICTIVE', + for: 'INSERT', + name: 'test', + to: ['public'], + using: undefined, + on: undefined, + withCheck: undefined, + }, + schema: '', + tableName: 'users', + type: 'create_policy', + }, + ]); +}); + +test('alter policy with recreation: changing all fields', async (t) => { + const schema1 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'permissive', for: 'select', using: sql`true` }), + })), + }; + + const schema2 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'restrictive', to: 'current_role', withCheck: sql`true` }), + })), + }; + + const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []); + + expect(sqlStatements).toStrictEqual([ + 'DROP POLICY "test" ON "users" CASCADE;', + 'CREATE POLICY "test" ON "users" AS RESTRICTIVE FOR ALL TO current_role WITH CHECK (true);', + ]); + expect(statements).toStrictEqual([ + { + data: { + as: 'PERMISSIVE', + for: 'SELECT', + name: 'test', + to: ['public'], + using: 'true', + on: undefined, + withCheck: undefined, + }, + schema: '', + tableName: 'users', + type: 'drop_policy', + }, + { + data: { + as: 'RESTRICTIVE', + for: 'ALL', + name: 'test', + on: undefined, + to: ['current_role'], + using: undefined, + withCheck: 'true', + }, + schema: '', + tableName: 'users', + type: 'create_policy', + }, + ]); +}); + +test('rename policy', async (t) => { + const schema1 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'permissive' }), + })), + }; + + const schema2 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('newName', { as: 'permissive' }), + })), + }; + + const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, [ + 'public.users.test->public.users.newName', + ]); + + expect(sqlStatements).toStrictEqual([ + 'ALTER POLICY "test" ON "users" RENAME TO "newName";', + ]); + expect(statements).toStrictEqual([ + { + newName: 'newName', + oldName: 'test', + schema: '', + tableName: 'users', + type: 'rename_policy', + }, + ]); +}); + +test('rename policy in renamed table', async (t) => { + const schema1 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'permissive' }), + })), + }; + + const schema2 = { + users: pgTable('users2', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('newName', { as: 'permissive' }), + })), + }; + + const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, [ + 'public.users->public.users2', + 'public.users2.test->public.users2.newName', + ]); + + expect(sqlStatements).toStrictEqual([ + 'ALTER TABLE "users" RENAME TO "users2";', + 'ALTER POLICY "test" ON "users2" RENAME TO "newName";', + ]); + expect(statements).toStrictEqual([ + { + fromSchema: '', + tableNameFrom: 'users', + tableNameTo: 'users2', + toSchema: '', + type: 'rename_table', + }, + { + newName: 'newName', + oldName: 'test', + schema: '', + tableName: 'users2', + type: 'rename_policy', + }, + ]); +}); + +test('create table with a policy', async (t) => { + const schema1 = {}; + + const schema2 = { + users: pgTable('users2', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'permissive' }), + })), + }; + + const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []); + + expect(sqlStatements).toStrictEqual([ + 'CREATE TABLE IF NOT EXISTS "users2" (\n\t"id" integer PRIMARY KEY NOT NULL\n);\n', + 'ALTER TABLE "users2" ENABLE ROW LEVEL SECURITY;', + 'CREATE POLICY "test" ON "users2" AS PERMISSIVE FOR ALL TO public;', + ]); + expect(statements).toStrictEqual([ + { + columns: [ + { + name: 'id', + notNull: true, + primaryKey: true, + type: 'integer', + }, + ], + compositePKs: [], + checkConstraints: [], + compositePkName: '', + policies: [ + 'test--PERMISSIVE--ALL--public--undefined--undefined--undefined', + ], + schema: '', + tableName: 'users2', + isRLSEnabled: false, + type: 'create_table', + uniqueConstraints: [], + }, + { + data: { + as: 'PERMISSIVE', + for: 'ALL', + name: 'test', + to: [ + 'public', + ], + on: undefined, + using: undefined, + withCheck: undefined, + }, + schema: '', + tableName: 'users2', + type: 'create_policy', + }, + ]); +}); + +test('drop table with a policy', async (t) => { + const schema1 = { + users: pgTable('users2', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { as: 'permissive' }), + })), + }; + + const schema2 = {}; + + const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []); + + expect(sqlStatements).toStrictEqual([ + 'DROP POLICY "test" ON "users2" CASCADE;', + 'DROP TABLE "users2" CASCADE;', + ]); + expect(statements).toStrictEqual([ + { + policies: [ + 'test--PERMISSIVE--ALL--public--undefined--undefined--undefined', + ], + schema: '', + tableName: 'users2', + type: 'drop_table', + }, + ]); +}); + +test('add policy with multiple "to" roles', async (t) => { + const schema1 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }), + }; + + const role = pgRole('manager').existing(); + + const schema2 = { + role, + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { to: ['current_role', role] }), + })), + }; + + const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []); + + expect(sqlStatements).toStrictEqual([ + 'ALTER TABLE "users" ENABLE ROW LEVEL SECURITY;', + 'CREATE POLICY "test" ON "users" AS PERMISSIVE FOR ALL TO current_role, "manager";', + ]); + expect(statements).toStrictEqual([ + { + schema: '', + tableName: 'users', + type: 'enable_rls', + }, + { + data: { + as: 'PERMISSIVE', + for: 'ALL', + name: 'test', + on: undefined, + to: ['current_role', 'manager'], + using: undefined, + withCheck: undefined, + }, + schema: '', + tableName: 'users', + type: 'create_policy', + }, + ]); +}); + +test('create table with rls enabled', async (t) => { + const schema1 = {}; + + const schema2 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }).enableRLS(), + }; + + const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []); + + expect(sqlStatements).toStrictEqual([ + `CREATE TABLE IF NOT EXISTS "users" (\n\t"id" integer PRIMARY KEY NOT NULL\n); +`, + 'ALTER TABLE "users" ENABLE ROW LEVEL SECURITY;', + ]); + + console.log(statements); +}); + +test('enable rls force', async (t) => { + const schema1 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }), + }; + + const schema2 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }).enableRLS(), + }; + + const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []); + + expect(sqlStatements).toStrictEqual(['ALTER TABLE "users" ENABLE ROW LEVEL SECURITY;']); +}); + +test('disable rls force', async (t) => { + const schema1 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }).enableRLS(), + }; + + const schema2 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }), + }; + + const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []); + + expect(sqlStatements).toStrictEqual(['ALTER TABLE "users" DISABLE ROW LEVEL SECURITY;']); +}); + +test('drop policy with enabled rls', async (t) => { + const schema1 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { to: ['current_role', role] }), + })).enableRLS(), + }; + + const role = pgRole('manager').existing(); + + const schema2 = { + role, + users: pgTable('users', { + id: integer('id').primaryKey(), + }).enableRLS(), + }; + + const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []); + + expect(sqlStatements).toStrictEqual([ + 'DROP POLICY "test" ON "users" CASCADE;', + ]); +}); + +test('add policy with enabled rls', async (t) => { + const schema1 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }).enableRLS(), + }; + + const role = pgRole('manager').existing(); + + const schema2 = { + role, + users: pgTable('users', { + id: integer('id').primaryKey(), + }, () => ({ + rls: pgPolicy('test', { to: ['current_role', role] }), + })).enableRLS(), + }; + + const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []); + + expect(sqlStatements).toStrictEqual([ + 'CREATE POLICY "test" ON "users" AS PERMISSIVE FOR ALL TO current_role, "manager";', + ]); +}); + +test('add policy + link table', async (t) => { + const schema1 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }), + }; + + const users = pgTable('users', { + id: integer('id').primaryKey(), + }); + + const schema2 = { + users, + rls: pgPolicy('test', { as: 'permissive' }).link(users), + }; + + const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []); + + expect(sqlStatements).toStrictEqual([ + 'ALTER TABLE "users" ENABLE ROW LEVEL SECURITY;', + 'CREATE POLICY "test" ON "users" AS PERMISSIVE FOR ALL TO public;', + ]); + expect(statements).toStrictEqual([ + { + schema: '', + tableName: 'users', + type: 'enable_rls', + }, + { + data: { + as: 'PERMISSIVE', + for: 'ALL', + name: 'test', + to: ['public'], + on: undefined, + using: undefined, + withCheck: undefined, + }, + schema: '', + tableName: 'users', + type: 'create_policy', + }, + ]); +}); + +test('link table', async (t) => { + const schema1 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }), + rls: pgPolicy('test', { as: 'permissive' }), + }; + + const users = pgTable('users', { + id: integer('id').primaryKey(), + }); + + const schema2 = { + users, + rls: pgPolicy('test', { as: 'permissive' }).link(users), + }; + + const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []); + + expect(sqlStatements).toStrictEqual([ + 'ALTER TABLE "users" ENABLE ROW LEVEL SECURITY;', + 'CREATE POLICY "test" ON "users" AS PERMISSIVE FOR ALL TO public;', + ]); + expect(statements).toStrictEqual([ + { + schema: '', + tableName: 'users', + type: 'enable_rls', + }, + { + data: { + as: 'PERMISSIVE', + for: 'ALL', + name: 'test', + to: ['public'], + on: undefined, + using: undefined, + withCheck: undefined, + }, + schema: '', + tableName: 'users', + type: 'create_policy', + }, + ]); +}); + +test('unlink table', async (t) => { + const users = pgTable('users', { + id: integer('id').primaryKey(), + }); + + const schema1 = { + users, + rls: pgPolicy('test', { as: 'permissive' }).link(users), + }; + + const schema2 = { + users, + rls: pgPolicy('test', { as: 'permissive' }), + }; + + const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []); + + expect(sqlStatements).toStrictEqual([ + 'ALTER TABLE "users" DISABLE ROW LEVEL SECURITY;', + 'DROP POLICY "test" ON "users" CASCADE;', + ]); + expect(statements).toStrictEqual([ + { + schema: '', + tableName: 'users', + type: 'disable_rls', + }, + { + data: { + as: 'PERMISSIVE', + for: 'ALL', + name: 'test', + to: ['public'], + on: undefined, + using: undefined, + withCheck: undefined, + }, + schema: '', + tableName: 'users', + type: 'drop_policy', + }, + ]); +}); + +test('drop policy with link', async (t) => { + const users = pgTable('users', { + id: integer('id').primaryKey(), + }); + + const schema1 = { + users, + rls: pgPolicy('test', { as: 'permissive' }).link(users), + }; + + const schema2 = { + users, + }; + + const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []); + + expect(sqlStatements).toStrictEqual([ + 'ALTER TABLE "users" DISABLE ROW LEVEL SECURITY;', + 'DROP POLICY "test" ON "users" CASCADE;', + ]); + expect(statements).toStrictEqual([ + { + schema: '', + tableName: 'users', + type: 'disable_rls', + }, + { + data: { + as: 'PERMISSIVE', + for: 'ALL', + name: 'test', + to: ['public'], + on: undefined, + using: undefined, + withCheck: undefined, + }, + schema: '', + tableName: 'users', + type: 'drop_policy', + }, + ]); +}); + +test('add policy in table and with link table', async (t) => { + const schema1 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }), + }; + const users = pgTable('users', { + id: integer('id').primaryKey(), + }, () => [ + pgPolicy('test1', { to: 'current_user' }), + ]); + + const schema2 = { + users, + rls: pgPolicy('test', { as: 'permissive' }).link(users), + }; + + const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []); + + expect(sqlStatements).toStrictEqual([ + 'ALTER TABLE "users" ENABLE ROW LEVEL SECURITY;', + 'CREATE POLICY "test1" ON "users" AS PERMISSIVE FOR ALL TO current_user;', + 'CREATE POLICY "test" ON "users" AS PERMISSIVE FOR ALL TO public;', + ]); + expect(statements).toStrictEqual([ + { + schema: '', + tableName: 'users', + type: 'enable_rls', + }, + { + data: { + as: 'PERMISSIVE', + for: 'ALL', + name: 'test1', + to: ['current_user'], + on: undefined, + using: undefined, + withCheck: undefined, + }, + schema: '', + tableName: 'users', + type: 'create_policy', + }, + { + data: { + as: 'PERMISSIVE', + for: 'ALL', + name: 'test', + to: ['public'], + using: undefined, + on: undefined, + withCheck: undefined, + }, + schema: '', + tableName: 'users', + type: 'create_policy', + }, + ]); +}); + +test('link non-schema table', async (t) => { + const users = pgTable('users', { + id: integer('id').primaryKey(), + }); + + const schema1 = {}; + + const schema2 = { + rls: pgPolicy('test', { as: 'permissive' }).link(users), + }; + + const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []); + + expect(sqlStatements).toStrictEqual([ + 'CREATE POLICY "test" ON "public"."users" AS PERMISSIVE FOR ALL TO public;', + ]); + expect(statements).toStrictEqual([ + { + data: { + as: 'PERMISSIVE', + for: 'ALL', + name: 'test', + on: '"public"."users"', + to: [ + 'public', + ], + using: undefined, + withCheck: undefined, + }, + tableName: '"public"."users"', + type: 'create_ind_policy', + }, + ]); +}); + +test('unlink non-schema table', async (t) => { + const users = pgTable('users', { + id: integer('id').primaryKey(), + }); + + const schema1 = { + rls: pgPolicy('test', { as: 'permissive' }).link(users), + }; + + const schema2 = { + rls: pgPolicy('test', { as: 'permissive' }), + }; + + const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []); + + expect(sqlStatements).toStrictEqual([ + 'DROP POLICY "test" ON "public"."users" CASCADE;', + ]); + expect(statements).toStrictEqual([ + { + data: { + as: 'PERMISSIVE', + for: 'ALL', + name: 'test', + on: '"public"."users"', + to: [ + 'public', + ], + using: undefined, + withCheck: undefined, + }, + tableName: '"public"."users"', + type: 'drop_ind_policy', + }, + ]); +}); + +test('add policy + link non-schema table', async (t) => { + const schema1 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }), + }; + + const cities = pgTable('cities', { + id: integer('id').primaryKey(), + }); + + const schema2 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, (t) => [ + pgPolicy('test2'), + ]), + rls: pgPolicy('test', { as: 'permissive' }).link(cities), + }; + + const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []); + + expect(sqlStatements).toStrictEqual([ + 'ALTER TABLE "users" ENABLE ROW LEVEL SECURITY;', + 'CREATE POLICY "test2" ON "users" AS PERMISSIVE FOR ALL TO public;', + 'CREATE POLICY "test" ON "public"."cities" AS PERMISSIVE FOR ALL TO public;', + ]); + expect(statements).toStrictEqual([ + { + schema: '', + tableName: 'users', + type: 'enable_rls', + }, + { + data: { + as: 'PERMISSIVE', + for: 'ALL', + name: 'test2', + on: undefined, + to: [ + 'public', + ], + using: undefined, + withCheck: undefined, + }, + schema: '', + tableName: 'users', + type: 'create_policy', + }, + { + data: { + as: 'PERMISSIVE', + for: 'ALL', + name: 'test', + on: '"public"."cities"', + to: [ + 'public', + ], + using: undefined, + withCheck: undefined, + }, + tableName: '"public"."cities"', + type: 'create_ind_policy', + }, + ]); +}); + +test('add policy + link non-schema table from auth schema', async (t) => { + const schema1 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }), + }; + + const authSchema = pgSchema('auth'); + + const cities = authSchema.table('cities', { + id: integer('id').primaryKey(), + }); + + const schema2 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, (t) => [ + pgPolicy('test2'), + ]), + rls: pgPolicy('test', { as: 'permissive' }).link(cities), + }; + + const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []); + + expect(sqlStatements).toStrictEqual([ + 'ALTER TABLE "users" ENABLE ROW LEVEL SECURITY;', + 'CREATE POLICY "test2" ON "users" AS PERMISSIVE FOR ALL TO public;', + 'CREATE POLICY "test" ON "auth"."cities" AS PERMISSIVE FOR ALL TO public;', + ]); + expect(statements).toStrictEqual([ + { + schema: '', + tableName: 'users', + type: 'enable_rls', + }, + { + data: { + as: 'PERMISSIVE', + for: 'ALL', + name: 'test2', + on: undefined, + to: [ + 'public', + ], + using: undefined, + withCheck: undefined, + }, + schema: '', + tableName: 'users', + type: 'create_policy', + }, + { + data: { + as: 'PERMISSIVE', + for: 'ALL', + name: 'test', + on: '"auth"."cities"', + to: [ + 'public', + ], + using: undefined, + withCheck: undefined, + }, + tableName: '"auth"."cities"', + type: 'create_ind_policy', + }, + ]); +}); + +test('rename policy that is linked', async (t) => { + const users = pgTable('users', { + id: integer('id').primaryKey(), + }); + + const schema1 = { + rls: pgPolicy('test', { as: 'permissive' }).link(users), + }; + + const schema2 = { + rls: pgPolicy('newName', { as: 'permissive' }).link(users), + }; + + const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, [ + '"public"."users".test->"public"."users".newName', + ]); + + expect(sqlStatements).toStrictEqual([ + 'ALTER POLICY "test" ON "public"."users" RENAME TO "newName";', + ]); + expect(statements).toStrictEqual([ + { + newName: 'newName', + oldName: 'test', + tableKey: '"public"."users"', + type: 'rename_ind_policy', + }, + ]); +}); + +test('alter policy that is linked', async (t) => { + const users = pgTable('users', { + id: integer('id').primaryKey(), + }); + + const schema1 = { + rls: pgPolicy('test', { as: 'permissive' }).link(users), + }; + + const schema2 = { + rls: pgPolicy('test', { as: 'permissive', to: 'current_role' }).link(users), + }; + + const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []); + + expect(sqlStatements).toStrictEqual([ + 'ALTER POLICY "test" ON "public"."users" TO current_role;', + ]); + expect(statements).toStrictEqual([ + { + newData: { + as: 'PERMISSIVE', + for: 'ALL', + name: 'test', + on: '"public"."users"', + to: [ + 'current_role', + ], + using: undefined, + withCheck: undefined, + }, + oldData: { + as: 'PERMISSIVE', + for: 'ALL', + name: 'test', + on: '"public"."users"', + to: [ + 'public', + ], + using: undefined, + withCheck: undefined, + }, + type: 'alter_ind_policy', + }, + ]); +}); + +test('alter policy that is linked: withCheck', async (t) => { + const users = pgTable('users', { + id: integer('id').primaryKey(), + }); + + const schema1 = { + rls: pgPolicy('test', { as: 'permissive', withCheck: sql`true` }).link(users), + }; + + const schema2 = { + rls: pgPolicy('test', { as: 'permissive', withCheck: sql`false` }).link(users), + }; + + const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []); + + expect(sqlStatements).toStrictEqual([ + 'ALTER POLICY "test" ON "public"."users" TO public WITH CHECK (false);', + ]); + expect(statements).toStrictEqual([ + { + newData: { + as: 'PERMISSIVE', + for: 'ALL', + name: 'test', + on: '"public"."users"', + to: [ + 'public', + ], + using: undefined, + withCheck: 'false', + }, + oldData: { + as: 'PERMISSIVE', + for: 'ALL', + name: 'test', + on: '"public"."users"', + to: [ + 'public', + ], + using: undefined, + withCheck: 'true', + }, + type: 'alter_ind_policy', + }, + ]); +}); + +test('alter policy that is linked: using', async (t) => { + const users = pgTable('users', { + id: integer('id').primaryKey(), + }); + + const schema1 = { + rls: pgPolicy('test', { as: 'permissive', using: sql`true` }).link(users), + }; + + const schema2 = { + rls: pgPolicy('test', { as: 'permissive', using: sql`false` }).link(users), + }; + + const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []); + + expect(sqlStatements).toStrictEqual([ + 'ALTER POLICY "test" ON "public"."users" TO public USING (false);', + ]); + expect(statements).toStrictEqual([ + { + newData: { + as: 'PERMISSIVE', + for: 'ALL', + name: 'test', + on: '"public"."users"', + to: [ + 'public', + ], + using: 'false', + withCheck: undefined, + }, + oldData: { + as: 'PERMISSIVE', + for: 'ALL', + name: 'test', + on: '"public"."users"', + to: [ + 'public', + ], + using: 'true', + withCheck: undefined, + }, + type: 'alter_ind_policy', + }, + ]); +}); + +test('alter policy that is linked: using', async (t) => { + const users = pgTable('users', { + id: integer('id').primaryKey(), + }); + + const schema1 = { + rls: pgPolicy('test', { for: 'insert' }).link(users), + }; + + const schema2 = { + rls: pgPolicy('test', { for: 'delete' }).link(users), + }; + + const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []); + + expect(sqlStatements).toStrictEqual([ + 'DROP POLICY "test" ON "public"."users" CASCADE;', + 'CREATE POLICY "test" ON "public"."users" AS PERMISSIVE FOR DELETE TO public;', + ]); + expect(statements).toStrictEqual([ + { + data: { + as: 'PERMISSIVE', + for: 'INSERT', + name: 'test', + on: '"public"."users"', + to: [ + 'public', + ], + using: undefined, + withCheck: undefined, + }, + tableName: '"public"."users"', + type: 'drop_ind_policy', + }, + { + data: { + as: 'PERMISSIVE', + for: 'DELETE', + name: 'test', + on: '"public"."users"', + to: [ + 'public', + ], + using: undefined, + withCheck: undefined, + }, + tableName: '"public"."users"', + type: 'create_ind_policy', + }, + ]); +}); + +//// + +test('alter policy in the table', async (t) => { + const schema1 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, (t) => [ + pgPolicy('test', { as: 'permissive' }), + ]), + }; + + const schema2 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, (t) => [ + pgPolicy('test', { as: 'permissive', to: 'current_role' }), + ]), + }; + + const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []); + + expect(sqlStatements).toStrictEqual([ + 'ALTER POLICY "test" ON "users" TO current_role;', + ]); + expect(statements).toStrictEqual([ + { + newData: 'test--PERMISSIVE--ALL--current_role--undefined--undefined--undefined', + oldData: 'test--PERMISSIVE--ALL--public--undefined--undefined--undefined', + schema: '', + tableName: 'users', + type: 'alter_policy', + }, + ]); +}); + +test('alter policy in the table: withCheck', async (t) => { + const users = pgTable('users', { + id: integer('id').primaryKey(), + }); + + const schema1 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, (t) => [ + pgPolicy('test', { as: 'permissive', withCheck: sql`true` }), + ]), + }; + + const schema2 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, (t) => [ + pgPolicy('test', { as: 'permissive', withCheck: sql`false` }), + ]), + }; + + const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []); + + expect(sqlStatements).toStrictEqual([ + 'ALTER POLICY "test" ON "users" TO public WITH CHECK (false);', + ]); + expect(statements).toStrictEqual([ + { + newData: 'test--PERMISSIVE--ALL--public--undefined--false--undefined', + oldData: 'test--PERMISSIVE--ALL--public--undefined--true--undefined', + schema: '', + tableName: 'users', + type: 'alter_policy', + }, + ]); +}); + +test('alter policy in the table: using', async (t) => { + const users = pgTable('users', { + id: integer('id').primaryKey(), + }); + + const schema1 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, (t) => [ + pgPolicy('test', { as: 'permissive', using: sql`true` }), + ]), + }; + + const schema2 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, (t) => [ + pgPolicy('test', { as: 'permissive', using: sql`false` }), + ]), + }; + + const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []); + + expect(sqlStatements).toStrictEqual([ + 'ALTER POLICY "test" ON "users" TO public USING (false);', + ]); + expect(statements).toStrictEqual([ + { + newData: 'test--PERMISSIVE--ALL--public--false--undefined--undefined', + oldData: 'test--PERMISSIVE--ALL--public--true--undefined--undefined', + schema: '', + tableName: 'users', + type: 'alter_policy', + }, + ]); +}); + +test('alter policy in the table: using', async (t) => { + const users = pgTable('users', { + id: integer('id').primaryKey(), + }); + + const schema1 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, (t) => [ + pgPolicy('test', { for: 'insert' }), + ]), + }; + + const schema2 = { + users: pgTable('users', { + id: integer('id').primaryKey(), + }, (t) => [ + pgPolicy('test', { for: 'delete' }), + ]), + }; + + const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []); + + expect(sqlStatements).toStrictEqual([ + 'DROP POLICY "test" ON "users" CASCADE;', + 'CREATE POLICY "test" ON "users" AS PERMISSIVE FOR DELETE TO public;', + ]); + expect(statements).toStrictEqual([ + { + data: { + as: 'PERMISSIVE', + for: 'INSERT', + name: 'test', + on: undefined, + to: [ + 'public', + ], + using: undefined, + withCheck: undefined, + }, + schema: '', + tableName: 'users', + type: 'drop_policy', + }, + { + data: { + as: 'PERMISSIVE', + for: 'DELETE', + name: 'test', + on: undefined, + to: [ + 'public', + ], + using: undefined, + withCheck: undefined, + }, + schema: '', + tableName: 'users', + type: 'create_policy', + }, + ]); +}); diff --git a/drizzle-kit/tests/rls/pg-role.test.ts b/drizzle-kit/tests/rls/pg-role.test.ts new file mode 100644 index 000000000..a6b762955 --- /dev/null +++ b/drizzle-kit/tests/rls/pg-role.test.ts @@ -0,0 +1,234 @@ +import { pgRole } from 'drizzle-orm/pg-core'; +import { diffTestSchemas } from 'tests/schemaDiffer'; +import { expect, test } from 'vitest'; + +test('create role', async (t) => { + const schema1 = {}; + + const schema2 = { + manager: pgRole('manager'), + }; + + const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []); + + expect(sqlStatements).toStrictEqual(['CREATE ROLE "manager";']); + expect(statements).toStrictEqual([ + { + name: 'manager', + type: 'create_role', + values: { + createDb: false, + createRole: false, + inherit: true, + }, + }, + ]); +}); + +test('create role with properties', async (t) => { + const schema1 = {}; + + const schema2 = { + manager: pgRole('manager', { createDb: true, inherit: false, createRole: true }), + }; + + const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []); + + expect(sqlStatements).toStrictEqual(['CREATE ROLE "manager" WITH CREATEDB CREATEROLE NOINHERIT;']); + expect(statements).toStrictEqual([ + { + name: 'manager', + type: 'create_role', + values: { + createDb: true, + createRole: true, + inherit: false, + }, + }, + ]); +}); + +test('create role with some properties', async (t) => { + const schema1 = {}; + + const schema2 = { + manager: pgRole('manager', { createDb: true, inherit: false }), + }; + + const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []); + + expect(sqlStatements).toStrictEqual(['CREATE ROLE "manager" WITH CREATEDB NOINHERIT;']); + expect(statements).toStrictEqual([ + { + name: 'manager', + type: 'create_role', + values: { + createDb: true, + createRole: false, + inherit: false, + }, + }, + ]); +}); + +test('drop role', async (t) => { + const schema1 = { manager: pgRole('manager') }; + + const schema2 = {}; + + const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []); + + expect(sqlStatements).toStrictEqual(['DROP ROLE "manager";']); + expect(statements).toStrictEqual([ + { + name: 'manager', + type: 'drop_role', + }, + ]); +}); + +test('create and drop role', async (t) => { + const schema1 = { + manager: pgRole('manager'), + }; + + const schema2 = { + admin: pgRole('admin'), + }; + + const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []); + + expect(sqlStatements).toStrictEqual(['DROP ROLE "manager";', 'CREATE ROLE "admin";']); + expect(statements).toStrictEqual([ + { + name: 'manager', + type: 'drop_role', + }, + { + name: 'admin', + type: 'create_role', + values: { + createDb: false, + createRole: false, + inherit: true, + }, + }, + ]); +}); + +test('rename role', async (t) => { + const schema1 = { + manager: pgRole('manager'), + }; + + const schema2 = { + admin: pgRole('admin'), + }; + + const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, ['manager->admin']); + + expect(sqlStatements).toStrictEqual(['ALTER ROLE "manager" RENAME TO "admin";']); + expect(statements).toStrictEqual([ + { nameFrom: 'manager', nameTo: 'admin', type: 'rename_role' }, + ]); +}); + +test('alter all role field', async (t) => { + const schema1 = { + manager: pgRole('manager'), + }; + + const schema2 = { + manager: pgRole('manager', { createDb: true, createRole: true, inherit: false }), + }; + + const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []); + + expect(sqlStatements).toStrictEqual(['ALTER ROLE "manager" WITH CREATEDB CREATEROLE NOINHERIT;']); + expect(statements).toStrictEqual([ + { + name: 'manager', + type: 'alter_role', + values: { + createDb: true, + createRole: true, + inherit: false, + }, + }, + ]); +}); + +test('alter createdb in role', async (t) => { + const schema1 = { + manager: pgRole('manager'), + }; + + const schema2 = { + manager: pgRole('manager', { createDb: true }), + }; + + const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []); + + expect(sqlStatements).toStrictEqual(['ALTER ROLE "manager" WITH CREATEDB NOCREATEROLE INHERIT;']); + expect(statements).toStrictEqual([ + { + name: 'manager', + type: 'alter_role', + values: { + createDb: true, + createRole: false, + inherit: true, + }, + }, + ]); +}); + +test('alter createrole in role', async (t) => { + const schema1 = { + manager: pgRole('manager'), + }; + + const schema2 = { + manager: pgRole('manager', { createRole: true }), + }; + + const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []); + + expect(sqlStatements).toStrictEqual(['ALTER ROLE "manager" WITH NOCREATEDB CREATEROLE INHERIT;']); + expect(statements).toStrictEqual([ + { + name: 'manager', + type: 'alter_role', + values: { + createDb: false, + createRole: true, + inherit: true, + }, + }, + ]); +}); + +test('alter inherit in role', async (t) => { + const schema1 = { + manager: pgRole('manager'), + }; + + const schema2 = { + manager: pgRole('manager', { inherit: false }), + }; + + const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []); + + expect(sqlStatements).toStrictEqual(['ALTER ROLE "manager" WITH NOCREATEDB NOCREATEROLE NOINHERIT;']); + expect(statements).toStrictEqual([ + { + name: 'manager', + type: 'alter_role', + values: { + createDb: false, + createRole: false, + inherit: false, + }, + }, + ]); +}); diff --git a/drizzle-kit/tests/schemaDiffer.ts b/drizzle-kit/tests/schemaDiffer.ts index 3001887e1..441318767 100644 --- a/drizzle-kit/tests/schemaDiffer.ts +++ b/drizzle-kit/tests/schemaDiffer.ts @@ -1,7 +1,6 @@ import { PGlite } from '@electric-sql/pglite'; import { Client } from '@libsql/client/.'; import { Database } from 'better-sqlite3'; -import { randomUUID } from 'crypto'; import { is } from 'drizzle-orm'; import { MySqlSchema, MySqlTable, MySqlView } from 'drizzle-orm/mysql-core'; import { @@ -12,6 +11,8 @@ import { isPgView, PgEnum, PgMaterializedView, + PgPolicy, + PgRole, PgSchema, PgSequence, PgTable, @@ -24,8 +25,11 @@ import { libSqlLogSuggestionsAndReturn } from 'src/cli/commands/libSqlPushUtils' import { columnsResolver, enumsResolver, + indPolicyResolver, mySqlViewsResolver, Named, + policyResolver, + roleResolver, schemasResolver, sequencesResolver, sqliteViewsResolver, @@ -34,6 +38,7 @@ import { } from 'src/cli/commands/migrate'; import { pgSuggestions } from 'src/cli/commands/pgPushUtils'; import { logSuggestionsAndReturn } from 'src/cli/commands/sqlitePushUtils'; +import { Entities } from 'src/cli/validations/cli'; import { CasingType } from 'src/cli/validations/common'; import { schemaToTypeScript as schemaToTypeScriptMySQL } from 'src/introspect-mysql'; import { schemaToTypeScript } from 'src/introspect-pg'; @@ -43,7 +48,7 @@ import { mysqlSchema, squashMysqlScheme, ViewSquashed } from 'src/serializer/mys import { generateMySqlSnapshot } from 'src/serializer/mysqlSerializer'; import { fromDatabase as fromMySqlDatabase } from 'src/serializer/mysqlSerializer'; import { prepareFromPgImports } from 'src/serializer/pgImports'; -import { pgSchema, squashPgScheme, View } from 'src/serializer/pgSchema'; +import { pgSchema, PgSquasher, Policy, Role, squashPgScheme, View } from 'src/serializer/pgSchema'; import { fromDatabase, generatePgSnapshot } from 'src/serializer/pgSerializer'; import { prepareFromSqliteImports } from 'src/serializer/sqliteImports'; import { sqliteSchema, squashSqliteScheme, View as SqliteView } from 'src/serializer/sqliteSchema'; @@ -58,16 +63,22 @@ import { ColumnsResolverInput, ColumnsResolverOutput, Enum, + PolicyResolverInput, + PolicyResolverOutput, ResolverInput, ResolverOutput, ResolverOutputWithMoved, + RolesResolverInput, + RolesResolverOutput, Sequence, Table, + TablePolicyResolverInput, + TablePolicyResolverOutput, } from 'src/snapshotsDiffer'; export type PostgresSchema = Record< string, - PgTable | PgEnum | PgSchema | PgSequence | PgView | PgMaterializedView + PgTable | PgEnum | PgSchema | PgSequence | PgView | PgMaterializedView | PgRole | PgPolicy >; export type MysqlSchema = Record | MySqlSchema | MySqlView>; export type SqliteSchema = Record | SQLiteView>; @@ -395,6 +406,186 @@ export const testColumnsResolver = } }; +export const testPolicyResolver = (renames: Set) => +async ( + input: TablePolicyResolverInput, +): Promise> => { + try { + if ( + input.created.length === 0 + || input.deleted.length === 0 + || renames.size === 0 + ) { + return { + tableName: input.tableName, + schema: input.schema, + created: input.created, + renamed: [], + deleted: input.deleted, + }; + } + + let createdPolicies = [...input.created]; + let deletedPolicies = [...input.deleted]; + + const renamed: { from: Policy; to: Policy }[] = []; + + const schema = input.schema || 'public'; + + for (let rename of renames) { + const [from, to] = rename.split('->'); + + const idxFrom = deletedPolicies.findIndex((it) => { + return `${schema}.${input.tableName}.${it.name}` === from; + }); + + if (idxFrom >= 0) { + const idxTo = createdPolicies.findIndex((it) => { + return `${schema}.${input.tableName}.${it.name}` === to; + }); + + renamed.push({ + from: deletedPolicies[idxFrom], + to: createdPolicies[idxTo], + }); + + delete createdPolicies[idxTo]; + delete deletedPolicies[idxFrom]; + + createdPolicies = createdPolicies.filter(Boolean); + deletedPolicies = deletedPolicies.filter(Boolean); + } + } + + return { + tableName: input.tableName, + schema: input.schema, + created: createdPolicies, + deleted: deletedPolicies, + renamed, + }; + } catch (e) { + console.error(e); + throw e; + } +}; + +export const testIndPolicyResolver = (renames: Set) => +async ( + input: PolicyResolverInput, +): Promise> => { + try { + if ( + input.created.length === 0 + || input.deleted.length === 0 + || renames.size === 0 + ) { + return { + created: input.created, + renamed: [], + deleted: input.deleted, + }; + } + + let createdPolicies = [...input.created]; + let deletedPolicies = [...input.deleted]; + + const renamed: { from: Policy; to: Policy }[] = []; + + for (let rename of renames) { + const [from, to] = rename.split('->'); + + const idxFrom = deletedPolicies.findIndex((it) => { + return `${it.on}.${it.name}` === from; + }); + + if (idxFrom >= 0) { + const idxTo = createdPolicies.findIndex((it) => { + return `${it.on}.${it.name}` === to; + }); + + renamed.push({ + from: deletedPolicies[idxFrom], + to: createdPolicies[idxTo], + }); + + delete createdPolicies[idxTo]; + delete deletedPolicies[idxFrom]; + + createdPolicies = createdPolicies.filter(Boolean); + deletedPolicies = deletedPolicies.filter(Boolean); + } + } + + return { + created: createdPolicies, + deleted: deletedPolicies, + renamed, + }; + } catch (e) { + console.error(e); + throw e; + } +}; + +export const testRolesResolver = (renames: Set) => +async ( + input: RolesResolverInput, +): Promise> => { + try { + if ( + input.created.length === 0 + || input.deleted.length === 0 + || renames.size === 0 + ) { + return { + created: input.created, + renamed: [], + deleted: input.deleted, + }; + } + + let createdPolicies = [...input.created]; + let deletedPolicies = [...input.deleted]; + + const renamed: { from: Policy; to: Policy }[] = []; + + for (let rename of renames) { + const [from, to] = rename.split('->'); + + const idxFrom = deletedPolicies.findIndex((it) => { + return `${it.name}` === from; + }); + + if (idxFrom >= 0) { + const idxTo = createdPolicies.findIndex((it) => { + return `${it.name}` === to; + }); + + renamed.push({ + from: deletedPolicies[idxFrom], + to: createdPolicies[idxTo], + }); + + delete createdPolicies[idxTo]; + delete deletedPolicies[idxFrom]; + + createdPolicies = createdPolicies.filter(Boolean); + deletedPolicies = deletedPolicies.filter(Boolean); + } + } + + return { + created: createdPolicies, + deleted: deletedPolicies, + renamed, + }; + } catch (e) { + console.error(e); + throw e; + } +}; + export const testViewsResolver = (renames: Set) => async (input: ResolverInput): Promise> => { try { @@ -606,6 +797,7 @@ export const diffTestSchemasPush = async ( cli: boolean = false, schemas: string[] = ['public'], casing?: CasingType | undefined, + entities?: Entities, sqlStatementsToRun: { before?: string[]; after?: string[]; runApply?: boolean } = { before: [], after: [], @@ -655,6 +847,7 @@ export const diffTestSchemasPush = async ( }, undefined, schemas, + entities, ); const leftTables = Object.values(right).filter((it) => is(it, PgTable)) as PgTable[]; @@ -665,6 +858,10 @@ export const diffTestSchemasPush = async ( const leftSequences = Object.values(right).filter((it) => isPgSequence(it)) as PgSequence[]; + const leftRoles = Object.values(right).filter((it) => is(it, PgRole)) as PgRole[]; + + const leftPolicies = Object.values(right).filter((it) => is(it, PgPolicy)) as PgPolicy[]; + const leftViews = Object.values(right).filter((it) => isPgView(it)) as PgView[]; const leftMaterializedViews = Object.values(right).filter((it) => isPgMaterializedView(it)) as PgMaterializedView[]; @@ -674,6 +871,8 @@ export const diffTestSchemasPush = async ( leftEnums, leftSchemas, leftSequences, + leftRoles, + leftPolicies, leftViews, leftMaterializedViews, casing, @@ -713,6 +912,9 @@ export const diffTestSchemasPush = async ( testSchemasResolver(renames), testEnumsResolver(renames), testSequencesResolver(renames), + testPolicyResolver(renames), + testIndPolicyResolver(renames), + testRolesResolver(renames), testTablesResolver(renames), testColumnsResolver(renames), testViewsResolver(renames), @@ -757,6 +959,9 @@ export const diffTestSchemasPush = async ( schemasResolver, enumsResolver, sequencesResolver, + policyResolver, + indPolicyResolver, + roleResolver, tablesResolver, columnsResolver, viewsResolver, @@ -779,6 +984,8 @@ export const applyPgDiffs = async (sn: PostgresSchema, casing: CasingType | unde views: {}, schemas: {}, sequences: {}, + policies: {}, + roles: {}, _meta: { schemas: {}, tables: {}, @@ -794,11 +1001,25 @@ export const applyPgDiffs = async (sn: PostgresSchema, casing: CasingType | unde const sequences = Object.values(sn).filter((it) => isPgSequence(it)) as PgSequence[]; + const roles = Object.values(sn).filter((it) => is(it, PgRole)) as PgRole[]; + const views = Object.values(sn).filter((it) => isPgView(it)) as PgView[]; + const policies = Object.values(sn).filter((it) => is(it, PgPolicy)) as PgPolicy[]; + const materializedViews = Object.values(sn).filter((it) => isPgMaterializedView(it)) as PgMaterializedView[]; - const serialized1 = generatePgSnapshot(tables, enums, schemas, sequences, views, materializedViews, casing); + const serialized1 = generatePgSnapshot( + tables, + enums, + schemas, + sequences, + roles, + policies, + views, + materializedViews, + casing, + ); const { version: v1, dialect: d1, ...rest1 } = serialized1; @@ -821,6 +1042,9 @@ export const applyPgDiffs = async (sn: PostgresSchema, casing: CasingType | unde testSchemasResolver(new Set()), testEnumsResolver(new Set()), testSequencesResolver(new Set()), + testPolicyResolver(new Set()), + testIndPolicyResolver(new Set()), + testRolesResolver(new Set()), testTablesResolver(new Set()), testColumnsResolver(new Set()), testViewsResolver(new Set()), @@ -853,6 +1077,14 @@ export const diffTestSchemas = async ( const rightSequences = Object.values(right).filter((it) => isPgSequence(it)) as PgSequence[]; + const leftRoles = Object.values(left).filter((it) => is(it, PgRole)) as PgRole[]; + + const rightRoles = Object.values(right).filter((it) => is(it, PgRole)) as PgRole[]; + + const leftPolicies = Object.values(left).filter((it) => is(it, PgPolicy)) as PgPolicy[]; + + const rightPolicies = Object.values(right).filter((it) => is(it, PgPolicy)) as PgPolicy[]; + const leftViews = Object.values(left).filter((it) => isPgView(it)) as PgView[]; const rightViews = Object.values(right).filter((it) => isPgView(it)) as PgView[]; @@ -866,6 +1098,8 @@ export const diffTestSchemas = async ( leftEnums, leftSchemas, leftSequences, + leftRoles, + leftPolicies, leftViews, leftMaterializedViews, casing, @@ -875,6 +1109,8 @@ export const diffTestSchemas = async ( rightEnums, rightSchemas, rightSequences, + rightRoles, + rightPolicies, rightViews, rightMaterializedViews, casing, @@ -914,6 +1150,9 @@ export const diffTestSchemas = async ( testSchemasResolver(renames), testEnumsResolver(renames), testSequencesResolver(renames), + testPolicyResolver(renames), + testIndPolicyResolver(renames), + testRolesResolver(renames), testTablesResolver(renames), testColumnsResolver(renames), testViewsResolver(renames), @@ -928,6 +1167,9 @@ export const diffTestSchemas = async ( schemasResolver, enumsResolver, sequencesResolver, + policyResolver, + indPolicyResolver, + roleResolver, tablesResolver, columnsResolver, viewsResolver, @@ -1626,6 +1868,7 @@ export const introspectPgToFile = async ( initSchema: PostgresSchema, testName: string, schemas: string[] = ['public'], + entities?: Entities, casing?: CasingType | undefined, ) => { // put in db @@ -1644,6 +1887,7 @@ export const introspectPgToFile = async ( }, undefined, schemas, + entities, ); const { version: initV, dialect: initD, ...initRest } = introspectedSchema; @@ -1672,6 +1916,8 @@ export const introspectPgToFile = async ( response.enums, response.schemas, response.sequences, + response.roles, + response.policies, response.views, response.matViews, casing, @@ -1696,6 +1942,9 @@ export const introspectPgToFile = async ( testSchemasResolver(new Set()), testEnumsResolver(new Set()), testSequencesResolver(new Set()), + testPolicyResolver(new Set()), + testIndPolicyResolver(new Set()), + testRolesResolver(new Set()), testTablesResolver(new Set()), testColumnsResolver(new Set()), testViewsResolver(new Set()), diff --git a/drizzle-kit/tests/sqlite-tables.test.ts b/drizzle-kit/tests/sqlite-tables.test.ts index 0390ff28e..8d8eae298 100644 --- a/drizzle-kit/tests/sqlite-tables.test.ts +++ b/drizzle-kit/tests/sqlite-tables.test.ts @@ -159,6 +159,7 @@ test('add table #6', async () => { type: 'drop_table', tableName: 'users1', schema: undefined, + policies: [], }); }); diff --git a/drizzle-kit/tests/testmysql.ts b/drizzle-kit/tests/testmysql.ts deleted file mode 100644 index 092f0a9e1..000000000 --- a/drizzle-kit/tests/testmysql.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { index, mysqlTable, text } from 'drizzle-orm/mysql-core'; -import { diffTestSchemasMysql } from './schemaDiffer'; - -const from = { - users: mysqlTable( - 'table', - { - name: text('name'), - }, - (t) => { - return { - idx: index('name_idx').on(t.name), - }; - }, - ), -}; - -const to = { - users: mysqlTable('table', { - name: text('name'), - }), -}; - -const { statements, sqlStatements } = await diffTestSchemasMysql(from, to, []); - -console.log(statements); -console.log(sqlStatements); diff --git a/drizzle-kit/tests/testsqlite.ts b/drizzle-kit/tests/testsqlite.ts deleted file mode 100644 index e68bbc195..000000000 --- a/drizzle-kit/tests/testsqlite.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { sqliteTable, text } from 'drizzle-orm/sqlite-core'; -import { diffTestSchemasMysql, diffTestSchemasSqlite } from './schemaDiffer'; - -const from = { - users: sqliteTable('table', { - password: text('password'), - }), -}; - -const to = { - users: sqliteTable('table1', { - password_hash: text('password_hash'), - }), -}; - -const { statements, sqlStatements } = await diffTestSchemasSqlite(from, to, [], true); - -console.log(statements); -console.log(sqlStatements); diff --git a/drizzle-kit/tsconfig.build.json b/drizzle-kit/tsconfig.build.json new file mode 100644 index 000000000..b57ab6b00 --- /dev/null +++ b/drizzle-kit/tsconfig.build.json @@ -0,0 +1,4 @@ +{ + "extends": "./tsconfig.json", + "include": ["src"] +} diff --git a/drizzle-orm/package.json b/drizzle-orm/package.json index 8622fea11..e2b17a1af 100644 --- a/drizzle-orm/package.json +++ b/drizzle-orm/package.json @@ -1,10 +1,11 @@ { "name": "drizzle-orm", - "version": "0.35.3", + "version": "0.36.0", "description": "Drizzle ORM package for SQL databases", "type": "module", "scripts": { - "build": "scripts/build.ts", + "p": "prisma generate --schema src/prisma/schema.prisma", + "build": "pnpm p && scripts/build.ts", "b": "pnpm build", "test:types": "cd type-tests && tsc", "test": "vitest run", @@ -45,7 +46,7 @@ "peerDependencies": { "@aws-sdk/client-rds-data": ">=3", "@cloudflare/workers-types": ">=3", - "@electric-sql/pglite": ">=0.1.1", + "@electric-sql/pglite": ">=0.2.0", "@libsql/client": ">=0.10.0", "@libsql/client-wasm": ">=0.10.0", "@neondatabase/serverless": ">=0.1", @@ -130,6 +131,9 @@ "@libsql/client": { "optional": true }, + "@libsql/client-wasm": { + "optional": true + }, "@opentelemetry/api": { "optional": true }, diff --git a/drizzle-orm/src/neon/index.ts b/drizzle-orm/src/neon/index.ts new file mode 100644 index 000000000..ee201ff1c --- /dev/null +++ b/drizzle-orm/src/neon/index.ts @@ -0,0 +1 @@ +export * from './rls.ts'; diff --git a/drizzle-orm/src/neon/rls.ts b/drizzle-orm/src/neon/rls.ts new file mode 100644 index 000000000..16e22f449 --- /dev/null +++ b/drizzle-orm/src/neon/rls.ts @@ -0,0 +1,93 @@ +import { is } from '~/entity.ts'; +import { type AnyPgColumn, pgPolicy, type PgPolicyToOption } from '~/pg-core/index.ts'; +import { PgRole, pgRole } from '~/pg-core/roles.ts'; +import { type SQL, sql } from '~/sql/sql.ts'; + +/** + * Generates a set of PostgreSQL row-level security (RLS) policies for CRUD operations based on the provided options. + * + * @param options - An object containing the policy configuration. + * @param options.role - The PostgreSQL role(s) to apply the policy to. Can be a single `PgRole` instance or an array of `PgRole` instances or role names. + * @param options.read - The SQL expression or boolean value that defines the read policy. Set to `true` to allow all reads, `false` to deny all reads, or provide a custom SQL expression. Set to `null` to prevent the policy from being generated. + * @param options.modify - The SQL expression or boolean value that defines the modify (insert, update, delete) policies. Set to `true` to allow all modifications, `false` to deny all modifications, or provide a custom SQL expression. Set to `null` to prevent policies from being generated. + * @returns An array of PostgreSQL policy definitions, one for each CRUD operation. + */ +export const crudPolicy = (options: { + role: PgPolicyToOption; + read: SQL | boolean | null; + modify: SQL | boolean | null; +}) => { + if (options.read === undefined) { + throw new Error('crudPolicy requires a read policy'); + } + + if (options.modify === undefined) { + throw new Error('crudPolicy requires a modify policy'); + } + + let read: SQL | undefined; + if (options.read === true) { + read = sql`true`; + } else if (options.read === false) { + read = sql`false`; + } else if (options.read !== null) { + read = options.read; + } + + let modify: SQL | undefined; + if (options.modify === true) { + modify = sql`true`; + } else if (options.modify === false) { + modify = sql`false`; + } else if (options.modify !== null) { + modify = options.modify; + } + + let rolesName = ''; + if (Array.isArray(options.role)) { + rolesName = options.role + .map((it) => { + return is(it, PgRole) ? it.name : (it as string); + }) + .join('-'); + } else { + rolesName = is(options.role, PgRole) + ? options.role.name + : (options.role as string); + } + + return [ + read + && pgPolicy(`crud-${rolesName}-policy-select`, { + for: 'select', + to: options.role, + using: read, + }), + + modify + && pgPolicy(`crud-${rolesName}-policy-insert`, { + for: 'insert', + to: options.role, + withCheck: modify, + }), + modify + && pgPolicy(`crud-${rolesName}-policy-update`, { + for: 'update', + to: options.role, + using: modify, + withCheck: modify, + }), + modify + && pgPolicy(`crud-${rolesName}-policy-delete`, { + for: 'delete', + to: options.role, + using: modify, + }), + ].filter(Boolean); +}; + +// These are default roles that Neon will set up. +export const authenticatedRole = pgRole('authenticated').existing(); +export const anonymousRole = pgRole('anonymous').existing(); + +export const authUid = (userIdColumn: AnyPgColumn) => sql`(select auth.user_id() = ${userIdColumn})`; diff --git a/drizzle-orm/src/pg-core/index.ts b/drizzle-orm/src/pg-core/index.ts index 084633c4a..ebc436bc1 100644 --- a/drizzle-orm/src/pg-core/index.ts +++ b/drizzle-orm/src/pg-core/index.ts @@ -5,8 +5,10 @@ export * from './db.ts'; export * from './dialect.ts'; export * from './foreign-keys.ts'; export * from './indexes.ts'; +export * from './policies.ts'; export * from './primary-keys.ts'; export * from './query-builders/index.ts'; +export * from './roles.ts'; export * from './schema.ts'; export * from './sequence.ts'; export * from './session.ts'; diff --git a/drizzle-orm/src/pg-core/policies.ts b/drizzle-orm/src/pg-core/policies.ts new file mode 100644 index 000000000..9c2f94f28 --- /dev/null +++ b/drizzle-orm/src/pg-core/policies.ts @@ -0,0 +1,56 @@ +import { entityKind } from '~/entity.ts'; +import type { SQL } from '~/sql/sql.ts'; +import type { PgRole } from './roles.ts'; +import type { PgTable } from './table.ts'; + +export type PgPolicyToOption = + | 'public' + | 'current_role' + | 'current_user' + | 'session_user' + | (string & {}) + | PgPolicyToOption[] + | PgRole; + +export interface PgPolicyConfig { + as?: 'permissive' | 'restrictive'; + for?: 'all' | 'select' | 'insert' | 'update' | 'delete'; + to?: PgPolicyToOption; + using?: SQL; + withCheck?: SQL; +} + +export class PgPolicy implements PgPolicyConfig { + static readonly [entityKind]: string = 'PgPolicy'; + + readonly as: PgPolicyConfig['as']; + readonly for: PgPolicyConfig['for']; + readonly to: PgPolicyConfig['to']; + readonly using: PgPolicyConfig['using']; + readonly withCheck: PgPolicyConfig['withCheck']; + + /** @internal */ + _linkedTable?: PgTable; + + constructor( + readonly name: string, + config?: PgPolicyConfig, + ) { + if (config) { + this.as = config.as; + this.for = config.for; + this.to = config.to; + this.using = config.using; + this.withCheck = config.withCheck; + } + } + + link(table: PgTable): this { + this._linkedTable = table; + return this; + } +} + +export function pgPolicy(name: string, config?: PgPolicyConfig) { + return new PgPolicy(name, config); +} diff --git a/drizzle-orm/src/pg-core/roles.ts b/drizzle-orm/src/pg-core/roles.ts new file mode 100644 index 000000000..a2c77c303 --- /dev/null +++ b/drizzle-orm/src/pg-core/roles.ts @@ -0,0 +1,41 @@ +import { entityKind } from '~/entity.ts'; + +export interface PgRoleConfig { + createDb?: boolean; + createRole?: boolean; + inherit?: boolean; +} + +export class PgRole implements PgRoleConfig { + static readonly [entityKind]: string = 'PgRole'; + + /** @internal */ + _existing?: boolean; + + /** @internal */ + readonly createDb: PgRoleConfig['createDb']; + /** @internal */ + readonly createRole: PgRoleConfig['createRole']; + /** @internal */ + readonly inherit: PgRoleConfig['inherit']; + + constructor( + readonly name: string, + config?: PgRoleConfig, + ) { + if (config) { + this.createDb = config.createDb; + this.createRole = config.createRole; + this.inherit = config.inherit; + } + } + + existing(): this { + this._existing = true; + return this; + } +} + +export function pgRole(name: string, config?: PgRoleConfig) { + return new PgRole(name, config); +} diff --git a/drizzle-orm/src/pg-core/table.ts b/drizzle-orm/src/pg-core/table.ts index 5bf9a9895..c3c34c577 100644 --- a/drizzle-orm/src/pg-core/table.ts +++ b/drizzle-orm/src/pg-core/table.ts @@ -6,22 +6,29 @@ import { getPgColumnBuilders, type PgColumnsBuilders } from './columns/all.ts'; import type { PgColumn, PgColumnBuilder, PgColumnBuilderBase } from './columns/common.ts'; import type { ForeignKey, ForeignKeyBuilder } from './foreign-keys.ts'; import type { AnyIndexBuilder } from './indexes.ts'; +import type { PgPolicy } from './policies.ts'; import type { PrimaryKeyBuilder } from './primary-keys.ts'; import type { UniqueConstraintBuilder } from './unique-constraint.ts'; -export type PgTableExtraConfig = Record< - string, +export type PgTableExtraConfigValue = | AnyIndexBuilder | CheckBuilder | ForeignKeyBuilder | PrimaryKeyBuilder | UniqueConstraintBuilder + | PgPolicy; + +export type PgTableExtraConfig = Record< + string, + PgTableExtraConfigValue >; export type TableConfig = TableConfigBase; /** @internal */ export const InlineForeignKeys = Symbol.for('drizzle:PgInlineForeignKeys'); +/** @internal */ +export const EnableRLS = Symbol.for('drizzle:EnableRLS'); export class PgTable extends Table { static override readonly [entityKind]: string = 'PgTable'; @@ -29,11 +36,15 @@ export class PgTable extends Table { /** @internal */ static override readonly Symbol = Object.assign({}, Table.Symbol, { InlineForeignKeys: InlineForeignKeys as typeof InlineForeignKeys, + EnableRLS: EnableRLS as typeof EnableRLS, }); /**@internal */ [InlineForeignKeys]: ForeignKey[] = []; + /** @internal */ + [EnableRLS]: boolean = false; + /** @internal */ override [Table.Symbol.ExtraConfigBuilder]: ((self: Record) => PgTableExtraConfig) | undefined = undefined; @@ -45,6 +56,12 @@ export type PgTableWithColumns = & PgTable & { [Key in keyof T['columns']]: T['columns'][Key]; + } + & { + enableRLS: () => Omit< + PgTableWithColumns, + 'enableRLS' + >; }; /** @internal */ @@ -55,7 +72,9 @@ export function pgTableWithSchema< >( name: TTableName, columns: TColumnsMap | ((columnTypes: PgColumnsBuilders) => TColumnsMap), - extraConfig: ((self: BuildExtraConfigColumns) => PgTableExtraConfig) | undefined, + extraConfig: + | ((self: BuildExtraConfigColumns) => PgTableExtraConfig | PgTableExtraConfigValue[]) + | undefined, schema: TSchemaName, baseName = name, ): PgTableWithColumns<{ @@ -101,17 +120,65 @@ export function pgTableWithSchema< table[PgTable.Symbol.ExtraConfigBuilder] = extraConfig as any; } - return table; + return Object.assign(table, { + enableRLS: () => { + table[PgTable.Symbol.EnableRLS] = true; + return table as PgTableWithColumns<{ + name: TTableName; + schema: TSchemaName; + columns: BuildColumns; + dialect: 'pg'; + }>; + }, + }); } export interface PgTableFn { + /** + * @deprecated This overload is deprecated. Use the other method overload instead. + */ + < + TTableName extends string, + TColumnsMap extends Record, + >( + name: TTableName, + columns: TColumnsMap, + extraConfig: ( + self: BuildExtraConfigColumns, + ) => PgTableExtraConfig, + ): PgTableWithColumns<{ + name: TTableName; + schema: TSchema; + columns: BuildColumns; + dialect: 'pg'; + }>; + + /** + * @deprecated This overload is deprecated. Use the other method overload instead. + */ + < + TTableName extends string, + TColumnsMap extends Record, + >( + name: TTableName, + columns: (columnTypes: PgColumnsBuilders) => TColumnsMap, + extraConfig: (self: BuildExtraConfigColumns) => PgTableExtraConfig, + ): PgTableWithColumns<{ + name: TTableName; + schema: TSchema; + columns: BuildColumns; + dialect: 'pg'; + }>; + < TTableName extends string, TColumnsMap extends Record, >( name: TTableName, columns: TColumnsMap, - extraConfig?: (self: BuildExtraConfigColumns) => PgTableExtraConfig, + extraConfig?: ( + self: BuildExtraConfigColumns, + ) => PgTableExtraConfigValue[], ): PgTableWithColumns<{ name: TTableName; schema: TSchema; @@ -125,7 +192,7 @@ export interface PgTableFn { >( name: TTableName, columns: (columnTypes: PgColumnsBuilders) => TColumnsMap, - extraConfig?: (self: BuildExtraConfigColumns) => PgTableExtraConfig, + extraConfig?: (self: BuildExtraConfigColumns) => PgTableExtraConfigValue[], ): PgTableWithColumns<{ name: TTableName; schema: TSchema; diff --git a/drizzle-orm/src/pg-core/utils.ts b/drizzle-orm/src/pg-core/utils.ts index 90378f249..0191c2439 100644 --- a/drizzle-orm/src/pg-core/utils.ts +++ b/drizzle-orm/src/pg-core/utils.ts @@ -7,6 +7,7 @@ import type { AnyPgColumn } from './columns/index.ts'; import { type ForeignKey, ForeignKeyBuilder } from './foreign-keys.ts'; import type { Index } from './indexes.ts'; import { IndexBuilder } from './indexes.ts'; +import { PgPolicy } from './policies.ts'; import { type PrimaryKey, PrimaryKeyBuilder } from './primary-keys.ts'; import { type UniqueConstraint, UniqueConstraintBuilder } from './unique-constraint.ts'; import { PgViewConfig } from './view-common.ts'; @@ -21,12 +22,15 @@ export function getTableConfig(table: TTable) { const uniqueConstraints: UniqueConstraint[] = []; const name = table[Table.Symbol.Name]; const schema = table[Table.Symbol.Schema]; + const policies: PgPolicy[] = []; + const enableRLS: boolean = table[PgTable.Symbol.EnableRLS]; const extraConfigBuilder = table[PgTable.Symbol.ExtraConfigBuilder]; if (extraConfigBuilder !== undefined) { const extraConfig = extraConfigBuilder(table[Table.Symbol.ExtraConfigColumns]); - for (const builder of Object.values(extraConfig)) { + const extraValues = Array.isArray(extraConfig) ? extraConfig.flat(1) as any[] : Object.values(extraConfig); + for (const builder of extraValues) { if (is(builder, IndexBuilder)) { indexes.push(builder.build(table)); } else if (is(builder, CheckBuilder)) { @@ -37,6 +41,8 @@ export function getTableConfig(table: TTable) { primaryKeys.push(builder.build(table)); } else if (is(builder, ForeignKeyBuilder)) { foreignKeys.push(builder.build(table)); + } else if (is(builder, PgPolicy)) { + policies.push(builder); } } } @@ -50,6 +56,8 @@ export function getTableConfig(table: TTable) { uniqueConstraints, name, schema, + policies, + enableRLS, }; } diff --git a/drizzle-orm/src/supabase/index.ts b/drizzle-orm/src/supabase/index.ts new file mode 100644 index 000000000..ee201ff1c --- /dev/null +++ b/drizzle-orm/src/supabase/index.ts @@ -0,0 +1 @@ +export * from './rls.ts'; diff --git a/drizzle-orm/src/supabase/rls.ts b/drizzle-orm/src/supabase/rls.ts new file mode 100644 index 000000000..20fea7355 --- /dev/null +++ b/drizzle-orm/src/supabase/rls.ts @@ -0,0 +1,33 @@ +import { bigserial, pgSchema, text, uuid } from '~/pg-core/index.ts'; +import { pgRole } from '~/pg-core/roles.ts'; +import { sql } from '~/sql/sql.ts'; + +export const anonRole = pgRole('anon').existing(); +export const authenticatedRole = pgRole('authenticated').existing(); +export const serviceRole = pgRole('service_role').existing(); +export const postgresRole = pgRole('postgres_role').existing(); +export const supabaseAuthAdminRole = pgRole('supabase_auth_admin').existing(); + +/* ------------------------------ auth schema; ------------------------------ */ +const auth = pgSchema('auth'); + +export const authUsers = auth.table('users', { + id: uuid().primaryKey().notNull(), +}); + +/* ------------------------------ realtime schema; ------------------------------- */ +const realtime = pgSchema('realtime'); + +export const realtimeMessages = realtime.table( + 'messages', + { + id: bigserial({ mode: 'bigint' }).primaryKey(), + topic: text().notNull(), + extension: text({ + enum: ['presence', 'broadcast', 'postgres_changes'], + }).notNull(), + }, +); + +export const authUid = sql`(select auth.uid())`; +export const realtimeTopic = sql`realtime.topic()`; diff --git a/drizzle-orm/src/table.ts b/drizzle-orm/src/table.ts index 0bf08fb3b..6bacfc207 100644 --- a/drizzle-orm/src/table.ts +++ b/drizzle-orm/src/table.ts @@ -109,7 +109,7 @@ export class Table implements SQLWrapper { [IsDrizzleTable] = true; /** @internal */ - [ExtraConfigBuilder]: ((self: any) => Record) | undefined = undefined; + [ExtraConfigBuilder]: ((self: any) => Record | unknown[]) | undefined = undefined; constructor(name: string, schema: string | undefined, baseName: string) { this[TableName] = this[OriginalName] = name; diff --git a/drizzle-orm/src/utils.ts b/drizzle-orm/src/utils.ts index 8d563d0da..8e1382c7a 100644 --- a/drizzle-orm/src/utils.ts +++ b/drizzle-orm/src/utils.ts @@ -302,7 +302,7 @@ export function isConfig(data: any): boolean { if ('client' in data) { const type = typeof data['client']; - if (type !== 'object' && type !== 'undefined') return false; + if (type !== 'object' && type !== 'function' && type !== 'undefined') return false; return true; } diff --git a/drizzle-orm/src/version.ts b/drizzle-orm/src/version.ts index 87f7e2ae9..6f22d27b3 100644 --- a/drizzle-orm/src/version.ts +++ b/drizzle-orm/src/version.ts @@ -1,4 +1,4 @@ // @ts-ignore - imported using Rollup json plugin export { version as npmVersion } from '../package.json'; // In version 7, we changed the PostgreSQL indexes API -export const compatibilityVersion = 9; +export const compatibilityVersion = 10; diff --git a/drizzle-orm/type-tests/pg/tables.ts b/drizzle-orm/type-tests/pg/tables.ts index 0ae1d8488..0b139dc3a 100644 --- a/drizzle-orm/type-tests/pg/tables.ts +++ b/drizzle-orm/type-tests/pg/tables.ts @@ -78,23 +78,23 @@ export const users = pgTable( enumCol: myEnum('enum_col').notNull(), arrayCol: text('array_col').array().notNull(), }, - (users) => ({ - usersAge1Idx: uniqueIndex('usersAge1Idx').on(users.class.asc().nullsFirst(), sql``), - usersAge2Idx: index('usersAge2Idx').on(sql``), - uniqueClass: uniqueIndex('uniqueClass') + (users) => [ + uniqueIndex('usersAge1Idx').on(users.class.asc().nullsFirst(), sql``), + index('usersAge2Idx').on(sql``), + uniqueIndex('uniqueClass') .using('btree', users.class.desc().op('text_ops'), users.subClass.nullsLast()) .where(sql`${users.class} is not null`) .concurrently(), - legalAge: check('legalAge', sql`${users.age1} > 18`), - usersClassFK: foreignKey({ columns: [users.subClass], foreignColumns: [classes.subClass] }) + check('legalAge', sql`${users.age1} > 18`), + foreignKey({ columns: [users.subClass], foreignColumns: [classes.subClass] }) .onUpdate('cascade') .onDelete('cascade'), - usersClassComplexFK: foreignKey({ + foreignKey({ columns: [users.class, users.subClass], foreignColumns: [classes.class, classes.subClass], }), - pk: primaryKey(users.age1, users.class), - }), + primaryKey(users.age1, users.class), + ], ); Expect, typeof users['$inferSelect']>>; @@ -172,9 +172,7 @@ export const citiesCustom = customSchema.table('cities_table', { id: serial('id').primaryKey(), name: text('name').notNull(), population: integer('population').default(0), -}, (cities) => ({ - citiesNameIdx: index().on(cities.id), -})); +}, (cities) => [index().on(cities.id)]); export const newYorkers = pgView('new_yorkers') .with({ diff --git a/integration-tests/package.json b/integration-tests/package.json index 775103111..b7a5cca5b 100644 --- a/integration-tests/package.json +++ b/integration-tests/package.json @@ -43,7 +43,8 @@ "dependencies": { "@aws-sdk/client-rds-data": "^3.549.0", "@aws-sdk/credential-providers": "^3.549.0", - "@electric-sql/pglite": "^0.2.12", + "@electric-sql/pglite": "0.2.12", + "@libsql/client": "^0.10.0", "@miniflare/d1": "^2.14.4", "@miniflare/shared": "^2.14.4", "@planetscale/database": "^1.16.0", diff --git a/integration-tests/tests/pg/pg-common.ts b/integration-tests/tests/pg/pg-common.ts index 78eecf328..3b3e4cb4d 100644 --- a/integration-tests/tests/pg/pg-common.ts +++ b/integration-tests/tests/pg/pg-common.ts @@ -18,6 +18,7 @@ import { gte, ilike, inArray, + is, lt, max, min, @@ -30,6 +31,7 @@ import { sumDistinct, TransactionRollbackError, } from 'drizzle-orm'; +import { authenticatedRole, crudPolicy } from 'drizzle-orm/neon'; import type { NeonHttpDatabase } from 'drizzle-orm/neon-http'; import type { PgColumn, PgDatabase, PgQueryResultHKT } from 'drizzle-orm/pg-core'; import { @@ -45,6 +47,7 @@ import { getMaterializedViewConfig, getTableConfig, getViewConfig, + index, inet, integer, intersect, @@ -55,8 +58,11 @@ import { macaddr, macaddr8, numeric, + PgDialect, pgEnum, pgMaterializedView, + PgPolicy, + pgPolicy, pgSchema, pgTable, pgTableCreator, @@ -4711,6 +4717,123 @@ export function tests() { }]); }); + test('policy', () => { + { + const policy = pgPolicy('test policy'); + + expect(is(policy, PgPolicy)).toBe(true); + expect(policy.name).toBe('test policy'); + } + + { + const policy = pgPolicy('test policy', { + as: 'permissive', + for: 'all', + to: 'public', + using: sql`1=1`, + withCheck: sql`1=1`, + }); + + expect(is(policy, PgPolicy)).toBe(true); + expect(policy.name).toBe('test policy'); + expect(policy.as).toBe('permissive'); + expect(policy.for).toBe('all'); + expect(policy.to).toBe('public'); + const dialect = new PgDialect(); + expect(is(policy.using, SQL)).toBe(true); + expect(dialect.sqlToQuery(policy.using!).sql).toBe('1=1'); + expect(is(policy.withCheck, SQL)).toBe(true); + expect(dialect.sqlToQuery(policy.withCheck!).sql).toBe('1=1'); + } + + { + const policy = pgPolicy('test policy', { + to: 'custom value', + }); + + expect(policy.to).toBe('custom value'); + } + + { + const p1 = pgPolicy('test policy'); + const p2 = pgPolicy('test policy 2', { + as: 'permissive', + for: 'all', + to: 'public', + using: sql`1=1`, + withCheck: sql`1=1`, + }); + const table = pgTable('table_with_policy', { + id: serial('id').primaryKey(), + name: text('name').notNull(), + }, () => ({ + p1, + p2, + })); + const config = getTableConfig(table); + expect(config.policies).toHaveLength(2); + expect(config.policies[0]).toBe(p1); + expect(config.policies[1]).toBe(p2); + } + }); + + test('neon: policy', () => { + { + const policy = crudPolicy({ + read: true, + modify: true, + role: authenticatedRole, + }); + + for (const it of Object.values(policy)) { + expect(is(it, PgPolicy)).toBe(true); + expect(it?.to).toStrictEqual(authenticatedRole); + it?.using ? expect(it.using).toStrictEqual(sql`true`) : ''; + it?.withCheck ? expect(it.withCheck).toStrictEqual(sql`true`) : ''; + } + } + + { + const table = pgTable('name', { + id: integer('id'), + }, (t) => [ + index('name').on(t.id), + crudPolicy({ + read: true, + modify: true, + role: authenticatedRole, + }), + primaryKey({ columns: [t.id], name: 'custom' }), + ]); + + const { policies, indexes, primaryKeys } = getTableConfig(table); + + expect(policies.length).toBe(4); + expect(indexes.length).toBe(1); + expect(primaryKeys.length).toBe(1); + + expect(policies[0]?.name === 'crud-custom-policy-modify'); + expect(policies[1]?.name === 'crud-custom-policy-read'); + } + }); + + test('Enable RLS function', () => { + const usersWithRLS = pgTable('users', { + id: integer(), + }).enableRLS(); + + const config1 = getTableConfig(usersWithRLS); + + const usersNoRLS = pgTable('users', { + id: integer(), + }); + + const config2 = getTableConfig(usersNoRLS); + + expect(config1.enableRLS).toBeTruthy(); + expect(config2.enableRLS).toBeFalsy(); + }); + test('$count separate', async (ctx) => { const { db } = ctx.pg; diff --git a/integration-tests/tests/pg/rls/rls.definition.test.ts b/integration-tests/tests/pg/rls/rls.definition.test.ts new file mode 100644 index 000000000..2365a2e6d --- /dev/null +++ b/integration-tests/tests/pg/rls/rls.definition.test.ts @@ -0,0 +1,16 @@ +import { crudPolicy } from 'drizzle-orm/neon'; +import { getTableConfig, integer, pgPolicy, pgRole, pgTable } from 'drizzle-orm/pg-core'; +import { test } from 'vitest'; + +test.skip('getTableConfig: policies', async () => { + const schema = pgTable('hhh', { + id: integer(), + }, () => [ + pgPolicy('name'), + crudPolicy({ role: pgRole('users'), read: true, modify: true }), + ]); + + const tc = getTableConfig(schema); + + console.log(tc.policies); +}); diff --git a/integration-tests/tests/utils/is-config.test.ts b/integration-tests/tests/utils/is-config.test.ts index e3d8d95e8..a71a753c2 100644 --- a/integration-tests/tests/utils/is-config.test.ts +++ b/integration-tests/tests/utils/is-config.test.ts @@ -298,3 +298,197 @@ describe('Rejects drivers', (it) => { expect(isConfig(cl)).toEqual(false); }); }); + +describe('Accepts drivers in .client', (it) => { + it('libsql', () => { + const cl = libsql({ + url: ':memory:', + }); + + expect(isConfig({ client: cl })).toEqual(true); + }); + + it('better-sqlite3', () => { + const cl = new betterSqlite3(':memory:'); + + expect(isConfig({ client: cl })).toEqual(true); + }); + + it('pglite', () => { + const cl = new pglite('memory://'); + + expect(isConfig({ client: cl })).toEqual(true); + }); + + it('node-postgres:Pool', () => { + const cl = new pg.Pool({ + connectionString: process.env['PG_CONNECTION_STRING'], + }); + + expect(isConfig({ client: cl })).toEqual(true); + }); + + it('node-postgres:Client', async () => { + const cl = new pg.Client({ + connectionString: process.env['PG_CONNECTION_STRING'], + }); + + const res = isConfig({ client: cl }); + + await cl.end(); + + expect(res).toEqual(true); + }); + + it('node-postgres:PoolClient', async () => { + const cl = new pg.Pool({ + connectionString: process.env['PG_CONNECTION_STRING'], + }); + + const con = await cl.connect(); + + const res = isConfig({ client: con }); + + con.release(); + + expect(res).toEqual(true); + }); + + it('postgres-js', () => { + const cl = postgres(process.env['PG_CONNECTION_STRING']!); + + expect(isConfig({ client: cl })).toEqual(true); + }); + + it('vercel:sql', () => { + expect(isConfig({ client: vcSql })).toEqual(true); + }); + + // it('vercel:Pool', () => { + // const cl = vcPool({ + // connectionString: process.env['VERCEL_CONNECTION_STRING'], + // }); + + // expect(isConfig({client:cl})).toEqual(true); + // }); + + it('vercel:Client', async () => { + const cl = vcClient({ + connectionString: process.env['NEON_CONNECTION_STRING'], + }); + + const res = isConfig({ client: cl }); + + expect(res).toEqual(true); + }); + + // it('vercel:PoolClient', async () => { + // const cl = vcPool({ + // connectionString: process.env['VERCEL_CONNECTION_STRING'], + // }); + + // const con = await cl.connect(); + + // const res = isConfig({ client: con }); + + // con.release(); + + // expect(res).toEqual(true); + // }); + + it('neon-serverless:Pool', async () => { + const cl = new neonPool({ + connectionString: process.env['NEON_CONNECTION_STRING']!, + }); + + expect(isConfig({ client: cl })).toEqual(true); + }); + + it('neon-serverless:Client', async () => { + const cl = new neonClient({ + connectionString: process.env['NEON_CONNECTION_STRING']!, + }); + + const res = isConfig({ client: cl }); + + await cl.end(); + + expect(res).toEqual(true); + }); + + it('neon-serverless:PoolClient', async () => { + const cl = new neonPool({ + connectionString: process.env['NEON_CONNECTION_STRING']!, + }); + + const con = await cl.connect(); + + const res = isConfig({ client: con }); + + con.release(); + + expect(res).toEqual(true); + }); + + it('neon-http', async () => { + const cl = neon(process.env['NEON_CONNECTION_STRING']!); + + expect(isConfig({ client: cl })).toEqual(true); + }); + + it('planetscale', async () => { + const cl = planetscale({ + url: process.env['PLANETSCALE_CONNECTION_STRING'], + }); + + expect(isConfig({ client: cl })).toEqual(true); + }); + + it('mysql2:Pool', async () => { + const cl = ms2Pool({ + uri: process.env['MYSQL_CONNECTION_STRING'], + }); + + expect(isConfig({ client: cl })).toEqual(true); + }); + + it('mysql2:Connection', async () => { + const cl = ms2Connection({ + uri: process.env['MYSQL_CONNECTION_STRING'], + }); + + expect(isConfig({ client: cl })).toEqual(true); + }); + + it('mysql2/promise:Pool', async () => { + const cl = await ms2pPool({ + uri: process.env['MYSQL_CONNECTION_STRING'], + }); + + const res = isConfig({ client: cl }); + + await cl.end(); + + expect(res).toEqual(true); + }); + + it('mysql2/promise:Connection', async () => { + const cl = await ms2pConnection({ + uri: process.env['MYSQL_CONNECTION_STRING'], + }); + + const res = isConfig({ client: cl }); + + await cl.end(); + + expect(res).toEqual(true); + }); + + it('tidb', async () => { + const cl = tidb({ + url: process.env['TIDB_CONNECTION_STRING'], + }); + + expect(isConfig({ client: cl })).toEqual(true); + }); +}); diff --git a/package.json b/package.json index b0fda61c8..29189a91b 100755 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "lint": "concurrently -n eslint,dprint \"eslint --ext ts .\" \"dprint check --list-different\"" }, "devDependencies": { - "@arethetypeswrong/cli": "^0.15.3", + "@arethetypeswrong/cli": "0.15.3", "@trivago/prettier-plugin-sort-imports": "^4.2.0", "@typescript-eslint/eslint-plugin": "^6.7.3", "@typescript-eslint/experimental-utils": "^5.62.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 20ff6ca0f..ed86a8353 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,7 +9,7 @@ importers: .: devDependencies: '@arethetypeswrong/cli': - specifier: ^0.15.3 + specifier: 0.15.3 version: 0.15.3 '@trivago/prettier-plugin-sort-imports': specifier: ^4.2.0 @@ -87,8 +87,8 @@ importers: drizzle-kit: dependencies: '@drizzle-team/brocli': - specifier: ^0.10.1 - version: 0.10.1 + specifier: ^0.10.2 + version: 0.10.2 '@esbuild-kit/esm-loader': specifier: ^2.5.5 version: 2.5.5 @@ -164,10 +164,10 @@ importers: version: 8.5.11 '@typescript-eslint/eslint-plugin': specifier: ^7.2.0 - version: 7.16.1(@typescript-eslint/parser@7.16.1(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5) + version: 7.16.1(@typescript-eslint/parser@7.16.1(eslint@8.57.0)(typescript@5.6.3))(eslint@8.57.0)(typescript@5.6.3) '@typescript-eslint/parser': specifier: ^7.2.0 - version: 7.16.1(eslint@8.57.0)(typescript@5.4.5) + version: 7.16.1(eslint@8.57.0)(typescript@5.6.3) '@vercel/postgres': specifier: ^0.8.0 version: 0.8.0 @@ -260,19 +260,19 @@ importers: version: 2.2.1 tsup: specifier: ^8.0.2 - version: 8.1.2(postcss@8.4.39)(tsx@3.14.0)(typescript@5.4.5)(yaml@2.4.2) + version: 8.1.2(postcss@8.4.39)(tsx@3.14.0)(typescript@5.6.3)(yaml@2.4.2) tsx: specifier: ^3.12.1 version: 3.14.0 typescript: - specifier: ^5.4.3 - version: 5.4.5 + specifier: ^5.6.3 + version: 5.6.3 uuid: specifier: ^9.0.1 version: 9.0.1 vite-tsconfig-paths: specifier: ^4.3.2 - version: 4.3.2(typescript@5.4.5)(vite@5.3.3(@types/node@18.19.33)(lightningcss@1.25.1)(terser@5.31.0)) + version: 4.3.2(typescript@5.6.3)(vite@5.3.3(@types/node@18.19.33)(lightningcss@1.25.1)(terser@5.31.0)) vitest: specifier: ^1.4.0 version: 1.6.0(@types/node@18.19.33)(@vitest/ui@1.6.0)(lightningcss@1.25.1)(terser@5.31.0) @@ -314,7 +314,7 @@ importers: version: 0.9.0 '@op-engineering/op-sqlite': specifier: ^2.0.16 - version: 2.0.22(react-native@0.74.1(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(@types/react@18.3.1)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.3.1)(utf-8-validate@6.0.3))(react@18.3.1) + version: 2.0.22(react-native@0.74.1(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(@types/react@18.3.1)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.3.1))(react@18.3.1) '@opentelemetry/api': specifier: ^1.4.1 version: 1.8.0 @@ -362,7 +362,7 @@ importers: version: 10.1.0 expo-sqlite: specifier: ^13.2.0 - version: 13.4.0(expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3)) + version: 13.4.0(expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)) knex: specifier: ^2.4.2 version: 2.5.1(better-sqlite3@8.7.0)(mysql2@3.3.3)(pg@8.11.5)(sqlite3@5.1.7) @@ -553,8 +553,11 @@ importers: specifier: ^3.549.0 version: 3.569.0(@aws-sdk/client-sso-oidc@3.583.0) '@electric-sql/pglite': - specifier: ^0.2.12 + specifier: 0.2.12 version: 0.2.12 + '@libsql/client': + specifier: ^0.10.0 + version: 0.10.0(bufferutil@4.0.8)(utf-8-validate@6.0.3) '@miniflare/d1': specifier: ^2.14.4 version: 2.14.4 @@ -652,9 +655,6 @@ importers: '@cloudflare/workers-types': specifier: ^4.20241004.0 version: 4.20241004.0 - '@libsql/client': - specifier: ^0.10.0 - version: 0.10.0(bufferutil@4.0.8)(utf-8-validate@6.0.3) '@neondatabase/serverless': specifier: 0.9.0 version: 0.9.0 @@ -1990,8 +1990,8 @@ packages: cpu: [x64] os: [win32] - '@drizzle-team/brocli@0.10.1': - resolution: {integrity: sha512-AHy0vjc+n/4w/8Mif+w86qpppHuF3AyXbcWW+R/W7GNA3F5/p2nuhlkCJaTXSLZheB4l1rtHzOfr9A7NwoR/Zg==} + '@drizzle-team/brocli@0.10.2': + resolution: {integrity: sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w==} '@drizzle-team/studio@0.0.5': resolution: {integrity: sha512-ps5qF0tMxWRVu+V5gvCRrQNqlY92aTnIKdq27gm9LZMSdaKYZt6AVvSK1dlUMzs6Rt0Jm80b+eWct6xShBKhIw==} @@ -4428,6 +4428,7 @@ packages: '@xmldom/xmldom@0.7.13': resolution: {integrity: sha512-lm2GW5PkosIzccsaZIz7tp8cPADSIlIHWDFTR1N0SzfinhhYgeIQjFMz4rYzanCScr3DqQLeomUDArp6MWKm+g==} engines: {node: '>=10.0.0'} + deprecated: this version is no longer supported, please update to at least 0.8.* '@xmldom/xmldom@0.8.10': resolution: {integrity: sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==} @@ -9600,11 +9601,6 @@ packages: engines: {node: '>=14.17'} hasBin: true - typescript@5.4.5: - resolution: {integrity: sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==} - engines: {node: '>=14.17'} - hasBin: true - typescript@5.6.3: resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==} engines: {node: '>=14.17'} @@ -12497,7 +12493,7 @@ snapshots: '@dprint/win32-x64@0.46.3': optional: true - '@drizzle-team/brocli@0.10.1': {} + '@drizzle-team/brocli@0.10.2': {} '@drizzle-team/studio@0.0.5': {} @@ -13029,7 +13025,7 @@ snapshots: mv: 2.1.1 safe-json-stringify: 1.2.0 - '@expo/cli@0.18.13(bufferutil@4.0.8)(encoding@0.1.13)(expo-modules-autolinking@1.11.1)(utf-8-validate@6.0.3)': + '@expo/cli@0.18.13(bufferutil@4.0.8)(encoding@0.1.13)(expo-modules-autolinking@1.11.1)': dependencies: '@babel/runtime': 7.24.6 '@expo/code-signing-certificates': 0.0.5 @@ -13047,7 +13043,7 @@ snapshots: '@expo/rudder-sdk-node': 1.1.1(encoding@0.1.13) '@expo/spawn-async': 1.7.2 '@expo/xcpretty': 4.3.1 - '@react-native/dev-middleware': 0.74.83(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3) + '@react-native/dev-middleware': 0.74.83(bufferutil@4.0.8)(encoding@0.1.13) '@urql/core': 2.3.6(graphql@15.8.0) '@urql/exchange-retry': 0.3.0(graphql@15.8.0) accepts: 1.3.8 @@ -13628,10 +13624,10 @@ snapshots: rimraf: 3.0.2 optional: true - '@op-engineering/op-sqlite@2.0.22(react-native@0.74.1(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(@types/react@18.3.1)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.3.1)(utf-8-validate@6.0.3))(react@18.3.1)': + '@op-engineering/op-sqlite@2.0.22(react-native@0.74.1(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(@types/react@18.3.1)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.3.1))(react@18.3.1)': dependencies: react: 18.3.1 - react-native: 0.74.1(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(@types/react@18.3.1)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.3.1)(utf-8-validate@6.0.3) + react-native: 0.74.1(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(@types/react@18.3.1)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.3.1) '@opentelemetry/api@1.8.0': {} @@ -13768,7 +13764,7 @@ snapshots: transitivePeerDependencies: - encoding - '@react-native-community/cli-server-api@13.6.6(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3)': + '@react-native-community/cli-server-api@13.6.6(bufferutil@4.0.8)(encoding@0.1.13)': dependencies: '@react-native-community/cli-debugger-ui': 13.6.6 '@react-native-community/cli-tools': 13.6.6(encoding@0.1.13) @@ -13778,7 +13774,7 @@ snapshots: nocache: 3.0.4 pretty-format: 26.6.2 serve-static: 1.15.0 - ws: 6.2.2(bufferutil@4.0.8)(utf-8-validate@6.0.3) + ws: 6.2.2(bufferutil@4.0.8) transitivePeerDependencies: - bufferutil - encoding @@ -13805,14 +13801,14 @@ snapshots: dependencies: joi: 17.13.1 - '@react-native-community/cli@13.6.6(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3)': + '@react-native-community/cli@13.6.6(bufferutil@4.0.8)(encoding@0.1.13)': dependencies: '@react-native-community/cli-clean': 13.6.6(encoding@0.1.13) '@react-native-community/cli-config': 13.6.6(encoding@0.1.13) '@react-native-community/cli-debugger-ui': 13.6.6 '@react-native-community/cli-doctor': 13.6.6(encoding@0.1.13) '@react-native-community/cli-hermes': 13.6.6(encoding@0.1.13) - '@react-native-community/cli-server-api': 13.6.6(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3) + '@react-native-community/cli-server-api': 13.6.6(bufferutil@4.0.8)(encoding@0.1.13) '@react-native-community/cli-tools': 13.6.6(encoding@0.1.13) '@react-native-community/cli-types': 13.6.6 chalk: 4.1.2 @@ -13901,16 +13897,16 @@ snapshots: transitivePeerDependencies: - supports-color - '@react-native/community-cli-plugin@0.74.83(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3)': + '@react-native/community-cli-plugin@0.74.83(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)': dependencies: - '@react-native-community/cli-server-api': 13.6.6(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3) + '@react-native-community/cli-server-api': 13.6.6(bufferutil@4.0.8)(encoding@0.1.13) '@react-native-community/cli-tools': 13.6.6(encoding@0.1.13) - '@react-native/dev-middleware': 0.74.83(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3) + '@react-native/dev-middleware': 0.74.83(bufferutil@4.0.8)(encoding@0.1.13) '@react-native/metro-babel-transformer': 0.74.83(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6)) chalk: 4.1.2 execa: 5.1.1 - metro: 0.80.9(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3) - metro-config: 0.80.9(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3) + metro: 0.80.9(bufferutil@4.0.8)(encoding@0.1.13) + metro-config: 0.80.9(bufferutil@4.0.8)(encoding@0.1.13) metro-core: 0.80.9 node-fetch: 2.7.0(encoding@0.1.13) querystring: 0.2.1 @@ -13925,7 +13921,7 @@ snapshots: '@react-native/debugger-frontend@0.74.83': {} - '@react-native/dev-middleware@0.74.83(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3)': + '@react-native/dev-middleware@0.74.83(bufferutil@4.0.8)(encoding@0.1.13)': dependencies: '@isaacs/ttlcache': 1.4.1 '@react-native/debugger-frontend': 0.74.83 @@ -13939,7 +13935,7 @@ snapshots: selfsigned: 2.4.1 serve-static: 1.15.0 temp-dir: 2.0.0 - ws: 6.2.2(bufferutil@4.0.8)(utf-8-validate@6.0.3) + ws: 6.2.2(bufferutil@4.0.8) transitivePeerDependencies: - bufferutil - encoding @@ -13962,12 +13958,12 @@ snapshots: '@react-native/normalize-colors@0.74.83': {} - '@react-native/virtualized-lists@0.74.83(@types/react@18.3.1)(react-native@0.74.1(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(@types/react@18.3.1)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.3.1)(utf-8-validate@6.0.3))(react@18.3.1)': + '@react-native/virtualized-lists@0.74.83(@types/react@18.3.1)(react-native@0.74.1(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(@types/react@18.3.1)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.3.1))(react@18.3.1)': dependencies: invariant: 2.2.4 nullthrows: 1.1.1 react: 18.3.1 - react-native: 0.74.1(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(@types/react@18.3.1)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.3.1)(utf-8-validate@6.0.3) + react-native: 0.74.1(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(@types/react@18.3.1)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.3.1) optionalDependencies: '@types/react': 18.3.1 @@ -14919,21 +14915,21 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/eslint-plugin@7.16.1(@typescript-eslint/parser@7.16.1(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5)': + '@typescript-eslint/eslint-plugin@7.16.1(@typescript-eslint/parser@7.16.1(eslint@8.57.0)(typescript@5.6.3))(eslint@8.57.0)(typescript@5.6.3)': dependencies: '@eslint-community/regexpp': 4.11.0 - '@typescript-eslint/parser': 7.16.1(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/parser': 7.16.1(eslint@8.57.0)(typescript@5.6.3) '@typescript-eslint/scope-manager': 7.16.1 - '@typescript-eslint/type-utils': 7.16.1(eslint@8.57.0)(typescript@5.4.5) - '@typescript-eslint/utils': 7.16.1(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/type-utils': 7.16.1(eslint@8.57.0)(typescript@5.6.3) + '@typescript-eslint/utils': 7.16.1(eslint@8.57.0)(typescript@5.6.3) '@typescript-eslint/visitor-keys': 7.16.1 eslint: 8.57.0 graphemer: 1.4.0 ignore: 5.3.1 natural-compare: 1.4.0 - ts-api-utils: 1.3.0(typescript@5.4.5) + ts-api-utils: 1.3.0(typescript@5.6.3) optionalDependencies: - typescript: 5.4.5 + typescript: 5.6.3 transitivePeerDependencies: - supports-color @@ -14971,16 +14967,16 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@7.16.1(eslint@8.57.0)(typescript@5.4.5)': + '@typescript-eslint/parser@7.16.1(eslint@8.57.0)(typescript@5.6.3)': dependencies: '@typescript-eslint/scope-manager': 7.16.1 '@typescript-eslint/types': 7.16.1 - '@typescript-eslint/typescript-estree': 7.16.1(typescript@5.4.5) + '@typescript-eslint/typescript-estree': 7.16.1(typescript@5.6.3) '@typescript-eslint/visitor-keys': 7.16.1 debug: 4.3.4 eslint: 8.57.0 optionalDependencies: - typescript: 5.4.5 + typescript: 5.6.3 transitivePeerDependencies: - supports-color @@ -15029,15 +15025,15 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/type-utils@7.16.1(eslint@8.57.0)(typescript@5.4.5)': + '@typescript-eslint/type-utils@7.16.1(eslint@8.57.0)(typescript@5.6.3)': dependencies: - '@typescript-eslint/typescript-estree': 7.16.1(typescript@5.4.5) - '@typescript-eslint/utils': 7.16.1(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/typescript-estree': 7.16.1(typescript@5.6.3) + '@typescript-eslint/utils': 7.16.1(eslint@8.57.0)(typescript@5.6.3) debug: 4.3.4 eslint: 8.57.0 - ts-api-utils: 1.3.0(typescript@5.4.5) + ts-api-utils: 1.3.0(typescript@5.6.3) optionalDependencies: - typescript: 5.4.5 + typescript: 5.6.3 transitivePeerDependencies: - supports-color @@ -15091,7 +15087,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@7.16.1(typescript@5.4.5)': + '@typescript-eslint/typescript-estree@7.16.1(typescript@5.6.3)': dependencies: '@typescript-eslint/types': 7.16.1 '@typescript-eslint/visitor-keys': 7.16.1 @@ -15100,9 +15096,9 @@ snapshots: is-glob: 4.0.3 minimatch: 9.0.4 semver: 7.6.2 - ts-api-utils: 1.3.0(typescript@5.4.5) + ts-api-utils: 1.3.0(typescript@5.6.3) optionalDependencies: - typescript: 5.4.5 + typescript: 5.6.3 transitivePeerDependencies: - supports-color @@ -15149,12 +15145,12 @@ snapshots: - supports-color - typescript - '@typescript-eslint/utils@7.16.1(eslint@8.57.0)(typescript@5.4.5)': + '@typescript-eslint/utils@7.16.1(eslint@8.57.0)(typescript@5.6.3)': dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) '@typescript-eslint/scope-manager': 7.16.1 '@typescript-eslint/types': 7.16.1 - '@typescript-eslint/typescript-estree': 7.16.1(typescript@5.4.5) + '@typescript-eslint/typescript-estree': 7.16.1(typescript@5.6.3) eslint: 8.57.0 transitivePeerDependencies: - supports-color @@ -15277,7 +15273,7 @@ snapshots: pathe: 1.1.2 picocolors: 1.0.1 sirv: 2.0.4 - vitest: 1.6.0(@types/node@20.12.12)(@vitest/ui@1.6.0)(lightningcss@1.25.1)(terser@5.31.0) + vitest: 1.6.0(@types/node@18.19.33)(@vitest/ui@1.6.0)(lightningcss@1.25.1)(terser@5.31.0) optional: true '@vitest/ui@1.6.0(vitest@2.1.2)': @@ -16490,7 +16486,7 @@ snapshots: drizzle-kit@0.25.0-b1faa33: dependencies: - '@drizzle-team/brocli': 0.10.1 + '@drizzle-team/brocli': 0.10.2 '@esbuild-kit/esm-loader': 2.5.5 esbuild: 0.19.12 esbuild-register: 3.5.0(esbuild@0.19.12) @@ -17338,35 +17334,35 @@ snapshots: expand-template@2.0.3: {} - expo-asset@10.0.6(expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3)): + expo-asset@10.0.6(expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)): dependencies: '@react-native/assets-registry': 0.74.83 - expo: 51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3) - expo-constants: 16.0.1(expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3)) + expo: 51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13) + expo-constants: 16.0.1(expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)) invariant: 2.2.4 md5-file: 3.2.3 transitivePeerDependencies: - supports-color - expo-constants@16.0.1(expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3)): + expo-constants@16.0.1(expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)): dependencies: '@expo/config': 9.0.2 - expo: 51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3) + expo: 51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13) transitivePeerDependencies: - supports-color - expo-file-system@17.0.1(expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3)): + expo-file-system@17.0.1(expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)): dependencies: - expo: 51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3) + expo: 51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13) - expo-font@12.0.5(expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3)): + expo-font@12.0.5(expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)): dependencies: - expo: 51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3) + expo: 51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13) fontfaceobserver: 2.3.0 - expo-keep-awake@13.0.2(expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3)): + expo-keep-awake@13.0.2(expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)): dependencies: - expo: 51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3) + expo: 51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13) expo-modules-autolinking@1.11.1: dependencies: @@ -17380,24 +17376,24 @@ snapshots: dependencies: invariant: 2.2.4 - expo-sqlite@13.4.0(expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3)): + expo-sqlite@13.4.0(expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)): dependencies: '@expo/websql': 1.0.1 - expo: 51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3) + expo: 51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13) - expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3): + expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13): dependencies: '@babel/runtime': 7.24.6 - '@expo/cli': 0.18.13(bufferutil@4.0.8)(encoding@0.1.13)(expo-modules-autolinking@1.11.1)(utf-8-validate@6.0.3) + '@expo/cli': 0.18.13(bufferutil@4.0.8)(encoding@0.1.13)(expo-modules-autolinking@1.11.1) '@expo/config': 9.0.2 '@expo/config-plugins': 8.0.4 '@expo/metro-config': 0.18.4 '@expo/vector-icons': 14.0.2 babel-preset-expo: 11.0.6(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6)) - expo-asset: 10.0.6(expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3)) - expo-file-system: 17.0.1(expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3)) - expo-font: 12.0.5(expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3)) - expo-keep-awake: 13.0.2(expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3)) + expo-asset: 10.0.6(expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)) + expo-file-system: 17.0.1(expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)) + expo-font: 12.0.5(expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)) + expo-keep-awake: 13.0.2(expo@51.0.8(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)) expo-modules-autolinking: 1.11.1 expo-modules-core: 1.12.11 fbemitter: 3.0.0(encoding@0.1.13) @@ -18879,12 +18875,12 @@ snapshots: metro-core: 0.80.9 rimraf: 3.0.2 - metro-config@0.80.9(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3): + metro-config@0.80.9(bufferutil@4.0.8)(encoding@0.1.13): dependencies: connect: 3.7.0 cosmiconfig: 5.2.1 jest-validate: 29.7.0 - metro: 0.80.9(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3) + metro: 0.80.9(bufferutil@4.0.8)(encoding@0.1.13) metro-cache: 0.80.9 metro-core: 0.80.9 metro-runtime: 0.80.9 @@ -18960,13 +18956,13 @@ snapshots: transitivePeerDependencies: - supports-color - metro-transform-worker@0.80.9(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3): + metro-transform-worker@0.80.9(bufferutil@4.0.8)(encoding@0.1.13): dependencies: '@babel/core': 7.24.6 '@babel/generator': 7.24.6 '@babel/parser': 7.24.6 '@babel/types': 7.24.6 - metro: 0.80.9(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3) + metro: 0.80.9(bufferutil@4.0.8)(encoding@0.1.13) metro-babel-transformer: 0.80.9 metro-cache: 0.80.9 metro-cache-key: 0.80.9 @@ -18980,7 +18976,7 @@ snapshots: - supports-color - utf-8-validate - metro@0.80.9(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3): + metro@0.80.9(bufferutil@4.0.8)(encoding@0.1.13): dependencies: '@babel/code-frame': 7.24.6 '@babel/core': 7.24.6 @@ -19006,7 +19002,7 @@ snapshots: metro-babel-transformer: 0.80.9 metro-cache: 0.80.9 metro-cache-key: 0.80.9 - metro-config: 0.80.9(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3) + metro-config: 0.80.9(bufferutil@4.0.8)(encoding@0.1.13) metro-core: 0.80.9 metro-file-map: 0.80.9 metro-resolver: 0.80.9 @@ -19014,7 +19010,7 @@ snapshots: metro-source-map: 0.80.9 metro-symbolicate: 0.80.9 metro-transform-plugins: 0.80.9 - metro-transform-worker: 0.80.9(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3) + metro-transform-worker: 0.80.9(bufferutil@4.0.8)(encoding@0.1.13) mime-types: 2.1.35 node-fetch: 2.7.0(encoding@0.1.13) nullthrows: 1.1.1 @@ -19023,7 +19019,7 @@ snapshots: source-map: 0.5.7 strip-ansi: 6.0.1 throat: 5.0.0 - ws: 7.5.9(bufferutil@4.0.8)(utf-8-validate@6.0.3) + ws: 7.5.9(bufferutil@4.0.8) yargs: 17.7.2 transitivePeerDependencies: - bufferutil @@ -19911,10 +19907,10 @@ snapshots: minimist: 1.2.8 strip-json-comments: 2.0.1 - react-devtools-core@5.2.0(bufferutil@4.0.8)(utf-8-validate@6.0.3): + react-devtools-core@5.2.0(bufferutil@4.0.8): dependencies: shell-quote: 1.8.1 - ws: 7.5.9(bufferutil@4.0.8)(utf-8-validate@6.0.3) + ws: 7.5.9(bufferutil@4.0.8) transitivePeerDependencies: - bufferutil - utf-8-validate @@ -19927,19 +19923,19 @@ snapshots: react-is@18.3.1: {} - react-native@0.74.1(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(@types/react@18.3.1)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.3.1)(utf-8-validate@6.0.3): + react-native@0.74.1(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(@types/react@18.3.1)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.3.1): dependencies: '@jest/create-cache-key-function': 29.7.0 - '@react-native-community/cli': 13.6.6(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3) + '@react-native-community/cli': 13.6.6(bufferutil@4.0.8)(encoding@0.1.13) '@react-native-community/cli-platform-android': 13.6.6(encoding@0.1.13) '@react-native-community/cli-platform-ios': 13.6.6(encoding@0.1.13) '@react-native/assets-registry': 0.74.83 '@react-native/codegen': 0.74.83(@babel/preset-env@7.24.6(@babel/core@7.24.6)) - '@react-native/community-cli-plugin': 0.74.83(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.3) + '@react-native/community-cli-plugin': 0.74.83(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(bufferutil@4.0.8)(encoding@0.1.13) '@react-native/gradle-plugin': 0.74.83 '@react-native/js-polyfills': 0.74.83 '@react-native/normalize-colors': 0.74.83 - '@react-native/virtualized-lists': 0.74.83(@types/react@18.3.1)(react-native@0.74.1(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(@types/react@18.3.1)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.3.1)(utf-8-validate@6.0.3))(react@18.3.1) + '@react-native/virtualized-lists': 0.74.83(@types/react@18.3.1)(react-native@0.74.1(@babel/core@7.24.6)(@babel/preset-env@7.24.6(@babel/core@7.24.6))(@types/react@18.3.1)(bufferutil@4.0.8)(encoding@0.1.13)(react@18.3.1))(react@18.3.1) abort-controller: 3.0.0 anser: 1.4.10 ansi-regex: 5.0.1 @@ -19958,14 +19954,14 @@ snapshots: pretty-format: 26.6.2 promise: 8.3.0 react: 18.3.1 - react-devtools-core: 5.2.0(bufferutil@4.0.8)(utf-8-validate@6.0.3) + react-devtools-core: 5.2.0(bufferutil@4.0.8) react-refresh: 0.14.2 react-shallow-renderer: 16.15.0(react@18.3.1) regenerator-runtime: 0.13.11 scheduler: 0.24.0-canary-efb381bbf-20230505 stacktrace-parser: 0.1.10 whatwg-fetch: 3.6.20 - ws: 6.2.2(bufferutil@4.0.8)(utf-8-validate@6.0.3) + ws: 6.2.2(bufferutil@4.0.8) yargs: 17.7.2 optionalDependencies: '@types/react': 18.3.1 @@ -20949,9 +20945,9 @@ snapshots: dependencies: typescript: 5.6.3 - ts-api-utils@1.3.0(typescript@5.4.5): + ts-api-utils@1.3.0(typescript@5.6.3): dependencies: - typescript: 5.4.5 + typescript: 5.6.3 ts-expose-internals-conditionally@1.0.0-empty.0: {} @@ -20975,10 +20971,6 @@ snapshots: v8-compile-cache-lib: 3.0.1 yn: 3.1.1 - tsconfck@3.0.3(typescript@5.4.5): - optionalDependencies: - typescript: 5.4.5 - tsconfck@3.0.3(typescript@5.6.3): optionalDependencies: typescript: 5.6.3 @@ -21017,7 +21009,7 @@ snapshots: - supports-color - ts-node - tsup@8.1.2(postcss@8.4.39)(tsx@3.14.0)(typescript@5.4.5)(yaml@2.4.2): + tsup@8.1.2(postcss@8.4.39)(tsx@3.14.0)(typescript@5.6.3)(yaml@2.4.2): dependencies: bundle-require: 5.0.0(esbuild@0.23.0) cac: 6.7.14 @@ -21036,7 +21028,7 @@ snapshots: tree-kill: 1.2.2 optionalDependencies: postcss: 8.4.39 - typescript: 5.4.5 + typescript: 5.6.3 transitivePeerDependencies: - jiti - supports-color @@ -21208,8 +21200,6 @@ snapshots: typescript@5.3.3: {} - typescript@5.4.5: {} - typescript@5.6.3: {} ua-parser-js@1.0.38: {} @@ -21431,24 +21421,24 @@ snapshots: - supports-color - terser - vite-tsconfig-paths@4.3.2(typescript@5.4.5)(vite@5.3.3(@types/node@18.19.33)(lightningcss@1.25.1)(terser@5.31.0)): + vite-tsconfig-paths@4.3.2(typescript@5.6.3)(vite@5.3.3(@types/node@18.15.10)(lightningcss@1.25.1)(terser@5.31.0)): dependencies: debug: 4.3.4 globrex: 0.1.2 - tsconfck: 3.0.3(typescript@5.4.5) + tsconfck: 3.0.3(typescript@5.6.3) optionalDependencies: - vite: 5.3.3(@types/node@18.19.33)(lightningcss@1.25.1)(terser@5.31.0) + vite: 5.3.3(@types/node@18.15.10)(lightningcss@1.25.1)(terser@5.31.0) transitivePeerDependencies: - supports-color - typescript - vite-tsconfig-paths@4.3.2(typescript@5.6.3)(vite@5.3.3(@types/node@18.15.10)(lightningcss@1.25.1)(terser@5.31.0)): + vite-tsconfig-paths@4.3.2(typescript@5.6.3)(vite@5.3.3(@types/node@18.19.33)(lightningcss@1.25.1)(terser@5.31.0)): dependencies: debug: 4.3.4 globrex: 0.1.2 tsconfck: 3.0.3(typescript@5.6.3) optionalDependencies: - vite: 5.3.3(@types/node@18.15.10)(lightningcss@1.25.1)(terser@5.31.0) + vite: 5.3.3(@types/node@18.19.33)(lightningcss@1.25.1)(terser@5.31.0) transitivePeerDependencies: - supports-color - typescript @@ -21885,17 +21875,15 @@ snapshots: imurmurhash: 0.1.4 signal-exit: 4.0.2 - ws@6.2.2(bufferutil@4.0.8)(utf-8-validate@6.0.3): + ws@6.2.2(bufferutil@4.0.8): dependencies: async-limiter: 1.0.1 optionalDependencies: bufferutil: 4.0.8 - utf-8-validate: 6.0.3 - ws@7.5.9(bufferutil@4.0.8)(utf-8-validate@6.0.3): + ws@7.5.9(bufferutil@4.0.8): optionalDependencies: bufferutil: 4.0.8 - utf-8-validate: 6.0.3 ws@8.14.2(bufferutil@4.0.8)(utf-8-validate@6.0.3): optionalDependencies: