diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e4afaa2e4d..e30e0076c9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -11,51 +11,51 @@ on: # TODO: Support latest releases workflow_dispatch: inputs: - name: + name: type: choice description: Package name (npm) options: - - "@auth/core" - - "@auth/nextjs" - - "@auth/dgraph-adapter" - - "@auth/drizzle-adapter" - - "@auth/dynamodb-adapter" - - "@auth/fauna-adapter" - - "@auth/firebase-adapter" - - "@auth/mikro-orm-adapter" - - "@auth/mongodb-adapter" - - "@auth/neo4j-adapter" - - "@auth/pouchdb-adapter" - - "@auth/prisma-adapter" - - "@auth/sequelize-adapter" - - "@auth/supabase-adapter" - - "@auth/typeorm-adapter" - - "@auth/upstash-redis-adapter" - - "@auth/xata-adapter" - - "next-auth" + - "@auth/core" + - "@auth/nextjs" + - "@auth/dgraph-adapter" + - "@auth/drizzle-adapter" + - "@auth/dynamodb-adapter" + - "@auth/fauna-adapter" + - "@auth/firebase-adapter" + - "@auth/mikro-orm-adapter" + - "@auth/mongodb-adapter" + - "@auth/neo4j-adapter" + - "@auth/pouchdb-adapter" + - "@auth/prisma-adapter" + - "@auth/sequelize-adapter" + - "@auth/supabase-adapter" + - "@auth/typeorm-adapter" + - "@auth/upstash-redis-adapter" + - "@auth/xata-adapter" + - "next-auth" # TODO: Infer from package name path: type: choice description: Directory name (packages/*) options: - - "core" - - "frameworks-nextjs" - - "adapter-dgraph" - - "adapter-drizzle" - - "adapter-dynamodb" - - "adapter-fauna" - - "adapter-firebase" - - "adapter-mikro-orm" - - "adapter-mongodb" - - "adapter-neo4j" - - "adapter-pouchdb" - - "adapter-prisma" - - "adapter-sequelize" - - "adapter-supabase" - - "adapter-typeorm" - - "adapter-upstash-redis" - - "adapter-xata" - - "next-auth" + - "core" + - "frameworks-nextjs" + - "adapter-dgraph" + - "adapter-drizzle" + - "adapter-dynamodb" + - "adapter-fauna" + - "adapter-firebase" + - "adapter-mikro-orm" + - "adapter-mongodb" + - "adapter-neo4j" + - "adapter-pouchdb" + - "adapter-prisma" + - "adapter-sequelize" + - "adapter-supabase" + - "adapter-typeorm" + - "adapter-upstash-redis" + - "adapter-xata" + - "next-auth" env: FORCE_COLOR: true diff --git a/.gitignore b/.gitignore index 658ab151e4..87db0b5ee3 100644 --- a/.gitignore +++ b/.gitignore @@ -65,6 +65,7 @@ packages/adapter-prisma/prisma/dev.db packages/adapter-prisma/prisma/migrations db.sqlite packages/adapter-supabase/supabase/.branches +packages/adapter-drizzle/.drizzle # Tests coverage @@ -97,5 +98,7 @@ packages/frameworks-sveltekit/vite.config.js.timestamp-* packages/frameworks-sveltekit/vite.config.ts.timestamp-* # Adapters +docs/docs/reference/adapter -docs/docs/reference/adapter \ No newline at end of file +## Drizzle migration folder +.drizzle \ No newline at end of file diff --git a/docs/docs/reference/adapters/index.md b/docs/docs/reference/adapters/index.md index ce4ba43a50..26b85f4824 100644 --- a/docs/docs/reference/adapters/index.md +++ b/docs/docs/reference/adapters/index.md @@ -8,6 +8,10 @@ Using an Auth.js / NextAuth.js adapter you can connect to any database service o

Dgraph Adapter

+
+ + +

Drizzle Adapter

