From d47b56743e92f4d22eedb1a1a8d62ccf27c3132a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Tue, 8 Aug 2023 19:28:46 +0200 Subject: [PATCH] feat(adapters): Drizzle adapter (#8258) Co-authored-by: Anthony Shew --- .github/workflows/release.yml | 74 +- .gitignore | 5 +- docs/docs/reference/adapters/index.md | 8 +- docs/docusaurus.config.js | 1 + docs/sidebars.js | 1 + docs/static/img/adapters/drizzle-orm.png | Bin 0 -> 96717 bytes packages/adapter-drizzle/README.md | 28 + packages/adapter-drizzle/package.json | 65 + packages/adapter-drizzle/src/index.ts | 268 ++++ packages/adapter-drizzle/src/lib/mysql.ts | 255 ++++ packages/adapter-drizzle/src/lib/pg.ts | 225 ++++ packages/adapter-drizzle/src/lib/sqlite.ts | 203 +++ packages/adapter-drizzle/src/lib/utils.ts | 47 + packages/adapter-drizzle/tests/fixtures.ts | 43 + .../tests/mysql/drizzle.config.ts | 13 + .../adapter-drizzle/tests/mysql/index.test.ts | 71 ++ .../adapter-drizzle/tests/mysql/schema.ts | 29 + packages/adapter-drizzle/tests/mysql/test.sh | 22 + .../tests/pg/drizzle.config.ts | 13 + .../adapter-drizzle/tests/pg/index.test.ts | 65 + packages/adapter-drizzle/tests/pg/migrator.ts | 10 + packages/adapter-drizzle/tests/pg/schema.ts | 11 + packages/adapter-drizzle/tests/pg/test.sh | 25 + .../tests/sqlite/drizzle.config.ts | 10 + .../tests/sqlite/index.test.ts | 60 + .../adapter-drizzle/tests/sqlite/schema.ts | 20 + packages/adapter-drizzle/tests/sqlite/test.sh | 12 + packages/adapter-drizzle/tsconfig.json | 25 + packages/adapter-test/index.ts | 27 +- packages/adapter-test/jest/jest-preset.js | 2 +- pnpm-lock.yaml | 1114 ++++++++++++++--- 31 files changed, 2539 insertions(+), 213 deletions(-) create mode 100644 docs/static/img/adapters/drizzle-orm.png create mode 100644 packages/adapter-drizzle/README.md create mode 100644 packages/adapter-drizzle/package.json create mode 100644 packages/adapter-drizzle/src/index.ts create mode 100644 packages/adapter-drizzle/src/lib/mysql.ts create mode 100644 packages/adapter-drizzle/src/lib/pg.ts create mode 100644 packages/adapter-drizzle/src/lib/sqlite.ts create mode 100644 packages/adapter-drizzle/src/lib/utils.ts create mode 100644 packages/adapter-drizzle/tests/fixtures.ts create mode 100644 packages/adapter-drizzle/tests/mysql/drizzle.config.ts create mode 100644 packages/adapter-drizzle/tests/mysql/index.test.ts create mode 100644 packages/adapter-drizzle/tests/mysql/schema.ts create mode 100755 packages/adapter-drizzle/tests/mysql/test.sh create mode 100644 packages/adapter-drizzle/tests/pg/drizzle.config.ts create mode 100644 packages/adapter-drizzle/tests/pg/index.test.ts create mode 100644 packages/adapter-drizzle/tests/pg/migrator.ts create mode 100644 packages/adapter-drizzle/tests/pg/schema.ts create mode 100755 packages/adapter-drizzle/tests/pg/test.sh create mode 100644 packages/adapter-drizzle/tests/sqlite/drizzle.config.ts create mode 100644 packages/adapter-drizzle/tests/sqlite/index.test.ts create mode 100644 packages/adapter-drizzle/tests/sqlite/schema.ts create mode 100755 packages/adapter-drizzle/tests/sqlite/test.sh create mode 100644 packages/adapter-drizzle/tsconfig.json 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 0000000000000000000000000000000000000000..7626548943b220bbc096c5edcd34b9c2103ef102 GIT binary patch literal 96717 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,R=(UOj$PpO5=#od10&M|8dC|d* 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

OZDwiqGNuZz+N5 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 literal 0 HcmV?d00001 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==}