@@ -67,10 +71,8 @@ Using an Auth.js / NextAuth.js adapter you can connect to any database service o If you don't find an adapter for the database or service you use, you can always create one yourself. Have a look at our guide on [how to create a database adapter](/guides/adapters/creating-a-database-adapter). ::: - ## Models - Auth.js can be used with any database. Models tell you what structures Auth.js expects from your database. Models will vary slightly depending on which adapter you use, but in general, will look something like this: ```mermaid @@ -131,7 +133,7 @@ If a user first signs in with an OAuth provider, then their email address is aut This provides a way to contact users and for users to maintain access to their account and sign in using email in the event they are unable to sign in with the OAuth provider in the future (if the [Email Provider](/reference/core/providers_email) is configured). ::: -User creation in the database is automatic and happens when the user is logging in for the first time with a provider. +User creation in the database is automatic and happens when the user is logging in for the first time with a provider. If the first sign-in is via the [OAuth Provider](/reference/core/providers_oauth), the default data saved is `id`, `name`, `email` and `image`. You can add more profile data by returning extra fields in your [OAuth provider](/guides/providers/custom-provider)'s [`profile()`](/reference/core/providers#profile) callback. If the first sign-in is via the [Email Provider](/reference/core/providers_email), then the saved user will have `id`, `email`, `emailVerified`, where `emailVerified` is the timestamp of when the user was created. diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js index d820507a9d..e5add05eb2 100644 --- a/docs/docusaurus.config.js +++ b/docs/docusaurus.config.js @@ -265,6 +265,7 @@ const docusaurusConfig = { ? [] : [ typedocAdapter("Dgraph"), + typedocAdapter("Drizzle"), typedocAdapter("DynamoDB"), typedocAdapter("Fauna"), typedocAdapter("Firebase"), diff --git a/docs/sidebars.js b/docs/sidebars.js index 53567a1353..3c25bf1743 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -55,6 +55,7 @@ module.exports = { link: { type: "doc", id: "reference/adapters/index" }, items: [ { type: "doc", id: "reference/adapter/dgraph/index" }, + { type: "doc", id: "reference/adapter/drizzle/index" }, { type: "doc", id: "reference/adapter/dynamodb/index" }, { type: "doc", id: "reference/adapter/fauna/index" }, { type: "doc", id: "reference/adapter/firebase/index" }, diff --git a/docs/static/img/adapters/drizzle-orm.png b/docs/static/img/adapters/drizzle-orm.png new file mode 100644 index 0000000000..7626548943 Binary files /dev/null and b/docs/static/img/adapters/drizzle-orm.png differ diff --git a/packages/adapter-drizzle/README.md b/packages/adapter-drizzle/README.md new file mode 100644 index 0000000000..bfcb702e94 --- /dev/null +++ b/packages/adapter-drizzle/README.md @@ -0,0 +1,28 @@ +

+
+
+ + + + + +

Drizzle ORM Adapter - NextAuth.js / Auth.js

+

+ + TypeScript + + + npm + + + Downloads + + + Github Stars + +

+

+ +--- + +Check out the documentation at [authjs.dev](https://authjs.dev/reference/adapter/drizzle). diff --git a/packages/adapter-drizzle/package.json b/packages/adapter-drizzle/package.json new file mode 100644 index 0000000000..f18c292950 --- /dev/null +++ b/packages/adapter-drizzle/package.json @@ -0,0 +1,65 @@ +{ + "name": "@auth/drizzle-adapter", + "version": "0.0.1", + "description": "Drizzle adapter for Auth.js.", + "homepage": "https://authjs.dev", + "repository": "https://github.com/nextauthjs/next-auth", + "bugs": { + "url": "https://github.com/nextauthjs/next-auth/issues" + }, + "author": "Anthony Shew", + "type": "module", + "types": "./index.d.ts", + "files": [ + "*.js", + "*.d.ts*", + "lib", + "src" + ], + "exports": { + ".": { + "types": "./index.d.ts", + "import": "./index.js" + } + }, + "license": "ISC", + "keywords": [ + "next-auth", + "@auth", + "Auth.js", + "next.js", + "oauth", + "drizzle" + ], + "private": false, + "publishConfig": { + "access": "public" + }, + "scripts": { + "clean": "find . -type d -name \".drizzle\" | xargs rm -rf", + "test": "pnpm test:mysql && pnpm test:sqlite && pnpm test:pg", + "test:mysql": "pnpm clean && ./tests/mysql/test.sh", + "test:sqlite": "pnpm clean && ./tests/sqlite/test.sh", + "test:pg": "pnpm clean && ./tests/pg/test.sh", + "build": "tsc", + "dev": "drizzle-kit generate:mysql --schema=src/schema.ts --out=.drizzle && tsc -w" + }, + "dependencies": { + "@auth/core": "workspace:*" + }, + "devDependencies": { + "@next-auth/adapter-test": "workspace:*", + "@next-auth/tsconfig": "workspace:*", + "@types/better-sqlite3": "^7.6.4", + "@types/uuid": "^8.3.3", + "better-sqlite3": "^8.4.0", + "drizzle-kit": "^0.19.5", + "drizzle-orm": "^0.27.0", + "jest": "^27.4.3", + "mysql2": "^3.2.0", + "postgres": "^3.3.4" + }, + "jest": { + "preset": "@next-auth/adapter-test/jest" + } +} diff --git a/packages/adapter-drizzle/src/index.ts b/packages/adapter-drizzle/src/index.ts new file mode 100644 index 0000000000..974e282345 --- /dev/null +++ b/packages/adapter-drizzle/src/index.ts @@ -0,0 +1,268 @@ +/** + *
+ *

Official Drizzle ORM adapter for Auth.js / NextAuth.js.

+ * + * + * + *
+ * + * ## Installation + * + * ```bash npm2yarn2pnpm + * npm install drizzle-orm @auth/drizzle-adapter + * npm install drizzle-kit --save-dev + * ``` + * + * @module @auth/drizzle-adapter + */ + +import { mySqlDrizzleAdapter } from "./lib/mysql.js" +import { pgDrizzleAdapter } from "./lib/pg.js" +import { SQLiteDrizzleAdapter } from "./lib/sqlite.js" +import { + isMySqlDatabase, + isPgDatabase, + isSQLiteDatabase, + SqlFlavorOptions, +} from "./lib/utils.js" + +import type { Adapter } from "@auth/core/adapters" + +/** + * Add the adapter to your `app/api/[...nextauth]/route.js` next-auth configuration object. + * + * ```ts title="pages/api/auth/[...nextauth].ts" + * import NextAuth from "next-auth" + * import GoogleProvider from "next-auth/providers/google" + * import { DrizzleAdapter } from "@auth/drizzle-adapter" + * import { db } from "./schema" + * + * export default NextAuth({ + * adapter: DrizzleAdapter(db), + * providers: [ + * GoogleProvider({ + * clientId: process.env.GOOGLE_CLIENT_ID, + * clientSecret: process.env.GOOGLE_CLIENT_SECRET, + * }), + * ], + * }) + * ``` + * + * ## Setup + * + * First, create a schema that includes [the minimum requirements for a `next-auth` adapter](/reference/adapters#models). You can select your favorite SQL flavor below and copy it. + * Additionally, you may extend the schema from the minimum requirements to suit your needs. + * + * - [Postgres](#postgres) + * - [MySQL](#mysql) + * - [SQLite](#sqlite) + * + * ### Postgres + + * ```ts title="schema.ts" + * import { + * timestamp, + * pgTable, + * text, + * primaryKey, + * integer + * } from "drizzle-orm/pg-core" + * import type { AdapterAccount } from '@auth/core/adapters' + * + * export const users = pgTable("users", { + * id: text("id").notNull().primaryKey(), + * name: text("name"), + * email: text("email").notNull(), + * emailVerified: timestamp("emailVerified", { mode: "date" }), + * image: text("image"), + * }) + * + * export const accounts = pgTable( + * "accounts", + * { + * userId: text("userId") + * .notNull() + * .references(() => users.id, { onDelete: "cascade" }), + * type: text("type").$type().notNull(), + * provider: text("provider").notNull(), + * providerAccountId: text("providerAccountId").notNull(), + * refresh_token: text("refresh_token"), + * access_token: text("access_token"), + * expires_at: integer("expires_at"), + * token_type: text("token_type"), + * scope: text("scope"), + * id_token: text("id_token"), + * session_state: text("session_state"), + * }, + * (account) => ({ + * compoundKey: primaryKey(account.provider, account.providerAccountId), + * }) + * ) + * + * export const sessions = pgTable("sessions", { + * sessionToken: text("sessionToken").notNull().primaryKey(), + * userId: text("userId") + * .notNull() + * .references(() => users.id, { onDelete: "cascade" }), + * expires: timestamp("expires", { mode: "date" }).notNull(), + * }) + * + * export const verificationTokens = pgTable( + * "verificationToken", + * { + * identifier: text("identifier").notNull(), + * token: text("token").notNull(), + * expires: timestamp("expires", { mode: "date" }).notNull(), + * }, + * (vt) => ({ + * compoundKey: primaryKey(vt.identifier, vt.token), + * }) + * ) + * ``` + * + * ### MySQL + * + * ```ts title="schema.ts" + * import { + * int, + * timestamp, + * mysqlTable, + * primaryKey, + * varchar, + * } from "drizzle-orm/mysql-core" + * import type { AdapterAccount } from "@auth/core/adapters" + * + * export const users = mysqlTable("users", { + * id: varchar("id", { length: 255 }).notNull().primaryKey(), + * name: varchar("name", { length: 255 }), + * email: varchar("email", { length: 255 }).notNull(), + * emailVerified: timestamp("emailVerified", { mode: "date", fsp: 3 }).defaultNow(), + * image: varchar("image", { length: 255 }), + * }) + * + * export const accounts = mysqlTable( + * "accounts", + * { + * userId: varchar("userId", { length: 255 }) + * .notNull() + * .references(() => users.id, { onDelete: "cascade" }), + * type: varchar("type", { length: 255 }).$type().notNull(), + * provider: varchar("provider", { length: 255 }).notNull(), + * providerAccountId: varchar("providerAccountId", { length: 255 }).notNull(), + * refresh_token: varchar("refresh_token", { length: 255 }), + * access_token: varchar("access_token", { length: 255 }), + * expires_at: int("expires_at"), + * token_type: varchar("token_type", { length: 255 }), + * scope: varchar("scope", { length: 255 }), + * id_token: varchar("id_token", { length: 255 }), + * session_state: varchar("session_state", { length: 255 }), + * }, + * (account) => ({ + * compoundKey: primaryKey(account.provider, account.providerAccountId), + * }) + * ) + * + * export const sessions = mysqlTable("sessions", { + * sessionToken: varchar("sessionToken", { length: 255 }).notNull().primaryKey(), + * userId: varchar("userId", { length: 255 }) + * .notNull() + * .references(() => users.id, { onDelete: "cascade" }), + * expires: timestamp("expires", { mode: "date" }).notNull(), + * }) + * + * export const verificationTokens = mysqlTable( + * "verificationToken", + * { + * identifier: varchar("identifier", { length: 255 }).notNull(), + * token: varchar("token", { length: 255 }).notNull(), + * expires: timestamp("expires", { mode: "date" }).notNull(), + * }, + * (vt) => ({ + * compoundKey: primaryKey(vt.identifier, vt.token), + * }) + * ) + * ``` + * + * ### SQLite + * + * ```ts title="schema.ts" + * import { integer, sqliteTable, text, primaryKey } from "drizzle-orm/sqlite-core" + * import type { AdapterAccount } from "@auth/core/adapters" + * + * export const users = sqliteTable("users", { + * id: text("id").notNull().primaryKey(), + * name: text("name"), + * email: text("email").notNull(), + * emailVerified: integer("emailVerified", { mode: "timestamp_ms" }), + * image: text("image"), + * }) + * + * export const accounts = sqliteTable( + * "accounts", + * { + * userId: text("userId") + * .notNull() + * .references(() => users.id, { onDelete: "cascade" }), + * type: text("type").$type().notNull(), + * provider: text("provider").notNull(), + * providerAccountId: text("providerAccountId").notNull(), + * refresh_token: text("refresh_token"), + * access_token: text("access_token"), + * expires_at: integer("expires_at"), + * token_type: text("token_type"), + * scope: text("scope"), + * id_token: text("id_token"), + * session_state: text("session_state"), + * }, + * (account) => ({ + * compoundKey: primaryKey(account.provider, account.providerAccountId), + * }) + * ) + * + * export const sessions = sqliteTable("sessions", { + * sessionToken: text("sessionToken").notNull().primaryKey(), + * userId: text("userId") + * .notNull() + * .references(() => users.id, { onDelete: "cascade" }), + * expires: integer("expires", { mode: "timestamp_ms" }).notNull(), + * }) + * + * export const verificationTokens = sqliteTable( + * "verificationToken", + * { + * identifier: text("identifier").notNull(), + * token: text("token").notNull(), + * expires: integer("expires", { mode: "timestamp_ms" }).notNull(), + * }, + * (vt) => ({ + * compoundKey: primaryKey(vt.identifier, vt.token), + * }) + * ) + * ``` + * + * ## Migrating your database + * With your schema now described in your code, you'll need to migrate your database to your schema. + * + * For full documentation on how to run migrations with Drizzle, [visit the Drizzle documentation](https://orm.drizzle.team/kit-docs/overview#running-migrations). + * + * --- + * + **/ +export function DrizzleAdapter( + db: SqlFlavor +): Adapter { + if (isMySqlDatabase(db)) { + // We need to cast to unknown since the type overlaps (PScale is MySQL based) + return mySqlDrizzleAdapter(db) + } + + if (isPgDatabase(db)) { + return pgDrizzleAdapter(db) + } + + if (isSQLiteDatabase(db)) { + return SQLiteDrizzleAdapter(db) + } + + throw new Error("Unsupported database type in Auth.js Drizzle adapter.") +} diff --git a/packages/adapter-drizzle/src/lib/mysql.ts b/packages/adapter-drizzle/src/lib/mysql.ts new file mode 100644 index 0000000000..013fa2346c --- /dev/null +++ b/packages/adapter-drizzle/src/lib/mysql.ts @@ -0,0 +1,255 @@ +import { and, eq } from "drizzle-orm" +import { + int, + timestamp, + mysqlTable, + primaryKey, + varchar, +} from "drizzle-orm/mysql-core" + +import type { Adapter, AdapterAccount } from "@auth/core/adapters" +import type { MySql2Database } from "drizzle-orm/mysql2" + +export const users = mysqlTable("users", { + id: varchar("id", { length: 255 }).notNull().primaryKey(), + name: varchar("name", { length: 255 }), + email: varchar("email", { length: 255 }).notNull(), + emailVerified: timestamp("emailVerified", { + mode: "date", + fsp: 3, + }).defaultNow(), + image: varchar("image", { length: 255 }), +}) + +export const accounts = mysqlTable( + "accounts", + { + userId: varchar("userId", { length: 255 }) + .notNull() + .references(() => users.id, { onDelete: "cascade" }), + type: varchar("type", { length: 255 }) + .$type() + .notNull(), + provider: varchar("provider", { length: 255 }).notNull(), + providerAccountId: varchar("providerAccountId", { length: 255 }).notNull(), + refresh_token: varchar("refresh_token", { length: 255 }), + access_token: varchar("access_token", { length: 255 }), + expires_at: int("expires_at"), + token_type: varchar("token_type", { length: 255 }), + scope: varchar("scope", { length: 255 }), + id_token: varchar("id_token", { length: 255 }), + session_state: varchar("session_state", { length: 255 }), + }, + (account) => ({ + compoundKey: primaryKey(account.provider, account.providerAccountId), + }) +) + +export const sessions = mysqlTable("sessions", { + sessionToken: varchar("sessionToken", { length: 255 }).notNull().primaryKey(), + userId: varchar("userId", { length: 255 }) + .notNull() + .references(() => users.id, { onDelete: "cascade" }), + expires: timestamp("expires", { mode: "date" }).notNull(), +}) + +export const verificationTokens = mysqlTable( + "verificationToken", + { + identifier: varchar("identifier", { length: 255 }).notNull(), + token: varchar("token", { length: 255 }).notNull(), + expires: timestamp("expires", { mode: "date" }).notNull(), + }, + (vt) => ({ + compoundKey: primaryKey(vt.identifier, vt.token), + }) +) + +export const schema = { users, accounts, sessions, verificationTokens } +export type DefaultSchema = typeof schema + +export function mySqlDrizzleAdapter( + client: MySql2Database> +): Adapter { + return { + async createUser(data) { + const id = crypto.randomUUID() + + await client.insert(users).values({ ...data, id }) + + return await client + .select() + .from(users) + .where(eq(users.id, id)) + .then((res) => res[0]) + }, + async getUser(data) { + const thing = + (await client + .select() + .from(users) + .where(eq(users.id, data)) + .then((res) => res[0])) ?? null + + return thing + }, + async getUserByEmail(data) { + const user = + (await client + .select() + .from(users) + .where(eq(users.email, data)) + .then((res) => res[0])) ?? null + + return user + }, + async createSession(data) { + await client.insert(sessions).values(data) + + return await client + .select() + .from(sessions) + .where(eq(sessions.sessionToken, data.sessionToken)) + .then((res) => res[0]) + }, + async getSessionAndUser(data) { + const sessionAndUser = + (await client + .select({ + session: sessions, + user: users, + }) + .from(sessions) + .where(eq(sessions.sessionToken, data)) + .innerJoin(users, eq(users.id, sessions.userId)) + .then((res) => res[0])) ?? null + + return sessionAndUser + }, + async updateUser(data) { + if (!data.id) { + throw new Error("No user id.") + } + + await client.update(users).set(data).where(eq(users.id, data.id)) + + return await client + .select() + .from(users) + .where(eq(users.id, data.id)) + .then((res) => res[0]) + }, + async updateSession(data) { + await client + .update(sessions) + .set(data) + .where(eq(sessions.sessionToken, data.sessionToken)) + + return await client + .select() + .from(sessions) + .where(eq(sessions.sessionToken, data.sessionToken)) + .then((res) => res[0]) + }, + async linkAccount(rawAccount) { + await client + .insert(accounts) + .values(rawAccount) + .then((res) => res[0]) + }, + async getUserByAccount(account) { + const dbAccount = + (await client + .select() + .from(accounts) + .where( + and( + eq(accounts.providerAccountId, account.providerAccountId), + eq(accounts.provider, account.provider) + ) + ) + .leftJoin(users, eq(accounts.userId, users.id)) + .then((res) => res[0])) ?? null + + if (!dbAccount) { + return null + } + + return dbAccount.users + }, + async deleteSession(sessionToken) { + const session = + (await client + .select() + .from(sessions) + .where(eq(sessions.sessionToken, sessionToken)) + .then((res) => res[0])) ?? null + + await client + .delete(sessions) + .where(eq(sessions.sessionToken, sessionToken)) + + return session + }, + async createVerificationToken(token) { + await client.insert(verificationTokens).values(token) + + return await client + .select() + .from(verificationTokens) + .where(eq(verificationTokens.identifier, token.identifier)) + .then((res) => res[0]) + }, + async useVerificationToken(token) { + try { + const deletedToken = + (await client + .select() + .from(verificationTokens) + .where( + and( + eq(verificationTokens.identifier, token.identifier), + eq(verificationTokens.token, token.token) + ) + ) + .then((res) => res[0])) ?? null + + await client + .delete(verificationTokens) + .where( + and( + eq(verificationTokens.identifier, token.identifier), + eq(verificationTokens.token, token.token) + ) + ) + + return deletedToken + } catch (err) { + throw new Error("No verification token found.") + } + }, + async deleteUser(id) { + const user = await client + .select() + .from(users) + .where(eq(users.id, id)) + .then((res) => res[0] ?? null) + + await client.delete(users).where(eq(users.id, id)) + + return user + }, + async unlinkAccount(account) { + await client + .delete(accounts) + .where( + and( + eq(accounts.providerAccountId, account.providerAccountId), + eq(accounts.provider, account.provider) + ) + ) + + return undefined + }, + } +} diff --git a/packages/adapter-drizzle/src/lib/pg.ts b/packages/adapter-drizzle/src/lib/pg.ts new file mode 100644 index 0000000000..cebf8aaca7 --- /dev/null +++ b/packages/adapter-drizzle/src/lib/pg.ts @@ -0,0 +1,225 @@ +import { and, eq } from "drizzle-orm" +import { + timestamp, + pgTable, + text, + primaryKey, + integer, +} from "drizzle-orm/pg-core" + +import type { PostgresJsDatabase } from "drizzle-orm/postgres-js" +import type { Adapter, AdapterAccount } from "@auth/core/adapters" + +export const users = pgTable("users", { + id: text("id").notNull().primaryKey(), + name: text("name"), + email: text("email").notNull(), + emailVerified: timestamp("emailVerified", { mode: "date" }), + image: text("image"), +}) + +export const accounts = pgTable( + "accounts", + { + userId: text("userId") + .notNull() + .references(() => users.id, { onDelete: "cascade" }), + type: text("type").$type().notNull(), + provider: text("provider").notNull(), + providerAccountId: text("providerAccountId").notNull(), + refresh_token: text("refresh_token"), + access_token: text("access_token"), + expires_at: integer("expires_at"), + token_type: text("token_type"), + scope: text("scope"), + id_token: text("id_token"), + session_state: text("session_state"), + }, + (account) => ({ + compoundKey: primaryKey(account.provider, account.providerAccountId), + }) +) + +export const sessions = pgTable("sessions", { + sessionToken: text("sessionToken").notNull().primaryKey(), + userId: text("userId") + .notNull() + .references(() => users.id, { onDelete: "cascade" }), + expires: timestamp("expires", { mode: "date" }).notNull(), +}) + +export const verificationTokens = pgTable( + "verificationToken", + { + identifier: text("identifier").notNull(), + token: text("token").notNull(), + expires: timestamp("expires", { mode: "date" }).notNull(), + }, + (vt) => ({ + compoundKey: primaryKey(vt.identifier, vt.token), + }) +) + +export const schema = { users, accounts, sessions, verificationTokens } +export type DefaultSchema = typeof schema + +export function pgDrizzleAdapter( + client: PostgresJsDatabase> +): Adapter { + return { + async createUser(data) { + return await client + .insert(users) + .values({ ...data, id: crypto.randomUUID() }) + .returning() + .then((res) => res[0] ?? null) + }, + async getUser(data) { + return await client + .select() + .from(users) + .where(eq(users.id, data)) + .then((res) => res[0] ?? null) + }, + async getUserByEmail(data) { + return await client + .select() + .from(users) + .where(eq(users.email, data)) + .then((res) => res[0] ?? null) + }, + async createSession(data) { + return await client + .insert(sessions) + .values(data) + .returning() + .then((res) => res[0]) + }, + async getSessionAndUser(data) { + return await client + .select({ + session: sessions, + user: users, + }) + .from(sessions) + .where(eq(sessions.sessionToken, data)) + .innerJoin(users, eq(users.id, sessions.userId)) + .then((res) => res[0] ?? null) + }, + async updateUser(data) { + if (!data.id) { + throw new Error("No user id.") + } + + return await client + .update(users) + .set(data) + .where(eq(users.id, data.id)) + .returning() + .then((res) => res[0]) + }, + async updateSession(data) { + return await client + .update(sessions) + .set(data) + .where(eq(sessions.sessionToken, data.sessionToken)) + .returning() + .then((res) => res[0]) + }, + async linkAccount(rawAccount) { + const updatedAccount = await client + .insert(accounts) + .values(rawAccount) + .returning() + .then((res) => res[0]) + + // Drizzle will return `null` for fields that are not defined. + // However, the return type is expecting `undefined`. + const account = { + ...updatedAccount, + access_token: updatedAccount.access_token ?? undefined, + token_type: updatedAccount.token_type ?? undefined, + id_token: updatedAccount.id_token ?? undefined, + refresh_token: updatedAccount.refresh_token ?? undefined, + scope: updatedAccount.scope ?? undefined, + expires_at: updatedAccount.expires_at ?? undefined, + session_state: updatedAccount.session_state ?? undefined, + } + + return account + }, + async getUserByAccount(account) { + const dbAccount = + (await client + .select() + .from(accounts) + .where( + and( + eq(accounts.providerAccountId, account.providerAccountId), + eq(accounts.provider, account.provider) + ) + ) + .leftJoin(users, eq(accounts.userId, users.id)) + .then((res) => res[0])) ?? null + + if (!dbAccount) { + return null + } + + return dbAccount.users + }, + async deleteSession(sessionToken) { + const session = await client + .delete(sessions) + .where(eq(sessions.sessionToken, sessionToken)) + .returning() + .then((res) => res[0] ?? null) + + return session + }, + async createVerificationToken(token) { + return await client + .insert(verificationTokens) + .values(token) + .returning() + .then((res) => res[0]) + }, + async useVerificationToken(token) { + try { + return await client + .delete(verificationTokens) + .where( + and( + eq(verificationTokens.identifier, token.identifier), + eq(verificationTokens.token, token.token) + ) + ) + .returning() + .then((res) => res[0] ?? null) + } catch (err) { + throw new Error("No verification token found.") + } + }, + async deleteUser(id) { + await client + .delete(users) + .where(eq(users.id, id)) + .returning() + .then((res) => res[0] ?? null) + }, + async unlinkAccount(account) { + const { type, provider, providerAccountId, userId } = await client + .delete(accounts) + .where( + and( + eq(accounts.providerAccountId, account.providerAccountId), + eq(accounts.provider, account.provider) + ) + ) + .returning() + .then((res) => res[0] ?? null) + + return { provider, type, providerAccountId, userId } + }, + } +} diff --git a/packages/adapter-drizzle/src/lib/sqlite.ts b/packages/adapter-drizzle/src/lib/sqlite.ts new file mode 100644 index 0000000000..b0efe78baf --- /dev/null +++ b/packages/adapter-drizzle/src/lib/sqlite.ts @@ -0,0 +1,203 @@ +import { eq, and } from "drizzle-orm" +import { + integer, + sqliteTable, + text, + primaryKey, + BaseSQLiteDatabase, +} from "drizzle-orm/sqlite-core" + +import type { Adapter, AdapterAccount } from "@auth/core/adapters" + +export const users = sqliteTable("users", { + id: text("id").notNull().primaryKey(), + name: text("name"), + email: text("email").notNull(), + emailVerified: integer("emailVerified", { mode: "timestamp_ms" }), + image: text("image"), +}) + +export const accounts = sqliteTable( + "accounts", + { + userId: text("userId") + .notNull() + .references(() => users.id, { onDelete: "cascade" }), + type: text("type").$type().notNull(), + provider: text("provider").notNull(), + providerAccountId: text("providerAccountId").notNull(), + refresh_token: text("refresh_token"), + access_token: text("access_token"), + expires_at: integer("expires_at"), + token_type: text("token_type"), + scope: text("scope"), + id_token: text("id_token"), + session_state: text("session_state"), + }, + (account) => ({ + compoundKey: primaryKey(account.provider, account.providerAccountId), + }) +) + +export const sessions = sqliteTable("sessions", { + sessionToken: text("sessionToken").notNull().primaryKey(), + userId: text("userId") + .notNull() + .references(() => users.id, { onDelete: "cascade" }), + expires: integer("expires", { mode: "timestamp_ms" }).notNull(), +}) + +export const verificationTokens = sqliteTable( + "verificationToken", + { + identifier: text("identifier").notNull(), + token: text("token").notNull(), + expires: integer("expires", { mode: "timestamp_ms" }).notNull(), + }, + (vt) => ({ + compoundKey: primaryKey(vt.identifier, vt.token), + }) +) + +export const schema = { users, accounts, sessions, verificationTokens } +export type DefaultSchema = typeof schema + +export function SQLiteDrizzleAdapter( + client: BaseSQLiteDatabase +): Adapter { + return { + createUser(data) { + return client + .insert(users) + .values({ ...data, id: crypto.randomUUID() }) + .returning() + .get() + }, + getUser(data) { + return client.select().from(users).where(eq(users.id, data)).get() ?? null + }, + getUserByEmail(data) { + return ( + client.select().from(users).where(eq(users.email, data)).get() ?? null + ) + }, + createSession(data) { + return client.insert(sessions).values(data).returning().get() + }, + getSessionAndUser(data) { + return ( + client + .select({ + session: sessions, + user: users, + }) + .from(sessions) + .where(eq(sessions.sessionToken, data)) + .innerJoin(users, eq(users.id, sessions.userId)) + .get() ?? null + ) + }, + updateUser(data) { + if (!data.id) { + throw new Error("No user id.") + } + + return client + .update(users) + .set(data) + .where(eq(users.id, data.id)) + .returning() + .get() + }, + updateSession(data) { + return client + .update(sessions) + .set(data) + .where(eq(sessions.sessionToken, data.sessionToken)) + .returning() + .get() + }, + linkAccount(rawAccount) { + const updatedAccount = client + .insert(accounts) + .values(rawAccount) + .returning() + .get() + + const account: AdapterAccount = { + ...updatedAccount, + type: updatedAccount.type, + access_token: updatedAccount.access_token ?? undefined, + token_type: updatedAccount.token_type ?? undefined, + id_token: updatedAccount.id_token ?? undefined, + refresh_token: updatedAccount.refresh_token ?? undefined, + scope: updatedAccount.scope ?? undefined, + expires_at: updatedAccount.expires_at ?? undefined, + session_state: updatedAccount.session_state ?? undefined, + } + + return account + }, + getUserByAccount(account) { + const results = client + .select() + .from(accounts) + .leftJoin(users, eq(users.id, accounts.userId)) + .where( + and( + eq(accounts.provider, account.provider), + eq(accounts.providerAccountId, account.providerAccountId) + ) + ) + .get() + + return results?.users ?? null + }, + deleteSession(sessionToken) { + return ( + client + .delete(sessions) + .where(eq(sessions.sessionToken, sessionToken)) + .returning() + .get() ?? null + ) + }, + createVerificationToken(token) { + return client.insert(verificationTokens).values(token).returning().get() + }, + useVerificationToken(token) { + try { + return ( + client + .delete(verificationTokens) + .where( + and( + eq(verificationTokens.identifier, token.identifier), + eq(verificationTokens.token, token.token) + ) + ) + .returning() + .get() ?? null + ) + } catch (err) { + throw new Error("No verification token found.") + } + }, + deleteUser(id) { + return client.delete(users).where(eq(users.id, id)).returning().get() + }, + unlinkAccount(account) { + client + .delete(accounts) + .where( + and( + eq(accounts.providerAccountId, account.providerAccountId), + eq(accounts.provider, account.provider) + ) + ) + .run() + + return undefined + }, + } +} diff --git a/packages/adapter-drizzle/src/lib/utils.ts b/packages/adapter-drizzle/src/lib/utils.ts new file mode 100644 index 0000000000..c622930b59 --- /dev/null +++ b/packages/adapter-drizzle/src/lib/utils.ts @@ -0,0 +1,47 @@ +import { MySqlDatabase } from "drizzle-orm/mysql-core" +import { PgDatabase } from "drizzle-orm/pg-core" +import { BaseSQLiteDatabase } from "drizzle-orm/sqlite-core" + +import type { AnyMySqlTable } from "drizzle-orm/mysql-core" +import type { AnyPgTable } from "drizzle-orm/pg-core" +import type { AnySQLiteTable } from "drizzle-orm/sqlite-core" +import type { DefaultSchema as PgSchema } from "./pg.js" +import type { DefaultSchema as MySqlSchema } from "./mysql.js" +import type { DefaultSchema as SQLiteSchema } from "./sqlite.js" + +export type AnyMySqlDatabase = MySqlDatabase +export type AnyPgDatabase = PgDatabase +export type AnySQLiteDatabase = BaseSQLiteDatabase + +export interface MinimumSchema { + mysql: MySqlSchema & Record + pg: PgSchema & Record + sqlite: SQLiteSchema & Record +} + +export type SqlFlavorOptions = + | AnyMySqlDatabase + | AnyPgDatabase + | AnySQLiteDatabase + +export type ClientFlavors = Flavor extends AnyMySqlDatabase + ? MinimumSchema["mysql"] + : Flavor extends AnyPgDatabase + ? MinimumSchema["pg"] + : Flavor extends AnySQLiteDatabase + ? MinimumSchema["sqlite"] + : never + +export function isMySqlDatabase( + db: any +): db is MySqlDatabase { + return db instanceof MySqlDatabase +} + +export function isPgDatabase(db: any): db is PgDatabase { + return db instanceof PgDatabase +} + +export function isSQLiteDatabase(db: any): db is AnySQLiteDatabase { + return db instanceof BaseSQLiteDatabase +} diff --git a/packages/adapter-drizzle/tests/fixtures.ts b/packages/adapter-drizzle/tests/fixtures.ts new file mode 100644 index 0000000000..a3c1f04d32 --- /dev/null +++ b/packages/adapter-drizzle/tests/fixtures.ts @@ -0,0 +1,43 @@ +// This work is needed as workaround to Drizzle truncating millisecond precision. +// https://github.com/drizzle-team/drizzle-orm/pull/668 + +import { randomUUID } from "../../adapter-test" + +const emailVerified = new Date() +emailVerified.setMilliseconds(0) + +const ONE_WEEK_FROM_NOW = new Date(Date.now() + 1000 * 60 * 60 * 24 * 7) +ONE_WEEK_FROM_NOW.setMilliseconds(0) +const FIFTEEN_MINUTES_FROM_NOW = new Date(Date.now() + 15 * 60 * 1000) +FIFTEEN_MINUTES_FROM_NOW.setMilliseconds(0) + +const ONE_MONTH = 1000 * 60 * 60 * 24 * 30 +const ONE_MONTH_FROM_NOW = new Date(Date.now() + ONE_MONTH) +ONE_MONTH_FROM_NOW.setMilliseconds(0) + +export const fixtures = { + user: { + email: "fill@murray.com", + image: "https://www.fillmurray.com/460/300", + name: "Fill Murray", + emailVerified, + }, + session: { + sessionToken: randomUUID(), + expires: ONE_WEEK_FROM_NOW, + }, + sessionUpdateExpires: ONE_MONTH_FROM_NOW, + verificationTokenExpires: FIFTEEN_MINUTES_FROM_NOW, + account: { + provider: "github", + providerAccountId: randomUUID(), + type: "oauth", + access_token: randomUUID(), + expires_at: ONE_MONTH / 1000, + id_token: randomUUID(), + refresh_token: randomUUID(), + token_type: "bearer", + scope: "user", + session_state: randomUUID(), + }, +} diff --git a/packages/adapter-drizzle/tests/mysql/drizzle.config.ts b/packages/adapter-drizzle/tests/mysql/drizzle.config.ts new file mode 100644 index 0000000000..caea468a06 --- /dev/null +++ b/packages/adapter-drizzle/tests/mysql/drizzle.config.ts @@ -0,0 +1,13 @@ +import type { Config } from "drizzle-kit" + +export default { + schema: "./tests/mysql/schema.ts", + out: "./tests/mysql/.drizzle", + driver: "mysql2", + dbCredentials: { + host: "localhost", + user: "root", + password: "password", + database: "next-auth", + }, +} satisfies Config diff --git a/packages/adapter-drizzle/tests/mysql/index.test.ts b/packages/adapter-drizzle/tests/mysql/index.test.ts new file mode 100644 index 0000000000..5f6be83778 --- /dev/null +++ b/packages/adapter-drizzle/tests/mysql/index.test.ts @@ -0,0 +1,71 @@ +import { runBasicTests } from "../../../adapter-test" +import { DrizzleAdapter } from "../../src" +import { db, sessions, verificationTokens, accounts, users } from "./schema" +import { eq, and } from "drizzle-orm" +import { fixtures } from "../fixtures" + +globalThis.crypto ??= require("node:crypto").webcrypto + +runBasicTests({ + adapter: DrizzleAdapter(db), + fixtures, + db: { + connect: async () => { + await Promise.all([ + db.delete(sessions), + db.delete(accounts), + db.delete(verificationTokens), + db.delete(users), + ]) + }, + disconnect: async () => { + await Promise.all([ + db.delete(sessions), + db.delete(accounts), + db.delete(verificationTokens), + db.delete(users), + ]) + }, + user: async (id) => { + const user = await db + .select() + .from(users) + .where(eq(users.id, id)) + .then((res) => res[0] ?? null) + return user + }, + session: async (sessionToken) => { + const session = await db + .select() + .from(sessions) + .where(eq(sessions.sessionToken, sessionToken)) + .then((res) => res[0] ?? null) + + return session + }, + account: (provider_providerAccountId) => { + const account = db + .select() + .from(accounts) + .where( + eq( + accounts.providerAccountId, + provider_providerAccountId.providerAccountId + ) + ) + .then((res) => res[0] ?? null) + return account + }, + verificationToken: (identifier_token) => + db + .select() + .from(verificationTokens) + .where( + and( + eq(verificationTokens.token, identifier_token.token), + eq(verificationTokens.identifier, identifier_token.identifier) + ) + ) + .then((res) => res[0]) ?? null, + }, +}) diff --git a/packages/adapter-drizzle/tests/mysql/schema.ts b/packages/adapter-drizzle/tests/mysql/schema.ts new file mode 100644 index 0000000000..e0c89e4f50 --- /dev/null +++ b/packages/adapter-drizzle/tests/mysql/schema.ts @@ -0,0 +1,29 @@ +import type { AdapterAccount } from "@auth/core/adapters" +import { + mysqlTable, + varchar, + timestamp, + int, + primaryKey, +} from "drizzle-orm/mysql-core" +import { drizzle } from "drizzle-orm/mysql2" +import { createPool } from "mysql2" +import { + users, + accounts, + sessions, + verificationTokens, + schema, +} from "../../src/lib/mysql" + +const poolConnection = createPool({ + host: "localhost", + user: "root", + password: "password", + database: "next-auth", +}) + +export { users, accounts, sessions, verificationTokens } +export const db = drizzle(poolConnection, { + schema: schema, +}) diff --git a/packages/adapter-drizzle/tests/mysql/test.sh b/packages/adapter-drizzle/tests/mysql/test.sh new file mode 100755 index 0000000000..d7e2b2c3a4 --- /dev/null +++ b/packages/adapter-drizzle/tests/mysql/test.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash + +echo "Initializing container for MySQL tests." + +MYSQL_DATABASE=next-auth +MYSQL_ROOT_PASSWORD=password +MYSQL_CONTAINER_NAME=next-auth-mysql-test + +docker run -d --rm \ +-e MYSQL_DATABASE=${MYSQL_DATABASE} \ +-e MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} \ +--name "${MYSQL_CONTAINER_NAME}" \ +-p 3306:3306 \ +mysql:8 \ +--default-authentication-plugin=mysql_native_password + +echo "Waiting 15 sec for db to start..." && sleep 15 + +drizzle-kit generate:mysql --config=./tests/mysql/drizzle.config.ts +drizzle-kit push:mysql --config=./tests/mysql/drizzle.config.ts +jest ./tests/mysql/index.test.ts --forceExit +docker stop ${MYSQL_CONTAINER_NAME} \ No newline at end of file diff --git a/packages/adapter-drizzle/tests/pg/drizzle.config.ts b/packages/adapter-drizzle/tests/pg/drizzle.config.ts new file mode 100644 index 0000000000..644b61d5b0 --- /dev/null +++ b/packages/adapter-drizzle/tests/pg/drizzle.config.ts @@ -0,0 +1,13 @@ +import type { Config } from "drizzle-kit" + +export default { + schema: "./tests/pg/schema.ts", + out: "./tests/pg/.drizzle", + dbCredentials: { + database: "nextauth", + host: "nextauth", + user: "nextauth", + password: "nextauth", + port: 5432, + }, +} satisfies Config diff --git a/packages/adapter-drizzle/tests/pg/index.test.ts b/packages/adapter-drizzle/tests/pg/index.test.ts new file mode 100644 index 0000000000..79d9350bd1 --- /dev/null +++ b/packages/adapter-drizzle/tests/pg/index.test.ts @@ -0,0 +1,65 @@ +import { runBasicTests } from "../../../adapter-test" +import { DrizzleAdapter } from "../../src" +import { db, accounts, sessions, users, verificationTokens } from "./schema" +import { eq, and } from "drizzle-orm" +import { fixtures } from "../fixtures" + +globalThis.crypto ??= require("node:crypto").webcrypto + +runBasicTests({ + adapter: DrizzleAdapter(db), + fixtures, + db: { + connect: async () => { + await Promise.all([ + db.delete(sessions), + db.delete(accounts), + db.delete(verificationTokens), + db.delete(users), + ]) + }, + disconnect: async () => { + await Promise.all([ + db.delete(sessions), + db.delete(accounts), + db.delete(verificationTokens), + db.delete(users), + ]) + }, + user: async (id) => + db + .select() + .from(users) + .where(eq(users.id, id)) + .then((res) => res[0] ?? null), + session: (sessionToken) => + db + .select() + .from(sessions) + .where(eq(sessions.sessionToken, sessionToken)) + .then((res) => res[0] ?? null), + account: (provider_providerAccountId) => { + return db + .select() + .from(accounts) + .where( + eq( + accounts.providerAccountId, + provider_providerAccountId.providerAccountId + ) + ) + .then((res) => res[0] ?? null) + }, + verificationToken: (identifier_token) => + db + .select() + .from(verificationTokens) + .where( + and( + eq(verificationTokens.token, identifier_token.token), + eq(verificationTokens.identifier, identifier_token.identifier) + ) + ) + .then((res) => res[0] ?? null), + }, +}) diff --git a/packages/adapter-drizzle/tests/pg/migrator.ts b/packages/adapter-drizzle/tests/pg/migrator.ts new file mode 100644 index 0000000000..a6f0f6f85b --- /dev/null +++ b/packages/adapter-drizzle/tests/pg/migrator.ts @@ -0,0 +1,10 @@ +import { migrate } from "drizzle-orm/postgres-js/migrator" +import { db } from "./schema" + +const migrator = async () => { + await migrate(db, { migrationsFolder: "./tests/pg/.drizzle" }) +} + +migrator() + .then(() => process.exit(0)) + .catch(() => process.exit(1)) diff --git a/packages/adapter-drizzle/tests/pg/schema.ts b/packages/adapter-drizzle/tests/pg/schema.ts new file mode 100644 index 0000000000..7fc39791f1 --- /dev/null +++ b/packages/adapter-drizzle/tests/pg/schema.ts @@ -0,0 +1,11 @@ +import { drizzle } from "drizzle-orm/postgres-js" +import postgres from "postgres" +import { users, accounts, sessions, verificationTokens } from "../../src/lib/pg" + +const connectionString = "postgres://nextauth:nextauth@localhost:5432/nextauth" +const sql = postgres(connectionString, { max: 1 }) + +export const db = drizzle(sql, { + schema: { users, accounts, sessions, verificationTokens }, +}) +export { users, accounts, sessions, verificationTokens } diff --git a/packages/adapter-drizzle/tests/pg/test.sh b/packages/adapter-drizzle/tests/pg/test.sh new file mode 100755 index 0000000000..49e615688f --- /dev/null +++ b/packages/adapter-drizzle/tests/pg/test.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +echo "Initializing container for PostgreSQL tests." + +PGUSER=nextauth +PGPASSWORD=nextauth +PGDATABASE=nextauth +PGPORT=5432 +PG_CONTAINER_NAME=next-auth-postgres-test + +docker run -d --rm \ +-e POSTGRES_USER=${PGUSER} \ +-e POSTGRES_PASSWORD=${PGUSER} \ +-e POSTGRES_DB=${PGDATABASE} \ +-e POSTGRES_HOST_AUTH_METHOD=trust \ +--name "${PG_CONTAINER_NAME}" \ +-p ${PGPORT}:5432 \ +postgres:15.3 + +echo "Waiting 15 sec for db to start..." && sleep 15 + +drizzle-kit generate:pg --config=./tests/pg/drizzle.config.ts +npx tsx ./tests/pg/migrator.ts +jest ./tests/pg/index.test.ts --forceExit +docker stop ${PG_CONTAINER_NAME} \ No newline at end of file diff --git a/packages/adapter-drizzle/tests/sqlite/drizzle.config.ts b/packages/adapter-drizzle/tests/sqlite/drizzle.config.ts new file mode 100644 index 0000000000..bd13ea09c4 --- /dev/null +++ b/packages/adapter-drizzle/tests/sqlite/drizzle.config.ts @@ -0,0 +1,10 @@ +import type { Config } from "drizzle-kit" + +export default { + schema: "./tests/sqlite/schema.ts", + out: "./tests/sqlite/.drizzle", + driver: "better-sqlite", + dbCredentials: { + url: "./db.sqlite", + }, +} satisfies Config diff --git a/packages/adapter-drizzle/tests/sqlite/index.test.ts b/packages/adapter-drizzle/tests/sqlite/index.test.ts new file mode 100644 index 0000000000..6e30b089e2 --- /dev/null +++ b/packages/adapter-drizzle/tests/sqlite/index.test.ts @@ -0,0 +1,60 @@ +import { runBasicTests } from "../../../adapter-test" +import { DrizzleAdapter } from "../../src" +import { db, accounts, sessions, users, verificationTokens } from "./schema" +import { eq, and } from "drizzle-orm" + +globalThis.crypto ??= require("node:crypto").webcrypto + +runBasicTests({ + adapter: DrizzleAdapter(db), + db: { + connect: async () => { + await Promise.all([ + db.delete(sessions), + db.delete(accounts), + db.delete(verificationTokens), + db.delete(users), + ]) + }, + disconnect: async () => { + await Promise.all([ + db.delete(sessions), + db.delete(accounts), + db.delete(verificationTokens), + db.delete(users), + ]) + }, + user: (id) => db.select().from(users).where(eq(users.id, id)).get() ?? null, + session: (sessionToken) => + db + .select() + .from(sessions) + .where(eq(sessions.sessionToken, sessionToken)) + .get() ?? null, + account: (provider_providerAccountId) => { + return ( + db + .select() + .from(accounts) + .where( + eq( + accounts.providerAccountId, + provider_providerAccountId.providerAccountId + ) + ) + .get() ?? null + ) + }, + verificationToken: (identifier_token) => + db + .select() + .from(verificationTokens) + .where( + and( + eq(verificationTokens.token, identifier_token.token), + eq(verificationTokens.identifier, identifier_token.identifier) + ) + ) + .get() ?? null, + }, +}) diff --git a/packages/adapter-drizzle/tests/sqlite/schema.ts b/packages/adapter-drizzle/tests/sqlite/schema.ts new file mode 100644 index 0000000000..71af1fa544 --- /dev/null +++ b/packages/adapter-drizzle/tests/sqlite/schema.ts @@ -0,0 +1,20 @@ +import { drizzle } from "drizzle-orm/better-sqlite3" +import Database from "better-sqlite3" +import { + users, + accounts, + sessions, + verificationTokens, +} from "../../src/lib/sqlite" + +const sqlite = new Database("db.sqlite") + +export { users, accounts, sessions, verificationTokens } +export const db = drizzle(sqlite, { + schema: { + users, + accounts, + sessions, + verificationTokens, + }, +}) diff --git a/packages/adapter-drizzle/tests/sqlite/test.sh b/packages/adapter-drizzle/tests/sqlite/test.sh new file mode 100755 index 0000000000..59c3e2903c --- /dev/null +++ b/packages/adapter-drizzle/tests/sqlite/test.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +set -eu + + +echo "Running SQLite tests." + +rm -f db.sqlite + +drizzle-kit generate:sqlite --config=./tests/sqlite/drizzle.config.ts +drizzle-kit push:sqlite --config=./tests/sqlite/drizzle.config.ts +jest ./tests/sqlite/index.test.ts --forceExit \ No newline at end of file diff --git a/packages/adapter-drizzle/tsconfig.json b/packages/adapter-drizzle/tsconfig.json new file mode 100644 index 0000000000..726c2dc177 --- /dev/null +++ b/packages/adapter-drizzle/tsconfig.json @@ -0,0 +1,25 @@ +{ + "extends": "@next-auth/tsconfig/tsconfig.base.json", + "compilerOptions": { + "allowJs": true, + "baseUrl": ".", + "isolatedModules": true, + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "node", + "outDir": ".", + "rootDir": "src", + "skipDefaultLibCheck": true, + "strictNullChecks": true, + "stripInternal": true, + "declarationMap": true, + "declaration": true + }, + "include": [ + "src/**/*" + ], + "exclude": [ + "*.js", + "*.d.ts", + ] +} \ No newline at end of file diff --git a/packages/adapter-test/index.ts b/packages/adapter-test/index.ts index 175757307a..bb3d8c163b 100644 --- a/packages/adapter-test/index.ts +++ b/packages/adapter-test/index.ts @@ -15,6 +15,13 @@ const requiredMethods = [ ] export interface TestOptions { adapter: Adapter + fixtures?: { + user?: any + session?: any + account?: any + sessionUpdateExpires?: Date + verificationTokenExpires?: Date + }, db: { /** Generates UUID v4 by default. Use it to override how the test suite should generate IDs, like user id. */ id?: () => string @@ -67,11 +74,11 @@ export async function runBasicTests(options: TestOptions) { await options.db.disconnect?.() }) - let user: any = { + let user: any = options.fixtures?.user ?? { email: "fill@murray.com", image: "https://www.fillmurray.com/460/300", name: "Fill Murray", - emailVerified: new Date(), + emailVerified: new Date() } if (process.env.CUSTOM_MODEL === "1") { @@ -79,12 +86,12 @@ export async function runBasicTests(options: TestOptions) { user.phone = "00000000000" } - const session: any = { + const session: any = options.fixtures?.session ?? { sessionToken: randomUUID(), expires: ONE_WEEK_FROM_NOW, } - const account: any = { + const account: any = options.fixtures?.account ?? { provider: "github", providerAccountId: randomUUID(), type: "oauth", @@ -175,15 +182,17 @@ export async function runBasicTests(options: TestOptions) { test("updateSession", async () => { let dbSession = await db.session(session.sessionToken) - expect(dbSession.expires.valueOf()).not.toBe(ONE_MONTH_FROM_NOW.valueOf()) + const expires = options.fixtures?.sessionUpdateExpires ?? ONE_MONTH_FROM_NOW + + expect(dbSession.expires.valueOf()).not.toBe(expires.valueOf()) await adapter.updateSession({ sessionToken: session.sessionToken, - expires: ONE_MONTH_FROM_NOW, + expires, }) dbSession = await db.session(session.sessionToken) - expect(dbSession.expires.valueOf()).toBe(ONE_MONTH_FROM_NOW.valueOf()) + expect(dbSession.expires.valueOf()).toBe(expires.valueOf()) }) test("linkAccount", async () => { @@ -232,7 +241,7 @@ export async function runBasicTests(options: TestOptions) { const verificationToken = { token: hashedToken, identifier, - expires: FIFTEEN_MINUTES_FROM_NOW, + expires: options.fixtures?.verificationTokenExpires ?? FIFTEEN_MINUTES_FROM_NOW, } await adapter.createVerificationToken?.(verificationToken) @@ -251,7 +260,7 @@ export async function runBasicTests(options: TestOptions) { const verificationToken = { token: hashedToken, identifier, - expires: FIFTEEN_MINUTES_FROM_NOW, + expires: options.fixtures?.verificationTokenExpires ?? FIFTEEN_MINUTES_FROM_NOW, } await adapter.createVerificationToken?.(verificationToken) diff --git a/packages/adapter-test/jest/jest-preset.js b/packages/adapter-test/jest/jest-preset.js index 9e0663627e..1a8b8ac4a7 100644 --- a/packages/adapter-test/jest/jest-preset.js +++ b/packages/adapter-test/jest/jest-preset.js @@ -15,7 +15,7 @@ module.exports = { ".(js|jsx)$": ["@swc/jest", swcConfig], }, transformIgnorePatterns: ["[/\\\\]node_modules[/\\\\].+\\.(js|jsx)$"], - moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"], + moduleFileExtensions: ["mjs", "cjs", "ts", "tsx", "js", "jsx", "json", "node"], rootDir: ".", // coverageDirectory: "/coverage/", // collectCoverageFrom: ["/packages/*/src/**/*.{ts,tsx}"], diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ef8b558d36..1928f58d2e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -238,6 +238,33 @@ importers: ts-jest: 27.1.5_lvqy56smyn5gszh3zmisfmhukm undici: 5.22.1 + packages/adapter-drizzle: + specifiers: + '@auth/core': workspace:* + '@next-auth/adapter-test': workspace:* + '@next-auth/tsconfig': workspace:* + '@types/better-sqlite3': ^7.6.4 + '@types/uuid': ^8.3.3 + better-sqlite3: ^8.4.0 + drizzle-kit: ^0.19.5 + drizzle-orm: ^0.27.0 + jest: ^27.4.3 + mysql2: ^3.2.0 + postgres: ^3.3.4 + dependencies: + '@auth/core': link:../core + devDependencies: + '@next-auth/adapter-test': link:../adapter-test + '@next-auth/tsconfig': link:../tsconfig + '@types/better-sqlite3': 7.6.4 + '@types/uuid': 8.3.4 + better-sqlite3: 8.5.0 + drizzle-kit: 0.19.12 + drizzle-orm: 0.27.2_z532zzwrbmn5dxr2a76pmjzzqi + jest: 27.5.1 + mysql2: 3.6.0 + postgres: 3.3.5 + packages/adapter-dynamodb: specifiers: '@auth/core': workspace:* @@ -6091,7 +6118,7 @@ packages: peerDependencies: react: '*' dependencies: - '@types/react': 18.2.5 + '@types/react': 18.2.18 prop-types: 15.8.1 react: 18.2.0 dev: true @@ -6360,6 +6387,10 @@ packages: - webpack-cli dev: true + /@drizzle-team/studio/0.0.5: + resolution: {integrity: sha512-ps5qF0tMxWRVu+V5gvCRrQNqlY92aTnIKdq27gm9LZMSdaKYZt6AVvSK1dlUMzs6Rt0Jm80b+eWct6xShBKhIw==} + dev: true + /@edge-runtime/jest-environment/1.1.0-beta.35: resolution: {integrity: sha512-CBMGtry4W/BLtmWpyHcbOwY+nn96YOEUVUWhob1SPQURGsxGnFU5r2fxrd99TDy/oTujw5jAbK4syOyUbna4KQ==} dependencies: @@ -6408,6 +6439,20 @@ packages: jsdoc-type-pratt-parser: 3.1.0 dev: true + /@esbuild-kit/core-utils/3.1.0: + resolution: {integrity: sha512-Uuk8RpCg/7fdHSceR1M6XbSZFSuMrxcePFuGgyvsBn+u339dk5OeL4jv2EojwTN2st/unJGsVm4qHWjWNmJ/tw==} + dependencies: + esbuild: 0.17.19 + source-map-support: 0.5.21 + dev: true + + /@esbuild-kit/esm-loader/2.5.5: + resolution: {integrity: sha512-Qwfvj/qoPbClxCRNuac1Du01r9gvNOT+pMYtJDapfB1eoGN1YlJ1BixLyL9WVENRx5RXgNLdfYdx/CuswlGhMw==} + dependencies: + '@esbuild-kit/core-utils': 3.1.0 + get-tsconfig: 4.6.2 + dev: true + /@esbuild/android-arm/0.15.16: resolution: {integrity: sha512-nyB6CH++2mSgx3GbnrJsZSxzne5K0HMyNIWafDHqYy7IwxFc4fd/CgHVZXr8Eh+Q3KbIAcAe3vGyqIPhGblvMQ==} engines: {node: '>=12'} @@ -6426,6 +6471,24 @@ packages: dev: true optional: true + /@esbuild/android-arm/0.17.19: + resolution: {integrity: sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm/0.18.20: + resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + /@esbuild/android-arm64/0.16.4: resolution: {integrity: sha512-VPuTzXFm/m2fcGfN6CiwZTlLzxrKsWbPkG7ArRFpuxyaHUm/XFHQPD4xNwZT6uUmpIHhnSjcaCmcla8COzmZ5Q==} engines: {node: '>=12'} @@ -6435,6 +6498,24 @@ packages: dev: true optional: true + /@esbuild/android-arm64/0.17.19: + resolution: {integrity: sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm64/0.18.20: + resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + /@esbuild/android-x64/0.16.4: resolution: {integrity: sha512-MW+B2O++BkcOfMWmuHXB15/l1i7wXhJFqbJhp82IBOais8RBEQv2vQz/jHrDEHaY2X0QY7Wfw86SBL2PbVOr0g==} engines: {node: '>=12'} @@ -6444,6 +6525,24 @@ packages: dev: true optional: true + /@esbuild/android-x64/0.17.19: + resolution: {integrity: sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-x64/0.18.20: + resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + /@esbuild/darwin-arm64/0.16.4: resolution: {integrity: sha512-a28X1O//aOfxwJVZVs7ZfM8Tyih2Za4nKJrBwW5Wm4yKsnwBy9aiS/xwpxiiTRttw3EaTg4Srerhcm6z0bu9Wg==} engines: {node: '>=12'} @@ -6453,6 +6552,24 @@ packages: dev: true optional: true + /@esbuild/darwin-arm64/0.17.19: + resolution: {integrity: sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-arm64/0.18.20: + resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + /@esbuild/darwin-x64/0.16.4: resolution: {integrity: sha512-e3doCr6Ecfwd7VzlaQqEPrnbvvPjE9uoTpxG5pyLzr2rI2NMjDHmvY1E5EO81O/e9TUOLLkXA5m6T8lfjK9yAA==} engines: {node: '>=12'} @@ -6462,6 +6579,24 @@ packages: dev: true optional: true + /@esbuild/darwin-x64/0.17.19: + resolution: {integrity: sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-x64/0.18.20: + resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + /@esbuild/freebsd-arm64/0.16.4: resolution: {integrity: sha512-Oup3G/QxBgvvqnXWrBed7xxkFNwAwJVHZcklWyQt7YCAL5bfUkaa6FVWnR78rNQiM8MqqLiT6ZTZSdUFuVIg1w==} engines: {node: '>=12'} @@ -6471,6 +6606,24 @@ packages: dev: true optional: true + /@esbuild/freebsd-arm64/0.17.19: + resolution: {integrity: sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-arm64/0.18.20: + resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + /@esbuild/freebsd-x64/0.16.4: resolution: {integrity: sha512-vAP+eYOxlN/Bpo/TZmzEQapNS8W1njECrqkTpNgvXskkkJC2AwOXwZWai/Kc2vEFZUXQttx6UJbj9grqjD/+9Q==} engines: {node: '>=12'} @@ -6480,6 +6633,24 @@ packages: dev: true optional: true + /@esbuild/freebsd-x64/0.17.19: + resolution: {integrity: sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-x64/0.18.20: + resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-arm/0.16.4: resolution: {integrity: sha512-A47ZmtpIPyERxkSvIv+zLd6kNIOtJH03XA0Hy7jaceRDdQaQVGSDt4mZqpWqJYgDk9rg96aglbF6kCRvPGDSUA==} engines: {node: '>=12'} @@ -6489,6 +6660,24 @@ packages: dev: true optional: true + /@esbuild/linux-arm/0.17.19: + resolution: {integrity: sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm/0.18.20: + resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-arm64/0.16.4: resolution: {integrity: sha512-2zXoBhv4r5pZiyjBKrOdFP4CXOChxXiYD50LRUU+65DkdS5niPFHbboKZd/c81l0ezpw7AQnHeoCy5hFrzzs4g==} engines: {node: '>=12'} @@ -6498,6 +6687,24 @@ packages: dev: true optional: true + /@esbuild/linux-arm64/0.17.19: + resolution: {integrity: sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm64/0.18.20: + resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-ia32/0.16.4: resolution: {integrity: sha512-uxdSrpe9wFhz4yBwt2kl2TxS/NWEINYBUFIxQtaEVtglm1eECvsj1vEKI0KX2k2wCe17zDdQ3v+jVxfwVfvvjw==} engines: {node: '>=12'} @@ -6507,6 +6714,24 @@ packages: dev: true optional: true + /@esbuild/linux-ia32/0.17.19: + resolution: {integrity: sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ia32/0.18.20: + resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-loong64/0.14.54: resolution: {integrity: sha512-bZBrLAIX1kpWelV0XemxBZllyRmM6vgFQQG2GdNb+r3Fkp0FOh1NJSvekXDs7jq70k4euu1cryLMfU+mTXlEpw==} engines: {node: '>=12'} @@ -6534,6 +6759,24 @@ packages: dev: true optional: true + /@esbuild/linux-loong64/0.17.19: + resolution: {integrity: sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-loong64/0.18.20: + resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-mips64el/0.16.4: resolution: {integrity: sha512-sD9EEUoGtVhFjjsauWjflZklTNr57KdQ6xfloO4yH1u7vNQlOfAlhEzbyBKfgbJlW7rwXYBdl5/NcZ+Mg2XhQA==} engines: {node: '>=12'} @@ -6543,6 +6786,24 @@ packages: dev: true optional: true + /@esbuild/linux-mips64el/0.17.19: + resolution: {integrity: sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-mips64el/0.18.20: + resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-ppc64/0.16.4: resolution: {integrity: sha512-X1HSqHUX9D+d0l6/nIh4ZZJ94eQky8d8z6yxAptpZE3FxCWYWvTDd9X9ST84MGZEJx04VYUD/AGgciddwO0b8g==} engines: {node: '>=12'} @@ -6552,6 +6813,24 @@ packages: dev: true optional: true + /@esbuild/linux-ppc64/0.17.19: + resolution: {integrity: sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ppc64/0.18.20: + resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-riscv64/0.16.4: resolution: {integrity: sha512-97ANpzyNp0GTXCt6SRdIx1ngwncpkV/z453ZuxbnBROCJ5p/55UjhbaG23UdHj88fGWLKPFtMoU4CBacz4j9FA==} engines: {node: '>=12'} @@ -6561,6 +6840,24 @@ packages: dev: true optional: true + /@esbuild/linux-riscv64/0.17.19: + resolution: {integrity: sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-riscv64/0.18.20: + resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-s390x/0.16.4: resolution: {integrity: sha512-pUvPQLPmbEeJRPjP0DYTC1vjHyhrnCklQmCGYbipkep+oyfTn7GTBJXoPodR7ZS5upmEyc8lzAkn2o29wD786A==} engines: {node: '>=12'} @@ -6570,6 +6867,24 @@ packages: dev: true optional: true + /@esbuild/linux-s390x/0.17.19: + resolution: {integrity: sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-s390x/0.18.20: + resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-x64/0.16.4: resolution: {integrity: sha512-N55Q0mJs3Sl8+utPRPBrL6NLYZKBCLLx0bme/+RbjvMforTGGzFvsRl4xLTZMUBFC1poDzBEPTEu5nxizQ9Nlw==} engines: {node: '>=12'} @@ -6579,6 +6894,24 @@ packages: dev: true optional: true + /@esbuild/linux-x64/0.17.19: + resolution: {integrity: sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-x64/0.18.20: + resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/netbsd-x64/0.16.4: resolution: {integrity: sha512-LHSJLit8jCObEQNYkgsDYBh2JrJT53oJO2HVdkSYLa6+zuLJh0lAr06brXIkljrlI+N7NNW1IAXGn/6IZPi3YQ==} engines: {node: '>=12'} @@ -6588,6 +6921,24 @@ packages: dev: true optional: true + /@esbuild/netbsd-x64/0.17.19: + resolution: {integrity: sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/netbsd-x64/0.18.20: + resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + /@esbuild/openbsd-x64/0.16.4: resolution: {integrity: sha512-nLgdc6tWEhcCFg/WVFaUxHcPK3AP/bh+KEwKtl69Ay5IBqUwKDaq/6Xk0E+fh/FGjnLwqFSsarsbPHeKM8t8Sw==} engines: {node: '>=12'} @@ -6597,6 +6948,24 @@ packages: dev: true optional: true + /@esbuild/openbsd-x64/0.17.19: + resolution: {integrity: sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/openbsd-x64/0.18.20: + resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + /@esbuild/sunos-x64/0.16.4: resolution: {integrity: sha512-08SluG24GjPO3tXKk95/85n9kpyZtXCVwURR2i4myhrOfi3jspClV0xQQ0W0PYWHioJj+LejFMt41q+PG3mlAQ==} engines: {node: '>=12'} @@ -6606,6 +6975,24 @@ packages: dev: true optional: true + /@esbuild/sunos-x64/0.17.19: + resolution: {integrity: sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + + /@esbuild/sunos-x64/0.18.20: + resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + /@esbuild/win32-arm64/0.16.4: resolution: {integrity: sha512-yYiRDQcqLYQSvNQcBKN7XogbrSvBE45FEQdH8fuXPl7cngzkCvpsG2H9Uey39IjQ6gqqc+Q4VXYHsQcKW0OMjQ==} engines: {node: '>=12'} @@ -6615,6 +7002,24 @@ packages: dev: true optional: true + /@esbuild/win32-arm64/0.17.19: + resolution: {integrity: sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-arm64/0.18.20: + resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + /@esbuild/win32-ia32/0.16.4: resolution: {integrity: sha512-5rabnGIqexekYkh9zXG5waotq8mrdlRoBqAktjx2W3kb0zsI83mdCwrcAeKYirnUaTGztR5TxXcXmQrEzny83w==} engines: {node: '>=12'} @@ -6624,6 +7029,24 @@ packages: dev: true optional: true + /@esbuild/win32-ia32/0.17.19: + resolution: {integrity: sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-ia32/0.18.20: + resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + /@esbuild/win32-x64/0.16.4: resolution: {integrity: sha512-sN/I8FMPtmtT2Yw+Dly8Ur5vQ5a/RmC8hW7jO9PtPSQUPkowxWpcUZnqOggU7VwyT3Xkj6vcXWd3V/qTXwultQ==} engines: {node: '>=12'} @@ -6633,6 +7056,24 @@ packages: dev: true optional: true + /@esbuild/win32-x64/0.17.19: + resolution: {integrity: sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-x64/0.18.20: + resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + /@eslint/eslintrc/1.4.0: resolution: {integrity: sha512-7yfvXy6MWLgWSFsLhz5yH3iQ52St8cdUY6FoGieKkRDVxuxmrNuUetIuu6cmjNWwniUHiWXjxCr5tTXDrbYS5A==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -6872,7 +7313,7 @@ packages: engines: {node: ^8.13.0 || >=10.10.0} dependencies: '@grpc/proto-loader': 0.7.3 - '@types/node': 18.16.3 + '@types/node': 20.4.8 dev: true /@grpc/proto-loader/0.7.3: @@ -6938,7 +7379,7 @@ packages: engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: '@jest/types': 27.5.1 - '@types/node': 18.16.3 + '@types/node': 20.4.8 chalk: 4.1.2 jest-message-util: 27.5.1 jest-util: 27.5.1 @@ -6950,7 +7391,7 @@ packages: engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} dependencies: '@jest/types': 28.1.3 - '@types/node': 18.16.3 + '@types/node': 20.4.8 chalk: 4.1.2 jest-message-util: 28.1.1 jest-util: 28.1.3 @@ -6962,7 +7403,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.5.0 - '@types/node': 18.16.3 + '@types/node': 20.4.8 chalk: 4.1.2 jest-message-util: 29.2.1 jest-util: 29.2.1 @@ -6974,7 +7415,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.5.0 - '@types/node': 18.16.3 + '@types/node': 20.4.8 chalk: 4.1.2 jest-message-util: 29.3.1 jest-util: 29.3.1 @@ -6986,7 +7427,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.5.0 - '@types/node': 18.16.3 + '@types/node': 20.4.8 chalk: 4.1.2 jest-message-util: 29.5.0 jest-util: 29.5.0 @@ -7007,7 +7448,7 @@ packages: '@jest/test-result': 27.5.1 '@jest/transform': 27.5.1 '@jest/types': 27.5.1 - '@types/node': 18.16.3 + '@types/node': 20.4.8 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.8.1 @@ -7052,14 +7493,14 @@ packages: '@jest/test-result': 28.1.1 '@jest/transform': 28.1.1 '@jest/types': 28.1.1 - '@types/node': 18.16.3 + '@types/node': 20.4.8 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.7.0 exit: 0.1.2 graceful-fs: 4.2.10 jest-changed-files: 28.0.2 - jest-config: 28.1.1_@types+node@18.16.3 + jest-config: 28.1.1_@types+node@20.4.8 jest-haste-map: 28.1.1 jest-message-util: 28.1.1 jest-regex-util: 28.0.2 @@ -7095,14 +7536,14 @@ packages: '@jest/test-result': 29.2.1 '@jest/transform': 29.3.0 '@jest/types': 29.2.1 - '@types/node': 18.16.3 + '@types/node': 20.4.8 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.7.0 exit: 0.1.2 graceful-fs: 4.2.10 jest-changed-files: 29.2.0 - jest-config: 29.3.0_@types+node@18.16.3 + jest-config: 29.3.0_@types+node@20.4.8 jest-haste-map: 29.3.0 jest-message-util: 29.2.1 jest-regex-util: 29.2.0 @@ -7137,14 +7578,14 @@ packages: '@jest/test-result': 29.3.1 '@jest/transform': 29.3.1 '@jest/types': 29.3.1 - '@types/node': 18.16.3 + '@types/node': 20.4.8 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.7.0 exit: 0.1.2 graceful-fs: 4.2.10 jest-changed-files: 29.2.0 - jest-config: 29.3.1_@types+node@18.16.3 + jest-config: 29.3.1_@types+node@20.4.8 jest-haste-map: 29.3.1 jest-message-util: 29.3.1 jest-regex-util: 29.2.0 @@ -7179,14 +7620,14 @@ packages: '@jest/test-result': 29.5.0 '@jest/transform': 29.5.0 '@jest/types': 29.5.0 - '@types/node': 18.16.3 + '@types/node': 20.4.8 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.8.0 exit: 0.1.2 graceful-fs: 4.2.10 jest-changed-files: 29.5.0 - jest-config: 29.5.0_@types+node@18.16.3 + jest-config: 29.5.0_@types+node@20.4.8 jest-haste-map: 29.5.0 jest-message-util: 29.5.0 jest-regex-util: 29.4.3 @@ -7220,7 +7661,7 @@ packages: dependencies: '@jest/fake-timers': 27.5.1 '@jest/types': 27.5.1 - '@types/node': 18.16.3 + '@types/node': 20.4.8 jest-mock: 27.5.1 dev: true @@ -7230,7 +7671,7 @@ packages: dependencies: '@jest/fake-timers': 28.1.1 '@jest/types': 28.1.1 - '@types/node': 18.16.3 + '@types/node': 20.4.8 jest-mock: 28.1.1 dev: true @@ -7240,7 +7681,7 @@ packages: dependencies: '@jest/fake-timers': 28.1.3 '@jest/types': 28.1.3 - '@types/node': 18.16.3 + '@types/node': 20.4.8 jest-mock: 28.1.3 dev: true @@ -7250,7 +7691,7 @@ packages: dependencies: '@jest/fake-timers': 29.3.0 '@jest/types': 29.5.0 - '@types/node': 18.16.3 + '@types/node': 20.4.8 jest-mock: 29.3.0 dev: true @@ -7260,7 +7701,7 @@ packages: dependencies: '@jest/fake-timers': 29.3.1 '@jest/types': 29.5.0 - '@types/node': 18.16.3 + '@types/node': 20.4.8 jest-mock: 29.3.1 dev: true @@ -7270,7 +7711,7 @@ packages: dependencies: '@jest/fake-timers': 29.5.0 '@jest/types': 29.5.0 - '@types/node': 18.16.3 + '@types/node': 20.4.8 jest-mock: 29.5.0 dev: true @@ -7348,7 +7789,7 @@ packages: dependencies: '@jest/types': 27.5.1 '@sinonjs/fake-timers': 8.1.0 - '@types/node': 18.16.3 + '@types/node': 20.4.8 jest-message-util: 27.5.1 jest-mock: 27.5.1 jest-util: 27.5.1 @@ -7360,7 +7801,7 @@ packages: dependencies: '@jest/types': 28.1.1 '@sinonjs/fake-timers': 9.1.2 - '@types/node': 18.16.3 + '@types/node': 20.4.8 jest-message-util: 28.1.1 jest-mock: 28.1.1 jest-util: 28.1.1 @@ -7372,7 +7813,7 @@ packages: dependencies: '@jest/types': 28.1.3 '@sinonjs/fake-timers': 9.1.2 - '@types/node': 18.16.3 + '@types/node': 20.4.8 jest-message-util: 28.1.3 jest-mock: 28.1.3 jest-util: 28.1.3 @@ -7384,7 +7825,7 @@ packages: dependencies: '@jest/types': 29.5.0 '@sinonjs/fake-timers': 9.1.2 - '@types/node': 18.16.3 + '@types/node': 20.4.8 jest-message-util: 29.3.1 jest-mock: 29.3.0 jest-util: 29.3.1 @@ -7396,7 +7837,7 @@ packages: dependencies: '@jest/types': 29.5.0 '@sinonjs/fake-timers': 9.1.2 - '@types/node': 18.16.3 + '@types/node': 20.4.8 jest-message-util: 29.3.1 jest-mock: 29.3.1 jest-util: 29.3.1 @@ -7408,7 +7849,7 @@ packages: dependencies: '@jest/types': 29.5.0 '@sinonjs/fake-timers': 10.3.0 - '@types/node': 18.16.3 + '@types/node': 20.4.8 jest-message-util: 29.5.0 jest-mock: 29.5.0 jest-util: 29.5.0 @@ -7484,7 +7925,7 @@ packages: '@jest/test-result': 27.5.1 '@jest/transform': 27.5.1 '@jest/types': 27.5.1 - '@types/node': 18.16.3 + '@types/node': 20.4.8 chalk: 4.1.2 collect-v8-coverage: 1.0.1 exit: 0.1.2 @@ -7523,7 +7964,7 @@ packages: '@jest/transform': 28.1.1 '@jest/types': 28.1.3 '@jridgewell/trace-mapping': 0.3.17 - '@types/node': 18.16.3 + '@types/node': 20.4.8 chalk: 4.1.2 collect-v8-coverage: 1.0.1 exit: 0.1.2 @@ -7561,7 +8002,7 @@ packages: '@jest/transform': 29.3.0 '@jest/types': 29.5.0 '@jridgewell/trace-mapping': 0.3.17 - '@types/node': 18.16.3 + '@types/node': 20.4.8 chalk: 4.1.2 collect-v8-coverage: 1.0.1 exit: 0.1.2 @@ -7598,7 +8039,7 @@ packages: '@jest/transform': 29.3.1 '@jest/types': 29.5.0 '@jridgewell/trace-mapping': 0.3.17 - '@types/node': 18.16.3 + '@types/node': 20.4.8 chalk: 4.1.2 collect-v8-coverage: 1.0.1 exit: 0.1.2 @@ -7635,7 +8076,7 @@ packages: '@jest/transform': 29.5.0 '@jest/types': 29.5.0 '@jridgewell/trace-mapping': 0.3.17 - '@types/node': 18.16.3 + '@types/node': 20.4.8 chalk: 4.1.2 collect-v8-coverage: 1.0.1 exit: 0.1.2 @@ -7944,7 +8385,7 @@ packages: dependencies: '@types/istanbul-lib-coverage': 2.0.4 '@types/istanbul-reports': 3.0.1 - '@types/node': 18.16.3 + '@types/node': 20.4.8 '@types/yargs': 15.0.14 chalk: 4.1.2 dev: true @@ -7955,7 +8396,7 @@ packages: dependencies: '@types/istanbul-lib-coverage': 2.0.4 '@types/istanbul-reports': 3.0.1 - '@types/node': 18.16.3 + '@types/node': 20.4.8 '@types/yargs': 16.0.4 chalk: 4.1.2 dev: true @@ -7967,7 +8408,7 @@ packages: '@jest/schemas': 28.0.2 '@types/istanbul-lib-coverage': 2.0.4 '@types/istanbul-reports': 3.0.1 - '@types/node': 18.16.3 + '@types/node': 20.4.8 '@types/yargs': 17.0.10 chalk: 4.1.2 dev: true @@ -7979,7 +8420,7 @@ packages: '@jest/schemas': 28.1.3 '@types/istanbul-lib-coverage': 2.0.4 '@types/istanbul-reports': 3.0.1 - '@types/node': 18.16.3 + '@types/node': 20.4.8 '@types/yargs': 17.0.10 chalk: 4.1.2 dev: true @@ -7991,7 +8432,7 @@ packages: '@jest/schemas': 29.0.0 '@types/istanbul-lib-coverage': 2.0.4 '@types/istanbul-reports': 3.0.1 - '@types/node': 18.16.3 + '@types/node': 20.4.8 '@types/yargs': 17.0.10 chalk: 4.1.2 dev: true @@ -8003,7 +8444,7 @@ packages: '@jest/schemas': 29.0.0 '@types/istanbul-lib-coverage': 2.0.4 '@types/istanbul-reports': 3.0.1 - '@types/node': 18.16.3 + '@types/node': 20.4.8 '@types/yargs': 17.0.10 chalk: 4.1.2 dev: true @@ -8015,7 +8456,7 @@ packages: '@jest/schemas': 29.4.3 '@types/istanbul-lib-coverage': 2.0.4 '@types/istanbul-reports': 3.0.1 - '@types/node': 18.16.3 + '@types/node': 20.4.8 '@types/yargs': 17.0.10 chalk: 4.1.2 dev: true @@ -9363,17 +9804,23 @@ packages: '@babel/types': 7.20.7 dev: true + /@types/better-sqlite3/7.6.4: + resolution: {integrity: sha512-dzrRZCYPXIXfSR1/surNbJ/grU3scTaygS0OMzjlGf71i9sc2fGyHPXXiXmEvNIoE0cGwsanEFMVJxPXmco9Eg==} + dependencies: + '@types/node': 20.4.8 + dev: true + /@types/body-parser/1.19.2: resolution: {integrity: sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==} dependencies: '@types/connect': 3.4.35 - '@types/node': 18.16.3 + '@types/node': 20.4.8 dev: true /@types/bonjour/3.5.10: resolution: {integrity: sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw==} dependencies: - '@types/node': 18.16.3 + '@types/node': 20.4.8 dev: true /@types/chai-subset/1.3.3: @@ -9390,13 +9837,13 @@ packages: resolution: {integrity: sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw==} dependencies: '@types/express-serve-static-core': 4.17.31 - '@types/node': 18.16.3 + '@types/node': 20.4.8 dev: true /@types/connect/3.4.35: resolution: {integrity: sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==} dependencies: - '@types/node': 18.16.3 + '@types/node': 20.4.8 dev: true /@types/cookie/0.4.1: @@ -9420,7 +9867,7 @@ packages: /@types/duplexify/3.6.1: resolution: {integrity: sha512-n0zoEj/fMdMOvqbHxmqnza/kXyoGgJmEpsXjpP+gEqE1Ye4yNqc7xWipKnUoMpWhMuzJQSfK2gMrwlElly7OGQ==} dependencies: - '@types/node': 18.16.3 + '@types/node': 20.4.8 dev: true /@types/eslint-scope/3.7.3: @@ -9448,7 +9895,7 @@ packages: /@types/express-serve-static-core/4.17.31: resolution: {integrity: sha512-DxMhY+NAsTwMMFHBTtJFNp5qiHKJ7TeqOo23zVEM9alT1Ml27Q3xcTH0xwxn7Q0BbMcVEJOs/7aQtUWupUQN3Q==} dependencies: - '@types/node': 18.16.3 + '@types/node': 20.4.8 '@types/qs': 6.9.7 '@types/range-parser': 1.2.4 dev: true @@ -9465,20 +9912,20 @@ packages: /@types/fs-extra/8.1.2: resolution: {integrity: sha512-SvSrYXfWSc7R4eqnOzbQF4TZmfpNSM9FrSWLU3EUnWBuyZqNBOrv1B1JA3byUDPUl9z4Ab3jeZG2eDdySlgNMg==} dependencies: - '@types/node': 18.16.3 + '@types/node': 20.4.8 dev: true /@types/glob/7.2.0: resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==} dependencies: '@types/minimatch': 3.0.5 - '@types/node': 18.16.3 + '@types/node': 20.4.8 dev: true /@types/graceful-fs/4.1.5: resolution: {integrity: sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==} dependencies: - '@types/node': 18.16.3 + '@types/node': 20.4.8 dev: true /@types/hast/2.3.4: @@ -9498,7 +9945,7 @@ packages: /@types/http-proxy/1.17.9: resolution: {integrity: sha512-QsbSjA/fSk7xB+UXlCT3wHBy5ai9wOcNDWwZAtud+jXhwOM3l+EYZh8Lng4+/6n8uar0J7xILzqftJdJ/Wdfkw==} dependencies: - '@types/node': 18.16.3 + '@types/node': 20.4.8 dev: true /@types/istanbul-lib-coverage/2.0.4: @@ -9549,7 +9996,7 @@ packages: /@types/jsdom/16.2.14: resolution: {integrity: sha512-6BAy1xXEmMuHeAJ4Fv4yXKwBDTGTOseExKE3OaHiNycdHdZw59KfYzrt0DkDluvwmik1HRt6QS7bImxUmpSy+w==} dependencies: - '@types/node': 18.16.3 + '@types/node': 20.4.8 '@types/parse5': 6.0.3 '@types/tough-cookie': 4.0.2 dev: true @@ -9577,7 +10024,7 @@ packages: /@types/keyv/3.1.4: resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} dependencies: - '@types/node': 18.16.3 + '@types/node': 20.4.8 dev: true /@types/linkify-it/3.0.2: @@ -9654,6 +10101,10 @@ packages: resolution: {integrity: sha512-OPs5WnnT1xkCBiuQrZA4+YAV4HEJejmHneyraIaxsbev5yCEr6KMwINNFP9wQeFIw8FWcoTqF3vQsa5CDaI+8Q==} dev: true + /@types/node/20.4.8: + resolution: {integrity: sha512-0mHckf6D2DiIAzh8fM8f3HQCvMKDpK94YQ0DSVkfWTG9BZleYIWudw9cJxX8oCk9bM+vAkDyujDV6dmKHbvQpg==} + dev: true + /@types/nodemailer/6.4.4: resolution: {integrity: sha512-Ksw4t7iliXeYGvIQcSIgWQ5BLuC/mljIEbjf615svhZL10PE9t+ei8O9gDaD3FPCasUJn9KTLwz2JFJyiiyuqw==} dependencies: @@ -9843,7 +10294,7 @@ packages: /@types/react-dom/18.0.6: resolution: {integrity: sha512-/5OFZgfIPSwy+YuIBP/FgJnQnsxhZhjjrnxudMddeblOouIodEQ75X14Rr4wGSG/bknL+Omy9iWlLo1u/9GzAA==} dependencies: - '@types/react': 18.0.37 + '@types/react': 18.2.18 dev: true /@types/react-router-config/5.0.6: @@ -9866,7 +10317,7 @@ packages: resolution: {integrity: sha512-YYknwy0D0iOwKQgz9v8nOzt2J6l4gouBmDnWqUUznltOTaon+r8US8ky8HvN0tXvc38U9m6z/t2RsVsnd1zM0g==} dependencies: '@types/history': 4.7.11 - '@types/react': 18.2.5 + '@types/react': 18.2.18 dev: true /@types/react/18.0.37: @@ -9877,6 +10328,14 @@ packages: csstype: 3.1.0 dev: true + /@types/react/18.2.18: + resolution: {integrity: sha512-da4NTSeBv/P34xoZPhtcLkmZuJ+oYaCxHmyHzwaDQo9RQPBeXV+06gEk2FpqEcsX9XrnNLvRpVh6bdavDSjtiQ==} + dependencies: + '@types/prop-types': 15.7.5 + '@types/scheduler': 0.16.2 + csstype: 3.1.0 + dev: true + /@types/react/18.2.5: resolution: {integrity: sha512-RuoMedzJ5AOh23Dvws13LU9jpZHIc/k90AgmK7CecAYeWmSr3553L4u5rk4sWAPBuQosfT7HmTfG4Rg5o4nGEA==} dependencies: @@ -9888,7 +10347,7 @@ packages: /@types/responselike/1.0.0: resolution: {integrity: sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==} dependencies: - '@types/node': 18.16.3 + '@types/node': 20.4.8 dev: true /@types/retry/0.12.0: @@ -9898,13 +10357,13 @@ packages: /@types/sass/1.43.1: resolution: {integrity: sha512-BPdoIt1lfJ6B7rw35ncdwBZrAssjcwzI5LByIrYs+tpXlj/CAkuVdRsgZDdP4lq5EjyWzwxZCqAoFyHKFwp32g==} dependencies: - '@types/node': 18.16.3 + '@types/node': 20.4.8 dev: true /@types/sax/1.2.4: resolution: {integrity: sha512-pSAff4IAxJjfAXUG6tFkO7dsSbTmf8CtUpfhhZ5VhkRpC4628tJhh3+V6H1E+/Gs9piSzYKT5yzHO5M4GG9jkw==} dependencies: - '@types/node': 18.16.3 + '@types/node': 20.4.8 dev: true /@types/scheduler/0.16.2: @@ -9925,26 +10384,26 @@ packages: resolution: {integrity: sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==} dependencies: '@types/mime': 1.3.2 - '@types/node': 18.16.3 + '@types/node': 20.4.8 dev: true /@types/set-cookie-parser/2.4.2: resolution: {integrity: sha512-fBZgytwhYAUkj/jC/FAV4RQ5EerRup1YQsXQCh8rZfiHkc4UahC192oH0smGwsXol3cL3A5oETuAHeQHmhXM4w==} dependencies: - '@types/node': 18.16.3 + '@types/node': 20.4.8 dev: true /@types/shelljs/0.8.11: resolution: {integrity: sha512-x9yaMvEh5BEaZKeVQC4vp3l+QoFj3BXcd4aYfuKSzIIyihjdVARAadYy3SMNIz0WCCdS2vB9JL/U6GQk5PaxQw==} dependencies: '@types/glob': 7.2.0 - '@types/node': 18.16.3 + '@types/node': 20.4.8 dev: true /@types/sockjs/0.3.33: resolution: {integrity: sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw==} dependencies: - '@types/node': 18.16.3 + '@types/node': 20.4.8 dev: true /@types/stack-utils/2.0.1: @@ -9954,7 +10413,7 @@ packages: /@types/stoppable/1.1.1: resolution: {integrity: sha512-b8N+fCADRIYYrGZOcmOR8ZNBOqhktWTB/bMUl5LvGtT201QKJZOOH5UsFyI3qtteM6ZAJbJqZoBcLqqxKIwjhw==} dependencies: - '@types/node': 18.16.3 + '@types/node': 20.4.8 dev: true /@types/testing-library__jest-dom/5.14.5: @@ -9970,7 +10429,7 @@ packages: /@types/tunnel/0.0.3: resolution: {integrity: sha512-sOUTGn6h1SfQ+gbgqC364jLFBw2lnFqkgF3q0WovEHRLMrVD1sd5aufqi/aJObLekJO+Aq5z646U4Oxy6shXMA==} dependencies: - '@types/node': 18.16.3 + '@types/node': 20.4.8 dev: true /@types/unist/2.0.6: @@ -9991,14 +10450,14 @@ packages: /@types/whatwg-url/8.2.2: resolution: {integrity: sha512-FtQu10RWgn3D9U4aazdwIE2yzphmTJREDqNdODHrbrZmmMqI0vMheC/6NE/J1Yveaj8H+ela+YwWTjq5PGmuhA==} dependencies: - '@types/node': 18.16.3 + '@types/node': 20.4.8 '@types/webidl-conversions': 6.1.1 dev: true /@types/ws/8.5.3: resolution: {integrity: sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==} dependencies: - '@types/node': 18.16.3 + '@types/node': 20.4.8 dev: true /@types/yargs-parser/21.0.0: @@ -10184,7 +10643,7 @@ packages: debug: 4.3.4 globby: 11.1.0 is-glob: 4.0.3 - semver: 7.3.8 + semver: 7.5.1 tsutils: 3.21.0_typescript@4.9.4 typescript: 4.9.4 transitivePeerDependencies: @@ -10205,7 +10664,7 @@ packages: debug: 4.3.4 globby: 11.1.0 is-glob: 4.0.3 - semver: 7.3.8 + semver: 7.5.1 tsutils: 3.21.0 transitivePeerDependencies: - supports-color @@ -10225,7 +10684,7 @@ packages: debug: 4.3.4 globby: 11.1.0 is-glob: 4.0.3 - semver: 7.3.8 + semver: 7.5.1 tsutils: 3.21.0_typescript@4.9.4 typescript: 4.9.4 transitivePeerDependencies: @@ -10608,8 +11067,10 @@ packages: indent-string: 4.0.0 dev: true - /ajv-formats/2.1.1: + /ajv-formats/2.1.1_ajv@8.11.0: resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} + peerDependencies: + ajv: ^8.0.0 peerDependenciesMeta: ajv: optional: true @@ -11566,6 +12027,14 @@ packages: tweetnacl: 0.14.5 dev: true + /better-sqlite3/8.5.0: + resolution: {integrity: sha512-vbPcv/Hx5WYdyNg/NbcfyaBZyv9s/NVbxb7yCeC5Bq1pVocNxeL2tZmSu3Rlm4IEOTjYdGyzWQgyx0OSdORBzw==} + requiresBuild: true + dependencies: + bindings: 1.5.0 + prebuild-install: 7.1.1 + dev: true + /big-integer/1.6.51: resolution: {integrity: sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==} engines: {node: '>=0.6'} @@ -11595,6 +12064,12 @@ packages: chainsaw: 0.1.0 dev: true + /bindings/1.5.0: + resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + dependencies: + file-uri-to-path: 1.0.0 + dev: true + /bl/4.1.0: resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} dependencies: @@ -11894,7 +12369,7 @@ packages: fs-minipass: 2.1.0 glob: 8.1.0 infer-owner: 1.0.4 - lru-cache: 7.10.1 + lru-cache: 7.18.3 minipass: 3.3.3 minipass-collect: 1.0.2 minipass-flush: 1.0.5 @@ -11970,6 +12445,11 @@ packages: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} + /camelcase/7.0.1: + resolution: {integrity: sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==} + engines: {node: '>=14.16'} + dev: true + /camelize/1.0.0: resolution: {integrity: sha512-W2lPwkBkMZwFlPCXhIlYgxu+7gC/NUlCtdK652DAJ1JdgV0sTrvuPFshNPrFa1TY2JOkLhgdeEBplB4ezEa+xg==} dev: false @@ -12135,7 +12615,7 @@ packages: resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} engines: {node: '>= 8.10.0'} dependencies: - anymatch: 3.1.2 + anymatch: 3.1.3 braces: 3.0.2 glob-parent: 5.1.2 is-binary-path: 2.1.0 @@ -12210,6 +12690,17 @@ packages: engines: {node: '>=10'} dev: true + /cli-color/2.0.3: + resolution: {integrity: sha512-OkoZnxyC4ERN3zLzZaY9Emb7f/MhBOIpePv0Ycok0fJYT+Ouo00UBEIwsVsr0yoow++n5YWlSUgST9GKhNHiRQ==} + engines: {node: '>=0.10'} + dependencies: + d: 1.0.1 + es5-ext: 0.10.61 + es6-iterator: 2.0.3 + memoizee: 0.4.15 + timers-ext: 0.1.7 + dev: true + /cli-cursor/3.1.0: resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} engines: {node: '>=8'} @@ -12426,8 +12917,8 @@ packages: engines: {node: '>= 12'} dev: true - /commander/9.3.0: - resolution: {integrity: sha512-hv95iU5uXPbK83mjrJKuZyFM/LBAoCV/XhVGkS5Je6tl7sxr6A0ITMw5WoRV46/UaJ46Nllm3Xt7IaJhXTIkzw==} + /commander/9.5.0: + resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} engines: {node: ^12.20.0 || >=14} dev: true @@ -12800,7 +13291,7 @@ packages: postcss-modules-scope: 3.0.0_postcss@8.4.24 postcss-modules-values: 4.0.0_postcss@8.4.24 postcss-value-parser: 4.2.0 - semver: 7.3.8 + semver: 7.5.1 webpack: 5.75.0 dev: true @@ -13833,7 +14324,6 @@ packages: dependencies: mimic-response: 3.1.0 dev: true - optional: true /dedent-js/1.0.1: resolution: {integrity: sha512-OUepMozQULMLUmhxS95Vudo0jb0UchLimi3+pQ2plj61Fcy8axbP9hbiD4Sz6DPqn6XG3kfmziVfQ1rSys5AJQ==} @@ -13970,6 +14460,11 @@ packages: engines: {node: '>=0.10'} dev: true + /denque/2.1.0: + resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==} + engines: {node: '>=0.10'} + dev: true + /depd/1.1.2: resolution: {integrity: sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==} engines: {node: '>= 0.6'} @@ -14079,6 +14574,12 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dev: true + /difflib/0.2.4: + resolution: {integrity: sha512-9YVwmMb0wQHQNr5J9m6BSj6fk4pfGITGQOOs+D9Fl+INODWFOfvhIU1hNv6GgR1RBoC/9NJcwu77zShxV0kT7w==} + dependencies: + heap: 0.2.7 + dev: true + /dir-glob/3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} @@ -14266,6 +14767,101 @@ packages: resolution: {integrity: sha512-+BNfZ+deCo8hMNpDqDnvT+c0XpJ5cUa6mqYq89bho2Ifze4URTqRkcwR399hWoTrTkbZ/XJYDgP6rc7pRgffEQ==} dev: true + /dreamopt/0.8.0: + resolution: {integrity: sha512-vyJTp8+mC+G+5dfgsY+r3ckxlz+QMX40VjPQsZc5gxVAxLmi64TBoVkP54A/pRAXMXsbu2GMMBrZPxNv23waMg==} + engines: {node: '>=0.4.0'} + dependencies: + wordwrap: 1.0.0 + dev: true + + /drizzle-kit/0.19.12: + resolution: {integrity: sha512-rcsmh5gUIkvuD0WrbEc+aLpqY2q2J8ltynRcJiJo2l01hhsYvPnX0sgxWlFXlfAIa5ZXNw2nJZhYlslI6tG3MA==} + hasBin: true + dependencies: + '@drizzle-team/studio': 0.0.5 + '@esbuild-kit/esm-loader': 2.5.5 + camelcase: 7.0.1 + chalk: 5.2.0 + commander: 9.5.0 + esbuild: 0.18.20 + esbuild-register: 3.4.2_esbuild@0.18.20 + glob: 8.1.0 + hanji: 0.0.5 + json-diff: 0.9.0 + minimatch: 7.4.6 + zod: 3.21.4 + transitivePeerDependencies: + - supports-color + dev: true + + /drizzle-orm/0.27.2_z532zzwrbmn5dxr2a76pmjzzqi: + resolution: {integrity: sha512-ZvBvceff+JlgP7FxHKe0zOU9CkZ4RcOtibumIrqfYzDGuOeF0YUY0F9iMqYpRM7pxnLRfC+oO7rWOUH3T5oFQA==} + peerDependencies: + '@aws-sdk/client-rds-data': '>=3' + '@cloudflare/workers-types': '>=3' + '@libsql/client': '*' + '@neondatabase/serverless': '>=0.1' + '@opentelemetry/api': ^1.4.1 + '@planetscale/database': '>=1' + '@types/better-sqlite3': '*' + '@types/pg': '*' + '@types/sql.js': '*' + '@vercel/postgres': '*' + better-sqlite3: '>=7' + bun-types: '*' + knex: '*' + kysely: '*' + mysql2: '>=2' + pg: '>=8' + postgres: '>=3' + sql.js: '>=1' + sqlite3: '>=5' + peerDependenciesMeta: + '@aws-sdk/client-rds-data': + optional: true + '@cloudflare/workers-types': + optional: true + '@libsql/client': + optional: true + '@neondatabase/serverless': + optional: true + '@opentelemetry/api': + optional: true + '@planetscale/database': + optional: true + '@types/better-sqlite3': + optional: true + '@types/pg': + optional: true + '@types/sql.js': + optional: true + '@vercel/postgres': + optional: true + better-sqlite3: + optional: true + bun-types: + optional: true + knex: + optional: true + kysely: + optional: true + mysql2: + optional: true + pg: + optional: true + postgres: + optional: true + sql.js: + optional: true + sqlite3: + optional: true + dependencies: + '@types/better-sqlite3': 7.6.4 + better-sqlite3: 8.5.0 + mysql2: 3.6.0 + postgres: 3.3.5 + dev: true + /duplexer/0.1.2: resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} dev: true @@ -14564,6 +15160,15 @@ packages: d: 1.0.1 ext: 1.6.0 + /es6-weak-map/2.0.3: + resolution: {integrity: sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==} + dependencies: + d: 1.0.1 + es5-ext: 0.10.61 + es6-iterator: 2.0.3 + es6-symbol: 3.1.3 + dev: true + /esbuild-android-64/0.14.54: resolution: {integrity: sha512-Tz2++Aqqz0rJ7kYBfz+iqyE3QMycD4vk7LBRyWaAVFgFtQ/O8EJOnVmTOiDWYZ/uYzB4kvP+bqejYdVKzE5lAQ==} engines: {node: '>=12'} @@ -14867,6 +15472,17 @@ packages: - supports-color dev: true + /esbuild-register/3.4.2_esbuild@0.18.20: + resolution: {integrity: sha512-kG/XyTDyz6+YDuyfB9ZoSIOOmgyFCH+xPRtsCa8W85HLRV5Csp+o3jWVbOSHgSLfyLc5DmP+KFDNwty4mEjC+Q==} + peerDependencies: + esbuild: '>=0.12 <1' + dependencies: + debug: 4.3.4 + esbuild: 0.18.20 + transitivePeerDependencies: + - supports-color + dev: true + /esbuild-sunos-64/0.14.54: resolution: {integrity: sha512-28GZ24KmMSeKi5ueWzMcco6EBHStL3B6ubM7M51RmPwXQGLe0teBGJocmWhgwccA1GeFXqxzILIxXpHbl9Q/Kw==} engines: {node: '>=12'} @@ -15028,6 +15644,66 @@ packages: '@esbuild/win32-x64': 0.16.4 dev: true + /esbuild/0.17.19: + resolution: {integrity: sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + 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 + dev: true + + /esbuild/0.18.20: + resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + 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 + dev: true + /esbuild/0.8.57: resolution: {integrity: sha512-j02SFrUwFTRUqiY0Kjplwjm1psuzO1d6AjaXKuOR9hrY0HuPsT6sV42B6myW34h1q4CRy+Y3g4RU/cGJeI/nNA==} hasBin: true @@ -15490,10 +16166,17 @@ packages: resolution: {integrity: sha512-EzV94NYKoO09GLXGjXj9JIlXijVck4ONSr5wiCWDvhsvj5jxSrzTmRU/9C1DyB6uToszLs8aifA6NQ7lEQdvFw==} engines: {node: '>= 0.8'} dependencies: - '@types/node': 18.16.3 + '@types/node': 20.4.8 require-like: 0.1.2 dev: true + /event-emitter/0.3.5: + resolution: {integrity: sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==} + dependencies: + d: 1.0.1 + es5-ext: 0.10.61 + dev: true + /event-target-shim/5.0.1: resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} engines: {node: '>=6'} @@ -15555,7 +16238,7 @@ packages: dependencies: '@apidevtools/json-schema-ref-parser': 9.0.9 ajv: 8.11.0 - ajv-formats: 2.1.1 + ajv-formats: 2.1.1_ajv@8.11.0 body-parser: 1.20.1 content-type: 1.0.4 deep-freeze: 0.0.1 @@ -15569,7 +16252,7 @@ packages: pump: 3.0.0 qs: 6.11.0 raw-body: 2.5.1 - semver: 7.3.8 + semver: 7.5.1 transitivePeerDependencies: - supports-color dev: true @@ -15584,7 +16267,6 @@ packages: engines: {node: '>=6'} requiresBuild: true dev: true - optional: true /expand-tilde/1.2.2: resolution: {integrity: sha512-rtmc+cjLZqnu9dSYosX9EWmSJhTwpACgJQTfj4hgg2JjOD/6SIQalZrt4a3aQeh++oNxkazcaxrhPUj6+g5G/Q==} @@ -15920,6 +16602,10 @@ packages: webpack: 5.75.0 dev: true + /file-uri-to-path/1.0.0: + resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} + dev: true + /file-uri-to-path/2.0.0: resolution: {integrity: sha512-hjPFI8oE/2iQPVe4gbrJ73Pp+Xfub2+WI2LlXDbsaJBwT5wuMh35WNWVYYTpnz895shtwfyutMFLFywpQAFdLg==} engines: {node: '>= 6'} @@ -16465,6 +17151,12 @@ packages: - supports-color dev: true + /generate-function/2.3.1: + resolution: {integrity: sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==} + dependencies: + is-property: 1.0.2 + dev: true + /gensync/1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} @@ -16537,6 +17229,12 @@ packages: get-intrinsic: 1.1.3 dev: true + /get-tsconfig/4.6.2: + resolution: {integrity: sha512-E5XrT4CbbXcXWy+1jChlZmrmCwd5KGx502kDCXJJ7y898TtWW9FwoG5HfOLVRKmlmDGkWN2HM9Ho+/Y8F0sJDg==} + dependencies: + resolve-pkg-maps: 1.0.0 + dev: true + /get-uri/3.0.2: resolution: {integrity: sha512-+5s0SJbGoyiJTZZ2JTpFPLMPSch72KEqGOTvQsBqg0RBWvwhWUSYZFAtz3TPW0GXJuLBJPts1E241iHg+VRfhg==} engines: {node: '>= 6'} @@ -16576,7 +17274,6 @@ packages: resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} requiresBuild: true dev: true - optional: true /github-slugger/1.4.0: resolution: {integrity: sha512-w0dzqw/nt51xMVmlaV1+JRzN+oCa1KfcgGEWhxUG16wbdA+Xnt/yoFO8Z8x/V82ZcZ0wy6ln9QDup5avbhiDhQ==} @@ -16926,6 +17623,13 @@ packages: resolution: {integrity: sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==} dev: true + /hanji/0.0.5: + resolution: {integrity: sha512-Abxw1Lq+TnYiL4BueXqMau222fPSPMFtya8HdpWsz/xVAhifXou71mPh/kY2+08RgFcVccjG3uZHs6K5HAe3zw==} + dependencies: + lodash.throttle: 4.1.1 + sisteransi: 1.0.5 + dev: true + /har-schema/2.0.0: resolution: {integrity: sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==} engines: {node: '>=4'} @@ -17809,6 +18513,14 @@ packages: resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} dev: true + /is-promise/2.2.2: + resolution: {integrity: sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==} + dev: true + + /is-property/1.0.2: + resolution: {integrity: sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==} + dev: true + /is-regex/1.1.4: resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} engines: {node: '>= 0.4'} @@ -18082,7 +18794,7 @@ packages: '@jest/environment': 27.5.1 '@jest/test-result': 27.5.1 '@jest/types': 27.5.1 - '@types/node': 18.16.3 + '@types/node': 20.4.8 chalk: 4.1.2 co: 4.6.0 dedent: 0.7.0 @@ -18110,7 +18822,7 @@ packages: '@jest/expect': 28.1.1 '@jest/test-result': 28.1.1 '@jest/types': 28.1.3 - '@types/node': 18.16.3 + '@types/node': 20.4.8 chalk: 4.1.2 co: 4.6.0 dedent: 0.7.0 @@ -18137,7 +18849,7 @@ packages: '@jest/expect': 29.3.0 '@jest/test-result': 29.3.1 '@jest/types': 29.5.0 - '@types/node': 18.16.3 + '@types/node': 20.4.8 chalk: 4.1.2 co: 4.6.0 dedent: 0.7.0 @@ -18164,7 +18876,7 @@ packages: '@jest/expect': 29.3.1 '@jest/test-result': 29.3.1 '@jest/types': 29.5.0 - '@types/node': 18.16.3 + '@types/node': 20.4.8 chalk: 4.1.2 co: 4.6.0 dedent: 0.7.0 @@ -18191,7 +18903,7 @@ packages: '@jest/expect': 29.5.0 '@jest/test-result': 29.5.0 '@jest/types': 29.5.0 - '@types/node': 18.16.3 + '@types/node': 20.4.8 chalk: 4.1.2 co: 4.6.0 dedent: 0.7.0 @@ -18432,7 +19144,7 @@ packages: - supports-color dev: true - /jest-config/28.1.1_@types+node@18.16.3: + /jest-config/28.1.1_@types+node@20.4.8: resolution: {integrity: sha512-tASynMhS+jVV85zKvjfbJ8nUyJS/jUSYZ5KQxLUN2ZCvcQc/OmhQl2j6VEL3ezQkNofxn5pQ3SPYWPHb0unTZA==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} peerDependencies: @@ -18447,7 +19159,7 @@ packages: '@babel/core': 7.20.12 '@jest/test-sequencer': 28.1.1 '@jest/types': 28.1.3 - '@types/node': 18.16.3 + '@types/node': 20.4.8 babel-jest: 28.1.1_@babel+core@7.20.12 chalk: 4.1.2 ci-info: 3.8.0 @@ -18509,7 +19221,7 @@ packages: - supports-color dev: true - /jest-config/29.3.0_@types+node@18.16.3: + /jest-config/29.3.0_@types+node@20.4.8: resolution: {integrity: sha512-sTSDs/M+//njznsytxiBxwfDnSWRb6OqiNSlO/B2iw1HUaa1YLsdWmV4AWLXss1XKzv1F0yVK+kA4XOhZ0I1qQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: @@ -18524,7 +19236,7 @@ packages: '@babel/core': 7.20.12 '@jest/test-sequencer': 29.3.0 '@jest/types': 29.5.0 - '@types/node': 18.16.3 + '@types/node': 20.4.8 babel-jest: 29.3.0_@babel+core@7.20.12 chalk: 4.1.2 ci-info: 3.7.0 @@ -18586,7 +19298,7 @@ packages: - supports-color dev: true - /jest-config/29.3.1_@types+node@18.16.3: + /jest-config/29.3.1_@types+node@20.4.8: resolution: {integrity: sha512-y0tFHdj2WnTEhxmGUK1T7fgLen7YK4RtfvpLFBXfQkh2eMJAQq24Vx9472lvn5wg0MAO6B+iPfJfzdR9hJYalg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: @@ -18601,7 +19313,7 @@ packages: '@babel/core': 7.20.12 '@jest/test-sequencer': 29.3.1 '@jest/types': 29.5.0 - '@types/node': 18.16.3 + '@types/node': 20.4.8 babel-jest: 29.3.1_@babel+core@7.20.12 chalk: 4.1.2 ci-info: 3.7.0 @@ -18663,7 +19375,7 @@ packages: - supports-color dev: true - /jest-config/29.5.0_@types+node@18.16.3: + /jest-config/29.5.0_@types+node@20.4.8: resolution: {integrity: sha512-kvDUKBnNJPNBmFFOhDbm59iu1Fii1Q6SxyhXfvylq3UTHbg6o7j/g8k2dZyXWLvfdKB1vAPxNZnMgtKJcmu3kA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: @@ -18678,7 +19390,7 @@ packages: '@babel/core': 7.22.1 '@jest/test-sequencer': 29.5.0 '@jest/types': 29.5.0 - '@types/node': 18.16.3 + '@types/node': 20.4.8 babel-jest: 29.5.0_@babel+core@7.22.1 chalk: 4.1.2 ci-info: 3.8.0 @@ -18852,7 +19564,7 @@ packages: '@jest/environment': 27.5.1 '@jest/fake-timers': 27.5.1 '@jest/types': 27.5.1 - '@types/node': 18.16.3 + '@types/node': 20.4.8 jest-mock: 27.5.1 jest-util: 27.5.1 jsdom: 16.7.0 @@ -18889,7 +19601,7 @@ packages: '@jest/environment': 27.5.1 '@jest/fake-timers': 27.5.1 '@jest/types': 27.5.1 - '@types/node': 18.16.3 + '@types/node': 20.4.8 jest-mock: 27.5.1 jest-util: 27.5.1 dev: true @@ -18901,7 +19613,7 @@ packages: '@jest/environment': 28.1.1 '@jest/fake-timers': 28.1.1 '@jest/types': 28.1.3 - '@types/node': 18.16.3 + '@types/node': 20.4.8 jest-mock: 28.1.1 jest-util: 28.1.3 dev: true @@ -18913,7 +19625,7 @@ packages: '@jest/environment': 29.3.0 '@jest/fake-timers': 29.3.0 '@jest/types': 29.5.0 - '@types/node': 18.16.3 + '@types/node': 20.4.8 jest-mock: 29.3.0 jest-util: 29.3.1 dev: true @@ -18925,7 +19637,7 @@ packages: '@jest/environment': 29.3.1 '@jest/fake-timers': 29.3.1 '@jest/types': 29.5.0 - '@types/node': 18.16.3 + '@types/node': 20.4.8 jest-mock: 29.3.1 jest-util: 29.3.1 dev: true @@ -18937,7 +19649,7 @@ packages: '@jest/environment': 29.5.0 '@jest/fake-timers': 29.5.0 '@jest/types': 29.5.0 - '@types/node': 18.16.3 + '@types/node': 20.4.8 jest-mock: 29.5.0 jest-util: 29.5.0 dev: true @@ -18973,7 +19685,7 @@ packages: dependencies: '@jest/types': 27.5.1 '@types/graceful-fs': 4.1.5 - '@types/node': 18.16.3 + '@types/node': 20.4.8 anymatch: 3.1.2 fb-watchman: 2.0.1 graceful-fs: 4.2.10 @@ -18993,7 +19705,7 @@ packages: dependencies: '@jest/types': 28.1.3 '@types/graceful-fs': 4.1.5 - '@types/node': 18.16.3 + '@types/node': 20.4.8 anymatch: 3.1.2 fb-watchman: 2.0.1 graceful-fs: 4.2.10 @@ -19012,7 +19724,7 @@ packages: dependencies: '@jest/types': 29.5.0 '@types/graceful-fs': 4.1.5 - '@types/node': 18.16.3 + '@types/node': 20.4.8 anymatch: 3.1.2 fb-watchman: 2.0.1 graceful-fs: 4.2.10 @@ -19031,7 +19743,7 @@ packages: dependencies: '@jest/types': 29.5.0 '@types/graceful-fs': 4.1.5 - '@types/node': 18.16.3 + '@types/node': 20.4.8 anymatch: 3.1.2 fb-watchman: 2.0.1 graceful-fs: 4.2.10 @@ -19050,7 +19762,7 @@ packages: dependencies: '@jest/types': 29.5.0 '@types/graceful-fs': 4.1.5 - '@types/node': 18.16.3 + '@types/node': 20.4.8 anymatch: 3.1.3 fb-watchman: 2.0.1 graceful-fs: 4.2.10 @@ -19088,7 +19800,7 @@ packages: '@jest/source-map': 27.5.1 '@jest/test-result': 27.5.1 '@jest/types': 27.5.1 - '@types/node': 18.16.3 + '@types/node': 20.4.8 chalk: 4.1.2 co: 4.6.0 expect: 27.5.1 @@ -19290,7 +20002,7 @@ packages: engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: '@jest/types': 27.5.1 - '@types/node': 18.16.3 + '@types/node': 20.4.8 dev: true /jest-mock/28.1.1: @@ -19298,7 +20010,7 @@ packages: engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} dependencies: '@jest/types': 28.1.1 - '@types/node': 18.16.3 + '@types/node': 20.4.8 dev: true /jest-mock/28.1.3: @@ -19306,7 +20018,7 @@ packages: engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} dependencies: '@jest/types': 28.1.3 - '@types/node': 18.16.3 + '@types/node': 20.4.8 dev: true /jest-mock/29.3.0: @@ -19314,7 +20026,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.5.0 - '@types/node': 18.16.3 + '@types/node': 20.4.8 jest-util: 29.3.1 dev: true @@ -19323,7 +20035,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.5.0 - '@types/node': 18.16.3 + '@types/node': 20.4.8 jest-util: 29.3.1 dev: true @@ -19332,7 +20044,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.5.0 - '@types/node': 18.16.3 + '@types/node': 20.4.8 jest-util: 29.5.0 dev: true @@ -19552,7 +20264,7 @@ packages: '@jest/test-result': 27.5.1 '@jest/transform': 27.5.1 '@jest/types': 27.5.1 - '@types/node': 18.16.3 + '@types/node': 20.4.8 chalk: 4.1.2 emittery: 0.8.1 graceful-fs: 4.2.10 @@ -19584,7 +20296,7 @@ packages: '@jest/test-result': 28.1.1 '@jest/transform': 28.1.1 '@jest/types': 28.1.3 - '@types/node': 18.16.3 + '@types/node': 20.4.8 chalk: 4.1.2 emittery: 0.10.2 graceful-fs: 4.2.10 @@ -19613,7 +20325,7 @@ packages: '@jest/test-result': 29.2.1 '@jest/transform': 29.3.0 '@jest/types': 29.5.0 - '@types/node': 18.16.3 + '@types/node': 20.4.8 chalk: 4.1.2 emittery: 0.13.1 graceful-fs: 4.2.10 @@ -19642,7 +20354,7 @@ packages: '@jest/test-result': 29.3.1 '@jest/transform': 29.3.1 '@jest/types': 29.5.0 - '@types/node': 18.16.3 + '@types/node': 20.4.8 chalk: 4.1.2 emittery: 0.13.1 graceful-fs: 4.2.10 @@ -19671,7 +20383,7 @@ packages: '@jest/test-result': 29.5.0 '@jest/transform': 29.5.0 '@jest/types': 29.5.0 - '@types/node': 18.16.3 + '@types/node': 20.4.8 chalk: 4.1.2 emittery: 0.13.1 graceful-fs: 4.2.10 @@ -19762,7 +20474,7 @@ packages: '@jest/test-result': 29.2.1 '@jest/transform': 29.3.0 '@jest/types': 29.5.0 - '@types/node': 18.16.3 + '@types/node': 20.4.8 chalk: 4.1.2 cjs-module-lexer: 1.2.2 collect-v8-coverage: 1.0.1 @@ -19792,7 +20504,7 @@ packages: '@jest/test-result': 29.3.1 '@jest/transform': 29.3.1 '@jest/types': 29.5.0 - '@types/node': 18.16.3 + '@types/node': 20.4.8 chalk: 4.1.2 cjs-module-lexer: 1.2.2 collect-v8-coverage: 1.0.1 @@ -19822,7 +20534,7 @@ packages: '@jest/test-result': 29.5.0 '@jest/transform': 29.5.0 '@jest/types': 29.5.0 - '@types/node': 18.16.3 + '@types/node': 20.4.8 chalk: 4.1.2 cjs-module-lexer: 1.2.2 collect-v8-coverage: 1.0.1 @@ -19845,7 +20557,7 @@ packages: resolution: {integrity: sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: - '@types/node': 18.16.3 + '@types/node': 20.4.8 graceful-fs: 4.2.10 dev: true @@ -19874,7 +20586,7 @@ packages: jest-util: 27.5.1 natural-compare: 1.4.0 pretty-format: 27.5.1 - semver: 7.3.8 + semver: 7.5.1 transitivePeerDependencies: - supports-color dev: true @@ -19937,7 +20649,7 @@ packages: jest-util: 29.2.1 natural-compare: 1.4.0 pretty-format: 29.3.1 - semver: 7.3.8 + semver: 7.5.1 transitivePeerDependencies: - supports-color dev: true @@ -19969,7 +20681,7 @@ packages: jest-util: 29.3.1 natural-compare: 1.4.0 pretty-format: 29.3.1 - semver: 7.3.8 + semver: 7.5.1 transitivePeerDependencies: - supports-color dev: true @@ -20010,7 +20722,7 @@ packages: engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: '@jest/types': 27.5.1 - '@types/node': 18.16.3 + '@types/node': 20.4.8 chalk: 4.1.2 ci-info: 3.7.0 graceful-fs: 4.2.10 @@ -20022,7 +20734,7 @@ packages: engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} dependencies: '@jest/types': 28.1.1 - '@types/node': 18.16.3 + '@types/node': 20.4.8 chalk: 4.1.2 ci-info: 3.7.0 graceful-fs: 4.2.10 @@ -20034,7 +20746,7 @@ packages: engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} dependencies: '@jest/types': 28.1.3 - '@types/node': 18.16.3 + '@types/node': 20.4.8 chalk: 4.1.2 ci-info: 3.7.0 graceful-fs: 4.2.10 @@ -20046,7 +20758,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.5.0 - '@types/node': 18.16.3 + '@types/node': 20.4.8 chalk: 4.1.2 ci-info: 3.7.0 graceful-fs: 4.2.10 @@ -20058,7 +20770,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.5.0 - '@types/node': 18.16.3 + '@types/node': 20.4.8 chalk: 4.1.2 ci-info: 3.7.0 graceful-fs: 4.2.10 @@ -20070,7 +20782,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.5.0 - '@types/node': 18.16.3 + '@types/node': 20.4.8 chalk: 4.1.2 ci-info: 3.8.0 graceful-fs: 4.2.10 @@ -20159,7 +20871,7 @@ packages: dependencies: '@jest/test-result': 27.5.1 '@jest/types': 27.5.1 - '@types/node': 18.16.3 + '@types/node': 20.4.8 ansi-escapes: 4.3.2 chalk: 4.1.2 jest-util: 27.5.1 @@ -20172,7 +20884,7 @@ packages: dependencies: '@jest/test-result': 28.1.1 '@jest/types': 28.1.1 - '@types/node': 18.16.3 + '@types/node': 20.4.8 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.10.2 @@ -20186,7 +20898,7 @@ packages: dependencies: '@jest/test-result': 28.1.1 '@jest/types': 28.1.3 - '@types/node': 18.16.3 + '@types/node': 20.4.8 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.10.2 @@ -20200,7 +20912,7 @@ packages: dependencies: '@jest/test-result': 29.2.1 '@jest/types': 29.5.0 - '@types/node': 18.16.3 + '@types/node': 20.4.8 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 @@ -20214,7 +20926,7 @@ packages: dependencies: '@jest/test-result': 29.3.1 '@jest/types': 29.5.0 - '@types/node': 18.16.3 + '@types/node': 20.4.8 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 @@ -20228,7 +20940,7 @@ packages: dependencies: '@jest/test-result': 29.5.0 '@jest/types': 29.5.0 - '@types/node': 18.16.3 + '@types/node': 20.4.8 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 @@ -20240,7 +20952,7 @@ packages: resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} engines: {node: '>= 10.13.0'} dependencies: - '@types/node': 18.16.3 + '@types/node': 20.4.8 merge-stream: 2.0.0 supports-color: 8.1.1 dev: true @@ -20249,7 +20961,7 @@ packages: resolution: {integrity: sha512-Au7slXB08C6h+xbJPp7VIb6U0XX5Kc9uel/WFc6/rcTzGiaVCBRngBExSYuXSLFPULPSYU3cJ3ybS988lNFQhQ==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} dependencies: - '@types/node': 18.16.3 + '@types/node': 20.4.8 merge-stream: 2.0.0 supports-color: 8.1.1 dev: true @@ -20258,7 +20970,7 @@ packages: resolution: {integrity: sha512-lY4AnnmsEWeiXirAIA0c9SDPbuCBq8IYuDVL8PMm0MZ2PEs2yPvRA/J64QBXuZp7CYKrDM/rmNrc9/i3KJQncw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@types/node': 18.16.3 + '@types/node': 20.4.8 jest-util: 29.3.1 merge-stream: 2.0.0 supports-color: 8.1.1 @@ -20268,7 +20980,7 @@ packages: resolution: {integrity: sha512-NcrQnevGoSp4b5kg+akIpthoAFHxPBcb5P6mYPY0fUNT+sSvmtu6jlkEle3anczUKIKEbMxFimk9oTP/tpIPgA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@types/node': 18.16.3 + '@types/node': 20.4.8 jest-util: 29.5.0 merge-stream: 2.0.0 supports-color: 8.1.1 @@ -20600,6 +21312,15 @@ packages: resolution: {integrity: sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==} dev: true + /json-diff/0.9.0: + resolution: {integrity: sha512-cVnggDrVkAAA3OvFfHpFEhOnmcsUpleEKq4d4O8sQWWSH40MBrWstKigVB1kGrgLWzuom+7rRdaCsnBD6VyObQ==} + hasBin: true + dependencies: + cli-color: 2.0.3 + difflib: 0.2.4 + dreamopt: 0.8.0 + dev: true + /json-parse-even-better-errors/2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} dev: true @@ -20697,7 +21418,7 @@ packages: jws: 3.2.2 lodash: 4.17.21 ms: 2.1.3 - semver: 7.3.8 + semver: 7.5.1 dev: true /jsprim/1.4.2: @@ -20843,7 +21564,7 @@ packages: optional: true dependencies: colorette: 2.0.16 - commander: 9.3.0 + commander: 9.5.0 debug: 4.3.4 escalade: 3.1.1 esm: 3.2.25 @@ -21197,6 +21918,10 @@ packages: resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} dev: true + /lodash.throttle/4.1.1: + resolution: {integrity: sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==} + dev: true + /lodash.union/4.6.0: resolution: {integrity: sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==} dev: true @@ -21288,11 +22013,15 @@ packages: dependencies: yallist: 4.0.0 - /lru-cache/7.10.1: - resolution: {integrity: sha512-BQuhQxPuRl79J5zSXRP+uNzPOyZw2oFI9JLRQ80XswSvg21KMKNtQza9eF42rfI/3Z40RvzBdXgziEkudzjo8A==} + /lru-cache/7.18.3: + resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} engines: {node: '>=12'} dev: true - optional: true + + /lru-cache/8.0.5: + resolution: {integrity: sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA==} + engines: {node: '>=16.14'} + dev: true /lru-memoizer/2.1.4: resolution: {integrity: sha512-IXAq50s4qwrOBrXJklY+KhgZF+5y98PDaNo0gi/v2KQBFLyWr+JyFvijZXkGKjQj/h9c0OwoE+JZbwUXce76hQ==} @@ -21301,6 +22030,12 @@ packages: lru-cache: 4.0.2 dev: true + /lru-queue/0.1.0: + resolution: {integrity: sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==} + dependencies: + es5-ext: 0.10.61 + dev: true + /ltgt/2.2.1: resolution: {integrity: sha512-AI2r85+4MquTw9ZYqabu4nMwy9Oftlfa/e/52t9IjtfG+mGBbTNdAoZ3RQKLHR6r0wQnwZnPIEh/Ya6XTWAKNA==} dev: true @@ -21378,7 +22113,7 @@ packages: http-proxy-agent: 5.0.0 https-proxy-agent: 5.0.1 is-lambda: 1.0.1 - lru-cache: 7.10.1 + lru-cache: 7.18.3 minipass: 3.3.3 minipass-collect: 1.0.2 minipass-fetch: 2.1.0 @@ -21559,6 +22294,19 @@ packages: fs-monkey: 1.0.3 dev: true + /memoizee/0.4.15: + resolution: {integrity: sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==} + dependencies: + d: 1.0.1 + es5-ext: 0.10.61 + 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 + dev: true + /memory-pager/1.5.0: resolution: {integrity: sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==} dev: true @@ -21715,7 +22463,6 @@ packages: engines: {node: '>=10'} requiresBuild: true dev: true - optional: true /min-indent/1.0.1: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} @@ -21767,6 +22514,13 @@ packages: brace-expansion: 2.0.1 dev: true + /minimatch/7.4.6: + resolution: {integrity: sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==} + engines: {node: '>=10'} + dependencies: + brace-expansion: 2.0.1 + dev: true + /minimatch/9.0.0: resolution: {integrity: sha512-0jJj8AvgKqWN05mrwuqi8QYKx1WmYSUoKSxu5Qhs9prezTz10sxAHGNZe9J9cqIJzta8DWsleh2KaVaLl6Ru2w==} engines: {node: '>=16 || 14 >=14.17'} @@ -21881,7 +22635,6 @@ packages: resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} requiresBuild: true dev: true - optional: true /mkdirp/0.5.6: resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} @@ -22085,6 +22838,20 @@ packages: sqlstring: 2.3.1 dev: true + /mysql2/3.6.0: + resolution: {integrity: sha512-EWUGAhv6SphezurlfI2Fpt0uJEWLmirrtQR7SkbTHFC+4/mJBrPiSzHESHKAWKG7ALVD6xaG/NBjjd1DGJGQQQ==} + engines: {node: '>= 8.0'} + dependencies: + denque: 2.1.0 + generate-function: 2.3.1 + iconv-lite: 0.6.3 + long: 5.2.1 + lru-cache: 8.0.5 + named-placeholders: 1.1.3 + seq-queue: 0.0.5 + sqlstring: 2.3.3 + dev: true + /mz/2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} dependencies: @@ -22093,6 +22860,13 @@ packages: thenify-all: 1.6.0 dev: true + /named-placeholders/1.1.3: + resolution: {integrity: sha512-eLoBxg6wE/rZkJPhU/xRX1WTpkFEwDJEN96oxFrTsqBdbT5ec295Q+CoHrL9IT0DipqKhmGcaZmwOt8OON5x1w==} + engines: {node: '>=12.0.0'} + dependencies: + lru-cache: 7.18.3 + dev: true + /nan/2.16.0: resolution: {integrity: sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA==} dev: true @@ -22102,18 +22876,17 @@ packages: resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true + dev: true /nanoid/3.3.6: resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - dev: true /napi-build-utils/1.0.2: resolution: {integrity: sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==} requiresBuild: true dev: true - optional: true /napi-macros/2.0.0: resolution: {integrity: sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg==} @@ -22318,7 +23091,6 @@ packages: dependencies: semver: 7.5.1 dev: true - optional: true /node-abort-controller/2.0.0: resolution: {integrity: sha512-L8RfEgjBTHAISTuagw51PprVAqNZoG6KSB6LQ6H1bskMVkFs5E71IyjauLBv3XbuomJlguWF/VnRHdJ1gqiAqA==} @@ -23457,7 +24229,7 @@ packages: cosmiconfig: 7.0.1 klona: 2.0.5 postcss: 8.4.21 - semver: 7.3.8 + semver: 7.5.1 webpack: 5.75.0 dev: true @@ -24224,7 +24996,7 @@ packages: resolution: {integrity: sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==} engines: {node: ^10 || ^12 || >=14} dependencies: - nanoid: 3.3.4 + nanoid: 3.3.6 picocolors: 1.0.0 source-map-js: 1.0.2 @@ -24277,6 +25049,10 @@ packages: xtend: 4.0.2 dev: true + /postgres/3.3.5: + resolution: {integrity: sha512-+JD93VELV9gHkqpV5gdL5/70HdGtEw4/XE1S4BC8f1mcPmdib3K5XsKVbnR1XcAyC41zOnifJ+9YRKxdIsXiUw==} + dev: true + /pouchdb-abstract-mapreduce/8.0.1: resolution: {integrity: sha512-BxJRHdfiC8gID8h4DPS0Xy6wsa2VBHRHMv9hsm0BhGTWTqS4k8ivItVSeU2dMoXiTBYp+7SerYmovUQNGSX1GA==} dependencies: @@ -24511,7 +25287,6 @@ packages: tar-fs: 2.1.1 tunnel-agent: 0.6.0 dev: true - optional: true /prelude-ls/1.1.2: resolution: {integrity: sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==} @@ -24770,7 +25545,7 @@ packages: '@protobufjs/path': 1.1.2 '@protobufjs/pool': 1.1.0 '@protobufjs/utf8': 1.1.0 - '@types/node': 18.16.3 + '@types/node': 20.4.8 long: 5.2.1 dev: true @@ -25485,6 +26260,10 @@ packages: resolution: {integrity: sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==} dev: true + /resolve-pkg-maps/1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + dev: true + /resolve.exports/1.1.0: resolution: {integrity: sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==} engines: {node: '>=10'} @@ -25777,7 +26556,7 @@ packages: dependencies: '@types/json-schema': 7.0.11 ajv: 8.11.0 - ajv-formats: 2.1.1 + ajv-formats: 2.1.1_ajv@8.11.0 ajv-keywords: 5.1.0_ajv@8.11.0 dev: true @@ -25866,6 +26645,10 @@ packages: - supports-color dev: true + /seq-queue/0.0.5: + resolution: {integrity: sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q==} + dev: true + /sequelize-pool/7.1.0: resolution: {integrity: sha512-G9c0qlIWQSK29pR/5U2JF5dDQeqqHRragoyahj/Nx4KOOQ3CPPfzxnfqFPCSB7x5UgjOgnZ61nSxz+fjDpRlJg==} engines: {node: '>= 10.0.0'} @@ -26069,7 +26852,6 @@ packages: resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} requiresBuild: true dev: true - optional: true /simple-get/4.0.1: resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} @@ -26079,7 +26861,6 @@ packages: once: 1.4.0 simple-concat: 1.0.1 dev: true - optional: true /simple-swizzle/0.2.2: resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} @@ -26908,7 +27689,7 @@ packages: dependencies: basic-auth-connect: 1.0.0 chalk: 1.1.3 - commander: 9.3.0 + commander: 9.5.0 compare-semver: 1.1.0 compression: 1.7.4 connect: 3.7.0 @@ -27213,7 +27994,6 @@ packages: pump: 3.0.0 tar-stream: 2.2.0 dev: true - optional: true /tar-stream/2.2.0: resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} @@ -27451,6 +28231,13 @@ packages: engines: {node: '>=8'} dev: true + /timers-ext/0.1.7: + resolution: {integrity: sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==} + dependencies: + es5-ext: 0.10.61 + next-tick: 1.1.0 + dev: true + /tiny-glob/0.2.9: resolution: {integrity: sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==} dependencies: @@ -28397,7 +29184,7 @@ packages: is-yarn-global: 0.3.0 latest-version: 5.1.0 pupa: 2.1.1 - semver: 7.3.8 + semver: 7.5.1 semver-diff: 3.1.1 xdg-basedir: 4.0.0 dev: true @@ -29215,7 +30002,7 @@ packages: /wkx/0.5.0: resolution: {integrity: sha512-Xng/d4Ichh8uN4l0FToV/258EjMGU9MGcA0HV2d9B/ZpZB3lqQm7nkOdZdm5GhKtLLhAE7PiVQwN4eN+2YJJUg==} dependencies: - '@types/node': 18.16.3 + '@types/node': 20.4.8 dev: true /word-wrap/1.2.3: @@ -29223,6 +30010,10 @@ packages: engines: {node: '>=0.10.0'} dev: true + /wordwrap/1.0.0: + resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} + dev: true + /wrap-ansi/7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} @@ -29451,7 +30242,6 @@ packages: /zod/3.21.4: resolution: {integrity: sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw==} - dev: false /zwitch/1.0.5: resolution: {integrity: sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==}