From df46a1eed6cc9280beee94fcb3d5a64103093629 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Chopin?= Date: Mon, 20 Oct 2025 21:21:22 +0200 Subject: [PATCH 01/22] feat: move to drizzle as first-class for hub database --- docs/content/blog/1.beta.md | 8 +- ...drawing-app-with-nuxt-and-cloudflare-r2.md | 2 +- docs/content/docs/2.features/database.md | 844 ++++++++---------- docs/content/docs/3.guides/2.drizzle.md | 256 ------ docs/content/index.yml | 2 +- docs/nuxt.config.ts | 3 +- docs/package.json | 5 +- package.json | 1 - playground/package.json | 12 +- playground/server/api/test.ts | 28 - playground/server/api/tests/db.ts | 28 +- playground/server/utils/drizzle.ts | 4 +- pnpm-lock.yaml | 481 ++++++++-- src/features.ts | 11 +- src/features/database.ts | 464 ++++------ src/module.ts | 13 +- .../api/_hub/database/query.post.dev.ts | 27 +- .../database/server/drizzle-utils/drizzle.ts | 1 - .../database/server/plugins/migrations.dev.ts | 20 +- src/runtime/database/server/utils/database.ts | 152 ---- .../server/utils/migrations/helpers.ts | 22 +- .../server/utils/migrations/migrations.ts | 31 +- src/types/database.ts | 50 +- src/types/module.ts | 59 +- src/utils/database.ts | 67 +- src/utils/devtools.ts | 57 +- 26 files changed, 1163 insertions(+), 1485 deletions(-) delete mode 100644 docs/content/docs/3.guides/2.drizzle.md delete mode 100644 src/runtime/database/server/drizzle-utils/drizzle.ts delete mode 100644 src/runtime/database/server/utils/database.ts diff --git a/docs/content/blog/1.beta.md b/docs/content/blog/1.beta.md index 70291b22..81c71c71 100644 --- a/docs/content/blog/1.beta.md +++ b/docs/content/blog/1.beta.md @@ -35,13 +35,13 @@ Let’s explain what the module and the admin are responsible for. **The NuxtHub module** allows you to access a SQL database, blob and KV storage (and more features) with zero configuration. In development, it generates a `.data/hub/wrangler.toml` file and uses [Cloudflare Proxy](https://developers.cloudflare.com/workers/wrangler/api/#getplatformproxy) to connect to the desired bindings: -- [`hubDatabase()`](/docs/features/database) -> [Cloudflare D1](https://www.cloudflare.com/developer-platform/d1/) -- [`hubKV()`](/docs/features/kv) -> [Cloudflare KV](https://www.cloudflare.com/developer-platform/workers-kv/) -- [`hubBlob()`](/docs/features/blob) -> [Cloudflare R2](https://www.cloudflare.com/developer-platform/r2/) +- [Database](/docs/features/database) with [Drizzle ORM](https://orm.drizzle.team) → [Cloudflare D1](https://www.cloudflare.com/developer-platform/d1/) +- [`hubKV()`](/docs/features/kv) → [Cloudflare KV](https://www.cloudflare.com/developer-platform/workers-kv/) +- [`hubBlob()`](/docs/features/blob) → [Cloudflare R2](https://www.cloudflare.com/developer-platform/r2/) In production, it reads from the bindings set in your Cloudflare dashboard following a specific naming convention: DB, BLOB, KV. -Note that `hubDatabase()`, `hubKV()` and `hubBlob()` server utils are a bit different than the binding itself to provide more features and a better developer experience when used in a Nuxt application. +Note that `hubKV()` and `hubBlob()` server utils are a bit different than the binding itself to provide more features and a better developer experience when used in a Nuxt application. ::callout{icon="i-lucide-rocket"} By leveraging bindings, you never have to add secret keys or tokens to your Nuxt application in order to access the database, KV or blob. The underlying secret is never exposed to your Nuxt server’s code, and therefore can’t be accidentally leaked. diff --git a/docs/content/blog/2.drawing-app-with-nuxt-and-cloudflare-r2.md b/docs/content/blog/2.drawing-app-with-nuxt-and-cloudflare-r2.md index fa489e33..b9db0c33 100644 --- a/docs/content/blog/2.drawing-app-with-nuxt-and-cloudflare-r2.md +++ b/docs/content/blog/2.drawing-app-with-nuxt-and-cloudflare-r2.md @@ -301,7 +301,7 @@ That's it! We have a minimal and fully functional drawing application. You may have noticed that the last drawing is displayed last, this is because Cloudflare R2 is using alphabetical order to list the files and we use the timestamp (using `Date.now()`) as the file name. Also, R2 doesn't support listing files with a custom order. -Even though it's easy to add a Cloudflare D1 database with [`hubDatabase()`](/docs/storage/database), I wanted to keep this example as simple as possible. +Even though it's easy to add a Cloudflare D1 database with [NuxtHub Database](/docs/features/database), I wanted to keep this example as simple as possible. Instead, I had the idea to use the timestamp in 2050 minus the timestamp of the drawing to get a descending order. It's not perfect but it works, until 2050, it's still a long time 😄. diff --git a/docs/content/docs/2.features/database.md b/docs/content/docs/2.features/database.md index 4ee5611f..08fae576 100644 --- a/docs/content/docs/2.features/database.md +++ b/docs/content/docs/2.features/database.md @@ -1,14 +1,18 @@ --- title: SQL Database navigation.title: Database -description: Access a SQL database in Nuxt to store and retrieve relational data. +description: Access a SQL database with Drizzle ORM in Nuxt to store and retrieve relational data with full type-safety. --- -NuxtHub Database supports PostgreSQL, MySQL and SQLite, and automatically configures [Nitro Database](https://nitro.build/guide/database), which is built on [db0](https://db0.unjs.io/). +NuxtHub Database provides a type-safe SQL database powered by [Drizzle ORM](https://orm.drizzle.team), supporting PostgreSQL, MySQL, and SQLite with automatic configuration and zero-config development setup. -## Getting Started +## Getting started -Enable the database in NuxtHub by setting the `database` property to your dialect in `hub` within your `nuxt.config.ts` file. +::steps{level="3"} + +### Set SQL dialect + +Enable the database in your `nuxt.config.ts` by setting the `database` property to your desired SQL dialect: ```ts [nuxt.config.ts] export default defineNuxtConfig({ @@ -18,532 +22,296 @@ export default defineNuxtConfig({ }) ``` -::tip -Checkout our [Drizzle ORM recipe](/docs/guides/drizzle) to get started with the database by providing a schema and migrations. -:: - -### Automatic Configuration - -When building the Nuxt app, NuxtHub automatically configures database connectors on many providers. - -::tabs - :::div{label="Vercel" icon="i-simple-icons-vercel"} - - When deploying to Vercel, Nitro Database `db` is configured for [PostgreSQL](https://www.postgresql.org/). - - ::tabs - ::::div{label="PostgreSQL" icon="i-simple-icons-postgresql"} +### Install dependencies - 1. Install the `pg` package - - :pm-install{name="pg"} - - 2. Add a PostgreSQL database to your project from the [Vercel dashboard](https://vercel.com/) -> Project -> Storage - - :::: - :: +Install Drizzle ORM, Drizzle Kit, and the appropriate driver(s): +::tabs{sync="database-dialect"} + :::tabs-item{label="PostgreSQL" icon="i-simple-icons-postgresql"} + :pm-install{name="drizzle-orm drizzle-kit pg @electric-sql/pglite"} ::: - - :::div{label="Cloudflare" icon="i-simple-icons-cloudflare"} - - When deploying to Cloudflare, Nitro Database `db` is configured based on your database dialect. - - ::tabs - ::::div{label="SQLite" icon="i-simple-icons-sqlite"} - - When using SQLite, the database is configured for [Cloudflare D1](https://developers.cloudflare.com/d1/). - - Add a `DB` binding to a [Cloudflare D1](https://developers.cloudflare.com/d1/) database in your `wrangler.jsonc` config. - - ```json [wrangler.jsonc] - { - "$schema": "node_modules/wrangler/config-schema.json", - // ... - "d1_databases": [ - { - "binding": "DB", - "database_name": "", - "database_id": "" - } - ] - } - ``` - - Learn more about adding bindings on [Cloudflare's documentation](https://developers.cloudflare.com/d1/get-started/#3-bind-your-worker-to-your-d1-database). - - :::: - - ::::div{label="PostgreSQL" icon="i-simple-icons-postgresql"} - - 1. Install the `pg` package - - :pm-install{name="pg"} - - ::note - Zero-config PostgreSQL via Hyperdrive support is not yet implemented for Cloudflare presets. - :: - - :::: - - ::::div{label="MySQL" icon="i-simple-icons-mysql"} - - 1. Install the `mysql2` package - - :pm-install{name="mysql2"} - - ::note - Zero-config MySQL via Hyperdrive support is not yet implemented for Cloudflare presets. - :: - - :::: - :: - + :::tabs-item{label="MySQL" icon="i-simple-icons-mysql"} + :pm-install{name="drizzle-orm drizzle-kit mysql2"} ::: - - :::div{label="Other" icon="i-simple-icons-nodedotjs"} - - When deploying to other providers, Nitro Database `db` is configured based on your database dialect. - - ::tabs - ::::div{label="PostgreSQL" icon="i-simple-icons-postgresql"} - - 1. Install the `pg` package - - :pm-install{name="pg"} - - 2. Set one of the following environment variables to configure your database connection: - - `POSTGRES_URL` - - `POSTGRESQL_URL` - - `DATABASE_URL` - - :::: - - ::::div{label="MySQL" icon="i-simple-icons-mysql"} - - 1. Install the `mysql2` package - - :pm-install{name="mysql2"} - - ::note - MySQL connector requires manual configuration in `nitro.database.db` within `nuxt.config.ts`. - :: - - :::: - - ::::div{label="SQLite" icon="i-simple-icons-sqlite"} - - 1. Install the `better-sqlite3` package - - :pm-install{name="better-sqlite3"} - - The database file will be stored at `.data/database/sqlite/db.sqlite3`. - - **Using Turso Cloud:** - - To use [Turso](https://turso.tech/) for SQLite during local development or production: - - 1. Install the `@libsql/client` package - - :pm-install{name="@libsql/client"} - - 2. Set the following environment variables: - - `TURSO_DATABASE_URL` - Your Turso database URL - - `TURSO_AUTH_TOKEN` - Your Turso authentication token - - NuxtHub will automatically detect these variables and configure the `libsql` connector. - - :::: - :: - - ::tip{to="#manual-configuration"} - You can manually configure the `db` within your Nitro Database configuration to use a different database connector. - :: - + :::tabs-item{label="SQLite" icon="i-simple-icons-sqlite"} + :pm-install{name="drizzle-orm drizzle-kit @libsql/client"} ::: :: -### Manual Configuration - -You can use any [db0](https://db0.unjs.io/connectors) connector by manually configuring the `db` within your [Nitro Database](https://nitro.build/guide/database) configuration. - -::note -Manually configuring the `db` in Nitro Database overrides automatic configuration. -:: - -```ts [nuxt.config.ts] -export default defineNuxtConfig({ - nitro: { - database: { - db: { - connector: 'postgresql', - options: { - url: 'postgresql://username:password@host:port/database' - /* any additional connector options */ - } - } - } - }, - - hub: { - database: true, - }, -}) -``` +NuxtHub automatically detects your database connection using environment variables: -::callout{to="https://db0.unjs.io/connectors"} -You can find the connector list on [db0 documentation](https://db0.unjs.io/connectors) with their configuration. +::tabs{sync="database-dialect"} + :::tabs-item{label="PostgreSQL" icon="i-simple-icons-postgresql" class="text-sm"} + - Uses `PGlite` (embedded PostgreSQL) if no environment variables are set. + - Uses `node-postgres` driver if you set `DATABASE_URL`, `POSTGRES_URL`, or `POSTGRESQL_URL` environment variable. + ::: + :::tabs-item{label="MySQL" icon="i-simple-icons-mysql" class="text-sm"} + - Uses `mysql2` driver if you set `DATABASE_URL` or `MYSQL_URL` environment variable. + - Requires environment variable (no local fallback) + ::: + :::tabs-item{label="SQLite" icon="i-simple-icons-sqlite" class="text-sm"} + - Uses `libsql` driver for [Turso](https://turso.tech) if you set `TURSO_DATABASE_URL` and `TURSO_AUTH_TOKEN` environment variables. + - Uses `libsql` locally with file at `.data/database/sqlite/db.sqlite` if no environment variables are set. + ::: :: -### Local Development - -During local development, NuxtHub automatically configures the database connector based on your configured dialect (from `hub.database` or inferred from your production `nitro.database.db` connector): - -::tabs - ::::div{label="SQLite" icon="i-simple-icons-sqlite"} - - **With Turso Cloud:** - - If `TURSO_DATABASE_URL` and `TURSO_AUTH_TOKEN` environment variables are provided, uses `libsql` connector to connect to your [Turso](https://turso.tech/) database - - Requires `@libsql/client` package: `npx nypm i @libsql/client` - - **Without environment variables:** - - Uses `better-sqlite3` connector with the database file stored at `.data/database/sqlite/db.sqlite3` - - Requires `better-sqlite3` package: `npx nypm i better-sqlite3` +### Database schema - :::: +Create your database schema with full TypeScript support using Drizzle ORM: - ::::div{label="PostgreSQL" icon="i-simple-icons-postgresql"} +::tabs{sync="database-dialect"} + :::tabs-item{label="PostgreSQL" icon="i-simple-icons-postgresql"} + ```ts [server/database/schema.ts] + import { pgTable, text, serial, timestamp } from 'drizzle-orm/pg-core' - **With environment variables set:** - - Uses `postgresql` connector if `POSTGRES_URL`, `POSTGRESQL_URL`, or `DATABASE_URL` environment variables are provided - - **Without environment variables:** - - Uses `pglite` connector (embedded PostgreSQL) with data stored at `.data/database/pglite/` - - :::: - - ::::div{label="MySQL" icon="i-simple-icons-mysql"} - - Requires manual configuration in `nitro.devDatabase.db` within your `nuxt.config.ts`. - - ```ts [nuxt.config.ts] - export default defineNuxtConfig({ - nitro: { - devDatabase: { - db: { - connector: 'mysql2', - options: { - host: 'localhost', - port: 3306, - user: 'root', - password: 'password', - database: 'mydb' - } - } - } - }, - hub: { - database: 'mysql' - } + export const users = pgTable('users', { + id: serial().primaryKey(), + name: text().notNull(), + email: text().notNull().unique(), + password: text().notNull(), + avatar: text().notNull(), + createdAt: timestamp().notNull().defaultNow(), }) ``` + ::: - ::note - Zero-config MySQL database setup during local development is not supported yet. - :: + :::tabs-item{label="SQLite" icon="i-simple-icons-sqlite"} + ```ts [server/database/schema.ts] + import { sqliteTable, text, integer } from 'drizzle-orm/sqlite-core' + + export const users = sqliteTable('users', { + id: integer().primaryKey({ autoIncrement: true }), + name: text().notNull(), + email: text().notNull().unique(), + password: text().notNull(), + avatar: text().notNull(), + createdAt: integer({ mode: 'timestamp' }).notNull(), + }) + ``` + ::: - :::: + :::tabs-item{label="MySQL" icon="i-simple-icons-mysql"} + ```ts [server/database/schema.ts] + import { mysqlTable, text, serial, timestamp } from 'drizzle-orm/mysql-core' + + export const users = mysqlTable('users', { + id: serial().primaryKey(), + name: text().notNull(), + email: text().notNull().unique(), + password: text().notNull(), + avatar: text().notNull(), + createdAt: timestamp().notNull().defaultNow(), + }) + ``` + ::: :: -You can override the automatic local development configuration by manually specifying a different database connector: - -::collapsible{name="manual local development database connector example"} -```ts [nuxt.config.ts] -export default defineNuxtConfig({ - nitro: { - devDatabase: { - db: { - connector: 'postgresql', - options: { - url: 'postgresql://username:password@localhost:5432/mydb' - } - } - } - }, -}) -``` +::callout{to="https://orm.drizzle.team/docs/sql-schema-declaration" external} +Learn more about [Drizzle ORM schema](https://orm.drizzle.team/docs/sql-schema-declaration) on the Drizzle documentation. :: -During local development, you can view and edit your database from Nuxt DevTools. +### `useDrizzle()` -:img{src="/images/landing/nuxt-devtools-database.png" alt="Nuxt DevTools Database" width="915" height="515"} +Create a server util to access your database with type-safety: -## `useDatabase()` +```ts [server/utils/drizzle.ts] +import * as schema from '../database/schema' -Server composable that returns a [db0](https://db0.unjs.io/) instance. +export { sql, eq, and, or } from 'drizzle-orm' -NuxtHub automatically configures Nitro Database. +export const tables = schema -Learn more about `useDatabase()` on the [Nitro documentation](https://nitro.build/guide/database#usage). +export function useDrizzle() { + return drizzle({ schema }) +} -```ts -const db = useDatabase('db') +export type User = typeof schema.users.$inferSelect ``` -::tip -Ensure that `'db'` is specified when using `useDatabase()` directly +::note +NuxtHub automatically configures the database connection and provides a pre-configured and auto-imported `drizzle()` function for you. :: -## `hubDatabase()` - -Server composable that returns a [Cloudflare D1](https://developers.cloudflare.com/d1/worker-api/d1-database/#methods) compatible database instance. - -```ts -const db = hubDatabase() -``` - -::important -We recommend new users to use [`useDatabase('db')`](#usedatabase) instead of `hubDatabase()` as `hubDatabase()` is deprecated and may be removed in the future. +::tip +Export also your schema as `tables` and Drizzle helpers like `sql`, `eq`, `and`, `or` to use them throughout your application without importing them manually. :: -### `prepare()` +### `drizzle.config.ts` -Generates a prepared statement to be used later. +Create a `drizzle.config.ts` file in your project root: -```ts -const stmt = db.prepare('SELECT * FROM users WHERE name = "Evan You"') -``` +::tabs{sync="database-dialect"} + :::tabs-item{label="PostgreSQL" icon="i-simple-icons-postgresql"} + ```ts [drizzle.config.ts] + import { defineConfig } from 'drizzle-kit' -::callout -Best practice is to use prepared statements which are precompiled objects used by the database to run the SQL. This is because prepared statements lead to overall faster execution and prevent SQL injection attacks. + export default defineConfig({ + dialect: 'postgresql', + schema: './server/database/schema.ts', + out: './server/database/migrations' + }) + ``` + ::: + :::tabs-item{label="MySQL" icon="i-simple-icons-mysql"} + ```ts [drizzle.config.ts] + import { defineConfig } from 'drizzle-kit' + + export default defineConfig({ + dialect: 'mysql', + schema: './server/database/schema.ts', + out: './server/database/migrations' + }) + ``` + ::: + :::tabs-item{label="SQLite" icon="i-simple-icons-sqlite"} + ```ts [drizzle.config.ts] + import { defineConfig } from 'drizzle-kit' + + export default defineConfig({ + dialect: 'sqlite', + schema: './server/database/schema.ts', + out: './server/database/migrations' + }) + ``` + ::: :: -### `bind()` - -Binds parameters to a prepared statement, allowing you to pass dynamic values to the query. - -```ts -const stmt = db.prepare('SELECT * FROM users WHERE name = ?1') - -stmt.bind('Evan You') - -// SELECT * FROM users WHERE name = 'Evan You' -``` - -The `?` character followed by a number (1-999) represents an ordered parameter. The number represents the position of the parameter when calling `.bind(...params)`. +### Add `db:generate` script -```ts -const stmt = db - .prepare('SELECT * FROM users WHERE name = ?2 AND age = ?1') - .bind(3, 'Leo Chopin') -// SELECT * FROM users WHERE name = 'Leo Chopin' AND age = 3 -``` - -If you instead use anonymous parameters (without a number), the values passed to `bind` will be assigned in order to the `?` placeholders in the query. - -It's recommended to use ordered parameters to improve maintainable and ensure that removing or reordering parameters will not break your queries. - -```ts -const stmt = db - .prepare('SELECT * FROM users WHERE name = ? AND age = ?') - .bind('Leo Chopin', 3) - -// SELECT * FROM users WHERE name = 'Leo Chopin' AND age = 3 -``` +Add a script to your `package.json`: -### `all()` - -Returns all rows as an array of objects, with each result row represented as an object on the results property (see [Return Object](#return-object)). - -```ts -const { results } = db.prepare('SELECT name, year FROM frameworks LIMIT 2').all() - -console.log(results) -/* -[ - { - name: "Laravel", - year: 2011, - }, - { - name: "Nuxt", - year: 2016, - } - ] -*/ -``` - -The method return an object that contains the results (if applicable), the success status and a meta object: - -```ts +```json [package.json] { - results: array | null, // [] if empty, or null if it does not apply - success: boolean, // true if the operation was successful, false otherwise - meta: { - duration: number, // duration of the operation in milliseconds - rows_read: number, // the number of rows read (scanned) by this query - rows_written: number // the number of rows written by this query + "scripts": { + "db:generate": "drizzle-kit generate" } } ``` -### `first()` - -Returns the first row of the results. This does not return metadata like the other methods. Instead, it returns the object directly. +### Generate migrations -```ts -const framework = db.prepare('SELECT * FROM frameworks WHERE year = ?1').bind(2016).first() +Generate migrations from your schema: -console.log(framework) -/* -{ - name: "Nuxt", - year: 2016, -} -*/ +```bash [Terminal] +npm run db:generate ``` -Get a specific column from the first row by passing the column name as a parameter: +This creates SQL migration files in `server/database/migrations/` which are automatically applied during deployment and development. -```ts -const total = db.prepare('SELECT COUNT(*) AS total FROM frameworks').first('total') -console.log(total) // 23 -``` +:: -### `raw()` +::tip{icon="i-lucide-rocket"} +That's it! You can now start your development server and your database will be automatically migrated. +:: -Returns results as an array of arrays, with each row represented by an array. The return type is an array of arrays, and does not include query metadata. +## Query Database -```ts -const rows = db.prepare('SELECT name, year FROM frameworks LIMIT 2').raw() -console.log(rows); - -/* -[ - [ "Laravel", 2011 ], - [ "Nuxt", 2016 ], -] -*/ -``` +Now that you have your database schema and migrations set up, you can start querying your database. -Column names are not included in the result set by default. To include column names as the first row of the result array, use `.raw({ columnNames: true })`. +### SQL Select -```ts -const rows = db.prepare('SELECT name, year FROM frameworks LIMIT 2').raw({ columnNames: true }) -console.log(rows); - -/* -[ - [ "name", "year" ], - [ "Laravel", 2011 ], - [ "Nuxt", 2016 ], -] -*/ +```ts [server/api/users.get.ts] +export default eventHandler(async (event) => { + const db = useDrizzle() + + return await db.select().from(tables.users) +}) ``` -### `run()` +::callout{to="https://orm.drizzle.team/docs/select" external} +Learn more about [Drizzle ORM select](https://orm.drizzle.team/docs/select) on the Drizzle documentation. +:: -Runs the query (or queries), but returns no results. Instead, `run()` returns the metrics only. Useful for write operations like UPDATE, DELETE or INSERT. +### SQL Insert -```ts -const result = db - .prepare('INSERT INTO frameworks (name, year) VALUES ("?1", ?2)') - .bind('Nitro', 2022) - .run() +```ts [server/api/users.post.ts] +export default eventHandler(async (event) => { + const { name, email } = await readBody(event) + const db = useDrizzle() -console.log(result) -/* -{ - success: true - meta: { - duration: 62, - } -} -*/ + return await db + .insert(tables.users) + .values({ + name, + email, + createdAt: new Date() + }) + .returning() +}) ``` -### `batch()` +::callout{to="https://orm.drizzle.team/docs/insert" external} +Learn more about [Drizzle ORM insert](https://orm.drizzle.team/docs/insert) on the Drizzle documentation. +:: -Sends multiple SQL statements inside a single call to the database. This can have a huge performance impact by reducing latency caused by multiple network round trips to the database. Each statement in the list will execute/commit sequentially and non-concurrently before returning the results in the same order. +### SQL Update -`batch` acts as a SQL transaction, meaning that if any statement fails, the entire transaction is aborted and rolled back. +```ts [server/api/users/[id\\].patch.ts] +export default eventHandler(async (event) => { + const { id } = getRouterParams(event) + const { name } = await readBody(event) + const db = useDrizzle() -```ts -const [info1, info2] = await db.batch([ - db.prepare('UPDATE frameworks SET version = ?1 WHERE name = ?2').bind(3, 'Nuxt'), - db.prepare('UPDATE authors SET age = ?1 WHERE username = ?2').bind(32, 'atinux'), -]) + return await db + .update(tables.users) + .set({ name }) + .where(eq(tables.users.id, Number(id))) + .returning() +}) ``` -`info1` and `info2` will contain the results of the first and second queries, similar to the results of the [`.all()`](#all) method (see [Return Object](#return-object)). +::callout{to="https://orm.drizzle.team/docs/update" external} +Learn more about [Drizzle ORM update](https://orm.drizzle.team/docs/update) on the Drizzle documentation. +:: -```ts -console.log(info1) -/* -{ - results: [], - success: true, - meta: { - duration: 62, - rows_read: 0, - rows_written: 1 +### SQL Delete + +```ts [server/api/users/[id\\].delete.ts] +export default eventHandler(async (event) => { + const { id } = getRouterParams(event) + const db = useDrizzle() + + const deletedUser = await db + .delete(tables.users) + .where(eq(tables.users.id, Number(id))) + .returning() + + if (!deletedUser) { + throw createError({ + statusCode: 404, + message: 'User not found' + }) } -} -*/ -``` - -The object returned is the same as the [`.all()`](#all) method. - -### `exec()` - -Executes one or more queries directly without prepared statements or parameters binding. The input can be one or multiple queries separated by \n. -If an error occurs, an exception is thrown with the query and error messages, execution stops, and further queries are not executed. - -```ts -const result = await hubDatabase().exec(`CREATE TABLE IF NOT EXISTS frameworks (id INTEGER PRIMARY KEY, name TEXT NOT NULL, year INTEGER NOT NULL DEFAULT 0)`) -console.log(result) -/* -{ - count: 1, - duration: 23 -} -*/ + return { deleted: true } +}) ``` -::callout -This method can have poorer performance (prepared statements can be reused in some cases) and, more importantly, is less safe. Only use this method for maintenance and one-shot tasks (for example, migration jobs). +::callout{to="https://orm.drizzle.team/docs/delete" external} +Learn more about [Drizzle ORM delete](https://orm.drizzle.team/docs/delete) on the Drizzle documentation. :: -## Using an ORM - -Instead of using `useDatabase('db')` to interact with your database directly using SQL, you can use an ORM like [Drizzle ORM](/docs/guides/drizzle). This can improve the developer experience by providing a type-safe API, migrations and more. - ## Database Migrations -Database migrations provide version control for your database schema. They track changes and ensure consistent schema evolution across all environments through incremental updates. NuxtHub supports SQL migration files (`.sql`). +Database migrations provide version control for your database schema. NuxtHub supports SQL migration files (`.sql`) and automatically applies them during development and deployment. Making them fully compatible with Drizzle Kit generated migrations. ### Migrations Directories -NuxtHub scans the `server/database/migrations` directory for migrations **for each [Nuxt layer](https://nuxt.com/docs/getting-started/layers)**. +NuxtHub scans `server/database/migrations` for migrations in each [Nuxt layer](https://nuxt.com/docs/getting-started/layers). -If you need to scan additional migrations directories, you can specify them in your `nuxt.config.ts` file. +To scan additional directories, specify them in your config: ```ts [nuxt.config.ts] export default defineNuxtConfig({ hub: { - // Array of additional migration directories to scan databaseMigrationsDirs: [ - 'my-module/db-migrations/' + 'server/database/custom-migrations/' ] } }) ``` -::note -NuxtHub will scan both `server/database/migrations` and `my-module/db-migrations` directories for `.sql` files. -:: -If you want more control to the migrations directories or you are working on a [Nuxt module](https://nuxt.com/docs/guide/going-further/modules), you can use the `hub:database:migrations:dirs` hook: +For more control (e.g., in Nuxt modules), use the `hub:database:migrations:dirs` hook: ::code-group ```ts [modules/auth/index.ts] @@ -557,7 +325,7 @@ export default defineNuxtModule({ const { resolve } = createResolver(import.meta.url) nuxt.hook('hub:database:migrations:dirs', (dirs) => { - dirs.push(resolve('db-migrations')) + dirs.push(resolve('./db-migrations')) }) } }) @@ -572,25 +340,20 @@ CREATE TABLE IF NOT EXISTS users ( :: ::tip -All migrations files are copied to the `.data/hub/database/migrations` directory when you run Nuxt. This consolidated view helps you track all migrations and enables you to use `npx nuxt hub database migrations ` commands. +All migration files are copied to `.data/hub/database/migrations` when you run Nuxt, giving you a consolidated view. :: ### Automatic Application -All `.sql` files in the database migrations directories are automatically applied when you: +Migrations are automatically applied when you: - Start the development server (`npx nuxi dev`) -- Build the application via CLI ([`npx nuxi build`](https://nuxt.com/docs/api/commands/build)) or during CI +- Build the application (`npx nuxi build`) -To apply migrations during CI with an automatically configured provider, ensure the connection string environment variable is set during build time. Alternatively, manually configure `db` [Nitro database](https://nitro.build/guide/database). -- PostgreSQL: `POSTGRESQL_URL` | `POSTGRESQL_URL` | `DATABASE_URL` - -::tip -All applied migrations are tracked in the `_hub_migrations` database table. -:: +Applied migrations are tracked in the `_hub_migrations` database table. ### Creating Migrations -Generate a new migration file using: +If you want to create migrations manually without using Drizzle Kit, you can use the following command: ```bash [Terminal] npx nuxt hub database migrations create @@ -600,14 +363,14 @@ npx nuxt hub database migrations create Migration names must only contain alphanumeric characters and `-` (spaces are converted to `-`). :: -Migration files are created in `server/database/migrations/` and are prefixed by an auto-incrementing sequence number. This migration number is used to determine the order in which migrations are run. +Example: ```bash [Example] > npx nuxthub database migrations create create-todos ✔ Created ./server/database/migrations/0001_create-todos.sql ``` -After creation, add your SQL queries to modify the database schema. For example, migrations should be used to create tables, add/delete/modify columns, and add/remove indexes. +Then add your SQL query to the migration file: ```sql [0001_create-todos.sql] -- Migration number: 0001 2025-01-30T17:17:37.252Z @@ -622,46 +385,16 @@ CREATE TABLE `todos` ( ``` ::note -You can create dialect-specific migrations by adding a `..sql` suffix to your migration files (e.g., `0001_create-todos.postgresql.sql` or `0001_create-todos.sqlite.sql`). This is useful when you need different SQL syntax for different database dialects. -:: - -::note{to="/docs/guides/drizzle#npm-run-dbgenerate"} -With [Drizzle ORM](/docs/guides/drizzle), migrations are automatically created when you run `npx drizzle-kit generate`. +Create dialect-specific migrations with `..sql` suffix (e.g., `0001_create-todos.postgresql.sql`). :: - - ### Post-Migration Queries ::important -This feature is for advanced use cases. As the queries are run after the migrations process (see [Automatic Application](#automatic-application)), you want to make sure your queries are idempotent. +Advanced use case: These queries run after migrations but aren't tracked in `_hub_migrations`. Ensure they're idempotent. :: -Sometimes you need to run additional queries after migrations are applied without tracking them in the migrations table. - -NuxtHub provides the `hub:database:queries:paths` hook for this purpose: +Use the `hub:database:queries:paths` hook to run additional queries after migrations: ::code-group ```ts [modules/admin/index.ts] @@ -675,7 +408,6 @@ export default defineNuxtModule({ const { resolve } = createResolver(import.meta.url) nuxt.hook('hub:database:queries:paths', (queries) => { - // Add SQL files to run after migrations queries.push(resolve('./db-queries/seed-admin.sql')) }) } @@ -686,15 +418,9 @@ INSERT OR IGNORE INTO admin_users (id, email, password) VALUES (1, 'admin@nuxt.c ``` :: -::note -These queries run after all migrations are applied but are not tracked in the `_hub_migrations` table. Use this for operations that should run when deploying your project. -:: - ### Foreign Key Constraints -If you are using Cloudflare D1 and using [Drizzle ORM](/docs/guides/drizzle) to generate your database migrations, your generated migration files will use `PRAGMA foreign_keys = ON | OFF;`, which is not supported by Cloudflare D1. Instead, they support [defer foreign key constraints](https://developers.cloudflare.com/d1/sql-api/foreign-keys/#defer-foreign-key-constraints). - -You need to update your migration file to use `PRAGMA defer_foreign_keys = on|off;` instead: +For Cloudflare D1 with Drizzle ORM migrations, replace: ```diff [Example] -PRAGMA foreign_keys = OFF; @@ -705,3 +431,133 @@ ALTER TABLE ... -PRAGMA foreign_keys = ON; +PRAGMA defer_foreign_keys = off; ``` + +::callout{to="https://developers.cloudflare.com/d1/sql-api/foreign-keys/#defer-foreign-key-constraints" external} +Learn more about [defer foreign key constraints](https://developers.cloudflare.com/d1/sql-api/foreign-keys/#defer-foreign-key-constraints) in Cloudflare D1. +:: + +## Database Seed + +You can populate your database with initial data using [Nitro Tasks](https://nitro.build/guide/tasks): + +::steps{level="3"} + +### Enable Nitro tasks + +```ts [nuxt.config.ts] +export default defineNuxtConfig({ + nitro: { + experimental: { + tasks: true + } + } +}) +``` + +### Create a seed task + +```ts [server/tasks/seed.ts] +export default defineTask({ + meta: { + name: 'db:seed', + description: 'Seed database with initial data' + }, + async run() { + console.log('Seeding database...') + + const users = [ + { + name: 'John Doe', + email: 'john@example.com', + password: 'hashed_password', + avatar: 'https://i.pravatar.cc/150?img=1', + createdAt: new Date() + }, + { + name: 'Jane Doe', + email: 'jane@example.com', + password: 'hashed_password', + avatar: 'https://i.pravatar.cc/150?img=2', + createdAt: new Date() + } + ] + + await useDrizzle().insert(tables.users).values(users) + + return { result: 'Database seeded successfully' } + } +}) +``` + +### Execute the task + +Open the `Tasks` tab in Nuxt DevTools and click on the `db:seed` task. + +:: + +## Local Development + +During local development, view and edit your database from [Nuxt DevTools](https://devtools.nuxt.com) using the [Drizzle Studio](https://orm.drizzle.team/drizzle-studio/overview): + +:img{src="/images/landing/nuxt-devtools-database.png" alt="Nuxt DevTools Database" width="915" height="515"} + +::warning +At the moment, Drizzle Studio does not support PGlite. +:: + +## Advanced configuration + +For advanced use cases, you can explicitly configure the database connection: + +```ts [nuxt.config.ts] +export default defineNuxtConfig({ + hub: { + database: { + dialect: 'postgresql', + driver: 'node-postgres', // Optional: explicitly choose driver + connection: { + connectionString: process.env.DATABASE_URL + } + } + } +}) +``` + +## Migration Guide + +::important +**Breaking Changes in NuxtHub v1:** If you're upgrading from a previous version that used `hubDatabase()`, follow this migration guide. +:: + +### Configuration Changes + +**Before:** +```diff [nuxt.config.ts] +export default defineNuxtConfig({ + hub: { +- database: true ++ database: 'sqlite' + } +}) +``` + +### API Changes + +The old `hubDatabase()` function has been removed. You must now use Drizzle ORM. + +**Before:** + +```ts +const db = hubDatabase() +const result = await db.prepare('SELECT * FROM users').all() +``` + +**After:** +```ts +const db = useDrizzle() +const result = await db.select().from(tables.users) +``` + +### Migration Files + +Your existing SQL migration files continue to work! No changes needed. diff --git a/docs/content/docs/3.guides/2.drizzle.md b/docs/content/docs/3.guides/2.drizzle.md deleted file mode 100644 index e4e49817..00000000 --- a/docs/content/docs/3.guides/2.drizzle.md +++ /dev/null @@ -1,256 +0,0 @@ ---- -title: Drizzle ORM -description: Learn how to setup Drizzle ORM with NuxtHub. ---- - -::callout{icon="i-simple-icons-drizzle" to="https://orm.drizzle.team" external} -Learn more about **Drizzle ORM**. -:: - -## Setup - -When Drizzle ORM is installed, NuxtHub provides a preconfigured Drizzle ORM client for your NuxtHub database. - -### Install Drizzle - -1. Install the `drizzle-orm` package to your project: - -:pm-install{name="drizzle-orm"} - -2. Install `drizzle-kit` development dependency to your project: - -:pm-install{name="drizzle-kit" dev=true} - -### `drizzle.config.ts` - -Add a `drizzle.config.ts` file to your project: - -```ts [drizzle.config.ts] -import { defineConfig } from 'drizzle-kit' - -export default defineConfig({ - dialect: 'postgresql', // or 'sqlite' or 'mysql' - schema: './server/database/schema.ts', - out: './server/database/migrations' -}) -``` - -### Database Schema - -::tabs - - :::div{label="PostgreSQL" icon="i-simple-icons-postgresql"} - ```ts [server/database/schema.ts] - import { pgTable, text, serial, timestamp } from 'drizzle-orm/pg-core' - - export const users = pgTable('users', { - id: serial().primaryKey(), - name: text().notNull(), - email: text().notNull().unique(), - password: text().notNull(), - avatar: text().notNull(), - createdAt: timestamp().notNull(), - }) - ``` - ::: - - :::div{label="SQLite" icon="i-simple-icons-sqlite"} - ```ts [server/database/schema.ts] - import { sqliteTable, text, integer } from 'drizzle-orm/sqlite-core' - - export const users = sqliteTable('users', { - id: integer().primaryKey({ autoIncrement: true }), - name: text().notNull(), - email: text().notNull().unique(), - password: text().notNull(), - avatar: text().notNull(), - createdAt: integer({ mode: 'timestamp' }).notNull(), - }) - ``` - ::: - - :::div{label="MySQL" icon="i-simple-icons-mysql"} - ```ts [server/database/schema.ts] - import { mysqlTable, text, serial, timestamp } from 'drizzle-orm/mysql-core' - - export const users = mysqlTable('users', { - id: serial().primaryKey(), - name: text().notNull(), - email: text().notNull().unique(), - password: text().notNull(), - avatar: text().notNull(), - createdAt: timestamp().notNull().defaultNow(), - }) - ``` - ::: -:: - -::note{to="https://orm.drizzle.team/docs/sql-schema-declaration#shape-your-data-schema"} -Learn more about the [Drizzle ORM schema](https://orm.drizzle.team/docs/sql-schema-declaration#shape-your-data-schema) on the Drizzle ORM documentation -:: - -### `useDrizzle()` - -Create a `useDrizzle()` server composable to interact with the database using your schema. - -```ts [server/utils/drizzle.ts] -export { sql, eq, and, or } from 'drizzle-orm' - -import * as schema from '../database/schema' - -export const tables = schema - -export function useDrizzle() { - return hubDrizzle({ schema }) -} - -export type User = typeof schema.users.$inferSelect -``` - -`hubDrizzle()` automatically uses the correct Drizzle ORM driver and provides the connection string based on the `db` Nitro Database configuration. - -We export the `tables` object and the `useDrizzle` function to be used in our API handlers without having to import them (Nuxt does it for us as long as it's exported from a `server/utils/` file). - -This allows you to conveniently reference your tables and interact directly with the [Drizzle API](https://orm.drizzle.team/docs/overview). - -::callout -Note that we are also exporting the `User` type, which is inferred from the `users` table. This is useful for type-checking the results of your queries. -:: - -::callout -We also export the `sql`, `eq`, `and`, and `or` functions from `drizzle-orm` to be used in our queries. -:: - -### `npm run db:generate` - -Let's add a `db:generate` script to the `package.json`: - -```json [package.json] -{ - "scripts": { - "db:generate": "drizzle-kit generate" - } -} -``` - -When running the `npm run db:generate` command, `drizzle-kit` will generate the migrations based on `server/database/schema.ts` and save them in the `server/database/migrations` directory. - -### Migrations - -Migrations created with `npm run db:generate` are automatically applied during deployment, preview and when starting the development server. - -::note{to="/docs/features/database#database-migrations"} -Learn more about migrations. -:: - -### Seed the database (Optional) - -You can add a server task to populate your database with initial data. This uses [Nitro Tasks](https://nitro.build/guide/tasks), which is currently an experimental feature. - -1. Update your nuxt.config.js: - -```ts [nuxt.config.ts] -export default defineNuxtConfig({ - nitro: { - experimental: { - tasks: true - } - } -}) -``` - -2. Create a new file containing the task: - -```ts [server/tasks/seed.ts] -export default defineTask({ - meta: { - name: 'db:seed', - description: 'Run database seed task' - }, - async run() { - console.log('Running DB seed task...') - const users = [ - { - name: 'John Doe', - email: 'john@example.com', - password: 'password123', - avatar: 'https://example.com/avatar/john.png', - createdAt: new Date() - }, - { - name: 'Jane Doe', - email: 'jane@example.com', - password: 'password123', - avatar: 'https://example.com/avatar/jane.png', - createdAt: new Date() - } - ] - useDrizzle().insert(tables.users).values(users) - return { result: 'success' } - } -}) -``` - -To run the seed task, start your dev server and open the Nuxt DevTools. Go to _Tasks_ and you will see the `db:seed` task ready to run. This will add the seed data to your database and give you the first users to work with. - -## Usage - -### Select - -```ts [server/api/todos/index.get.ts] -export default eventHandler(async () => { - const todos = useDrizzle().select().from(tables.todos).all() - - return todos -}) -``` - -### Insert - -```ts [server/api/todos/index.post.ts] -export default eventHandler(async (event) => { - const { title } = await readBody(event) - - const todo = useDrizzle().insert(tables.todos).values({ - title, - createdAt: new Date() - }).returning().get() - - return todo -}) -``` - -### Update - -```ts [server/api/todos/[id\\].patch.ts] -export default eventHandler(async (event) => { - const { id } = getRouterParams(event) - const { completed } = await readBody(event) - - const todo = useDrizzle().update(tables.todos).set({ - completed - }).where(eq(tables.todos.id, Number(id))).returning().get() - - return todo -}) -``` - -### Delete - -```ts [server/api/todos/[id\\].delete.ts] -export default eventHandler(async (event) => { - const { id } = getRouterParams(event) - - const deletedTodo = useDrizzle().delete(tables.todos).where(and( - eq(tables.todos.id, Number(id)) - )).returning().get() - - if (!deletedTodo) { - throw createError({ - statusCode: 404, - message: 'Todo not found' - }) - } - return deletedTodo -}) -``` diff --git a/docs/content/index.yml b/docs/content/index.yml index dc452fae..847446ac 100644 --- a/docs/content/index.yml +++ b/docs/content/index.yml @@ -175,7 +175,7 @@ sections: title: Database icon: i-lucide-database features: - - title: "hubDatabase() server helper" + - title: "Type-safe with Drizzle ORM" icon: i-lucide-square-function - title: "Database browser" icon: i-lucide-table diff --git a/docs/nuxt.config.ts b/docs/nuxt.config.ts index 0c70eba8..4ea57c20 100644 --- a/docs/nuxt.config.ts +++ b/docs/nuxt.config.ts @@ -62,7 +62,8 @@ export default defineNuxtConfig({ '/docs/server/logs': { redirect: { statusCode: 301, to: '/docs/getting-started/server-logs' } }, // Recipes '/docs/recipes/hooks': { redirect: { statusCode: 301, to: '/docs/guides/hooks' } }, - '/docs/recipes/drizzle': { redirect: { statusCode: 301, to: '/docs/guides/drizzle' } }, + '/docs/recipes/drizzle': { redirect: { statusCode: 301, to: '/docs/features/database' } }, + '/docs/guides/drizzle': { redirect: { statusCode: 301, to: '/docs/features/database' } }, '/docs/recipes/pre-rendering': { redirect: { statusCode: 301, to: '/docs/guides/pre-rendering' } } }, compatibilityDate: '2025-02-11', diff --git a/docs/package.json b/docs/package.json index 7faafdb7..aa9310c8 100644 --- a/docs/package.json +++ b/docs/package.json @@ -19,16 +19,15 @@ "@nuxt/content": "^3.7.1", "@nuxt/image": "^1.10.0", "@nuxt/scripts": "^0.12.1", - "@nuxt/ui": "4.0.1", + "@nuxt/ui": "^4.0.1", "@rollup/plugin-yaml": "^4.1.2", "@tsparticles/engine": "^3.8.1", "@tsparticles/slim": "^3.8.1", "@vueuse/core": "^13.1.0", "@vueuse/nuxt": "^13.1.0", - "better-sqlite3": "^12.4.1", "feed": "^5.1.0", "nuxt": "^4.1.3", "nuxt-llms": "^0.1.2", "nuxt-og-image": "^5.1.11" } -} \ No newline at end of file +} diff --git a/package.json b/package.json index 386bc9b4..fcfb2b09 100644 --- a/package.json +++ b/package.json @@ -109,7 +109,6 @@ "@parcel/watcher", "@tailwindcss/oxide", "@tsparticles/engine", - "better-sqlite3", "esbuild", "sharp", "unrs-resolver", diff --git a/playground/package.json b/playground/package.json index 3e65a01b..f1f7668e 100644 --- a/playground/package.json +++ b/playground/package.json @@ -9,22 +9,22 @@ "preview": "nuxi preview" }, "dependencies": { - "@ai-sdk/vue": "^2.0.68", + "@ai-sdk/vue": "^2.0.76", "@electric-sql/pglite": "^0.3.11", - "@iconify-json/simple-icons": "^1.2.54", + "@iconify-json/simple-icons": "^1.2.55", "@kgierke/nuxt-basic-auth": "^1.7.0", - "@nuxt/ui": "4.0.1", + "@libsql/client": "^0.15.15", + "@nuxt/ui": "^4.0.1", "@nuxthub/core": "workspace:*", "@nuxtjs/mdc": "^0.18.0", "@vueuse/core": "^13.9.0", "@vueuse/nuxt": "^13.9.0", - "ai": "^5.0.68", - "better-sqlite3": "^12.4.1", + "ai": "^5.0.76", "drizzle-orm": "^0.44.6", "nuxt": "^4.1.3", "nuxt-auth-utils": "^0.5.25", "pg": "^8.16.3", - "tailwindcss": "^4.1.14", + "tailwindcss": "^4.1.15", "workers-ai-provider": "^2.0.0", "zod": "^4.1.12" }, diff --git a/playground/server/api/test.ts b/playground/server/api/test.ts index 828e673d..2414f0e7 100644 --- a/playground/server/api/test.ts +++ b/playground/server/api/test.ts @@ -9,32 +9,4 @@ export default eventHandler(async () => { await kv.set('react:gatsby', { version: 2015 }) return kv.keys() - // const db = hubDatabase() - // return useProjectKV(projectUrl).getKeys() - // return await db.prepare('SELECT * from todos').all() - // return await db.prepare("SELECT * from todos").first() - // return await db.prepare('SELECT * from todos').raw() - // return await db.prepare("SELECT * from todos").run() - // return await db.exec('SELECT * from todos;') - - // const stmt = db.prepare('SELECT * from todos WHERE id = ?1') - // return { - // one: await stmt.bind(1).first(), - // three: await stmt.bind(3).first() - // } - - // return db.batch([ - // stmt.bind(1), - // stmt.bind(2) - // ]) - // return db.batch([ - // db.prepare('insert into todos (title, completed, created_at) values (?1, ?2, ?3)').bind('created', 0, Date.now()), - // db.prepare('update todos SET title = ?1 where id = ?2').bind('updated', 1), - // db.prepare('select * from todos where id = ?1').bind(1), - // ]) - - // return await db.exec('CREATE TABLE IF NOT EXISTS frameworks (id INTEGER PRIMARY KEY, name TEXT NOT NULL, year INTEGER NOT NULL DEFAULT 0)') - - // return useProjectDatabase(projectUrl).all(sql`SELECT * from todos``) - // return {} }) diff --git a/playground/server/api/tests/db.ts b/playground/server/api/tests/db.ts index 290e173f..b54ee592 100644 --- a/playground/server/api/tests/db.ts +++ b/playground/server/api/tests/db.ts @@ -1,23 +1,7 @@ -import { sqliteTable, integer, text } from 'drizzle-orm/sqlite-core' - export default defineEventHandler(async () => { - const db0 = useDatabase('db') - - - const _tables = await db0.sql` - SELECT - name, - type - FROM - sqlite_schema - WHERE - type = 'table' AND - name NOT LIKE 'sqlite_%' and name NOT LIKE '_litestream_%' and name NOT LIKE '__drizzle%' - ;` - const db = useDrizzle() - const drizzleTables = await db.all(sql` + const drizzleTables = await db.execute(sql` SELECT name, type @@ -29,18 +13,10 @@ export default defineEventHandler(async () => { ; `) - // const inserted = await db.insert(todos).values({ text: 'hello' }).returning().get() - // const todo = await db.select().from(todos).where(eq(todos.id, inserted.id)).get() - // const updated = await db.update(todos).set({ text: 'Bonjour' }).where(eq(todos.id, inserted.id)).returning() const all = await db.select().from(tables.todos).limit(3) - // const deleted = await db.delete(todos).where(eq(todos.id, all[0].id)) return { - drizzleTables, - // todo, - // inserted, - // updated, - // deleted, + drizzleTables: drizzleTables.rows || drizzleTables, all } }) diff --git a/playground/server/utils/drizzle.ts b/playground/server/utils/drizzle.ts index 5bdca7cd..4124aa2f 100644 --- a/playground/server/utils/drizzle.ts +++ b/playground/server/utils/drizzle.ts @@ -1,6 +1,6 @@ - import { sqliteTable, text, integer } from 'drizzle-orm/sqlite-core' // import { pgTable, text as pgText, boolean as pgBoolean, serial as pgSerial, timestamp as pgTimestamp } from 'drizzle-orm/pg-core' +import { drizzle } from '#hub/database' export { sql } from 'drizzle-orm' @@ -23,5 +23,5 @@ export const tables = { } export function useDrizzle() { - return hubDrizzle({ schema: tables }) + return drizzle({ schema: tables }) } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b46b3959..f1a08a9c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -34,7 +34,7 @@ importers: version: 3.4.2 db0: specifier: ^0.3.4 - version: 0.3.4(@electric-sql/pglite@0.3.11)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)) + version: 0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)) defu: specifier: ^6.1.4 version: 6.1.4 @@ -82,7 +82,7 @@ importers: version: 0.1.3 unstorage: specifier: ^1.17.1 - version: 1.17.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1) + version: 1.17.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1) zod: specifier: ^4.1.12 version: 4.1.12 @@ -122,7 +122,7 @@ importers: version: 9.37.0(jiti@2.6.1) nuxt: specifier: ^4.1.3 - version: 4.1.3(@electric-sql/pglite@0.3.11)(@parcel/watcher@2.5.1)(@types/node@24.7.2)(@vercel/blob@2.0.0)(@vue/compiler-sfc@3.5.22)(aws4fetch@1.0.20)(better-sqlite3@12.4.1)(db0@0.3.4(@electric-sql/pglite@0.3.11)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3))(eslint@9.37.0(jiti@2.6.1))(ioredis@5.8.1)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rolldown@1.0.0-beta.9)(rollup@4.50.0)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.1(typescript@5.9.3))(yaml@2.8.1) + version: 4.1.3(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@parcel/watcher@2.5.1)(@types/node@24.7.2)(@vercel/blob@2.0.0)(@vue/compiler-sfc@3.5.22)(aws4fetch@1.0.20)(better-sqlite3@12.4.1)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3))(eslint@9.37.0(jiti@2.6.1))(ioredis@5.8.1)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rolldown@1.0.0-beta.9)(rollup@4.50.0)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.1(typescript@5.9.3))(yaml@2.8.1) typescript: specifier: ~5.9.3 version: 5.9.3 @@ -158,16 +158,16 @@ importers: version: 1.2.31 '@nuxt/content': specifier: ^3.7.1 - version: 3.7.1(@electric-sql/pglite@0.3.11)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3))(magicast@0.3.5)(valibot@1.1.0(typescript@5.9.3)) + version: 3.7.1(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3))(magicast@0.3.5)(valibot@1.1.0(typescript@5.9.3)) '@nuxt/image': specifier: ^1.10.0 - version: 1.11.0(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1)(magicast@0.3.5) + version: 1.11.0(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1)(magicast@0.3.5) '@nuxt/scripts': specifier: ^0.12.1 - version: 0.12.1(@googlemaps/markerclusterer@2.6.2)(@unhead/vue@2.0.19(vue@3.5.22(typescript@5.9.3)))(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1)(magicast@0.3.5)(typescript@5.9.3)(vue@3.5.22(typescript@5.9.3)) + version: 0.12.1(@googlemaps/markerclusterer@2.6.2)(@unhead/vue@2.0.19(vue@3.5.22(typescript@5.9.3)))(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1)(magicast@0.3.5)(typescript@5.9.3)(vue@3.5.22(typescript@5.9.3)) '@nuxt/ui': - specifier: 4.0.1 - version: 4.0.1(@babel/parser@7.28.4)(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(change-case@5.4.4)(db0@0.3.4(@electric-sql/pglite@0.3.11)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(embla-carousel@8.6.0)(ioredis@5.8.1)(magicast@0.3.5)(react@19.1.1)(typescript@5.9.3)(valibot@1.1.0(typescript@5.9.3))(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-router@4.5.1(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3))(zod@3.25.76) + specifier: ^4.0.1 + version: 4.0.1(@babel/parser@7.28.4)(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(change-case@5.4.4)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(embla-carousel@8.6.0)(ioredis@5.8.1)(magicast@0.3.5)(react@19.1.1)(typescript@5.9.3)(valibot@1.1.0(typescript@5.9.3))(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-router@4.5.1(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3))(zod@3.25.76) '@rollup/plugin-yaml': specifier: ^4.1.2 version: 4.1.2(rollup@4.52.4) @@ -182,40 +182,40 @@ importers: version: 13.9.0(vue@3.5.22(typescript@5.9.3)) '@vueuse/nuxt': specifier: ^13.1.0 - version: 13.9.0(magicast@0.3.5)(nuxt@4.1.3(@electric-sql/pglite@0.3.11)(@parcel/watcher@2.5.1)(@types/node@24.7.2)(@vercel/blob@2.0.0)(@vue/compiler-sfc@3.5.22)(aws4fetch@1.0.20)(better-sqlite3@12.4.1)(db0@0.3.4(@electric-sql/pglite@0.3.11)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3))(eslint@9.37.0(jiti@2.6.1))(ioredis@5.8.1)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rolldown@1.0.0-beta.9)(rollup@4.52.4)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.1(typescript@5.9.3))(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)) - better-sqlite3: - specifier: ^12.4.1 - version: 12.4.1 + version: 13.9.0(magicast@0.3.5)(nuxt@4.1.3(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@parcel/watcher@2.5.1)(@types/node@24.7.2)(@vercel/blob@2.0.0)(@vue/compiler-sfc@3.5.22)(aws4fetch@1.0.20)(better-sqlite3@12.4.1)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3))(eslint@9.37.0(jiti@2.6.1))(ioredis@5.8.1)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rolldown@1.0.0-beta.9)(rollup@4.52.4)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.1(typescript@5.9.3))(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)) feed: specifier: ^5.1.0 version: 5.1.0 nuxt: specifier: ^4.1.3 - version: 4.1.3(@electric-sql/pglite@0.3.11)(@parcel/watcher@2.5.1)(@types/node@24.7.2)(@vercel/blob@2.0.0)(@vue/compiler-sfc@3.5.22)(aws4fetch@1.0.20)(better-sqlite3@12.4.1)(db0@0.3.4(@electric-sql/pglite@0.3.11)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3))(eslint@9.37.0(jiti@2.6.1))(ioredis@5.8.1)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rolldown@1.0.0-beta.9)(rollup@4.52.4)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.1(typescript@5.9.3))(yaml@2.8.1) + version: 4.1.3(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@parcel/watcher@2.5.1)(@types/node@24.7.2)(@vercel/blob@2.0.0)(@vue/compiler-sfc@3.5.22)(aws4fetch@1.0.20)(better-sqlite3@12.4.1)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3))(eslint@9.37.0(jiti@2.6.1))(ioredis@5.8.1)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rolldown@1.0.0-beta.9)(rollup@4.52.4)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.1(typescript@5.9.3))(yaml@2.8.1) nuxt-llms: specifier: ^0.1.2 version: 0.1.3(magicast@0.3.5) nuxt-og-image: specifier: ^5.1.11 - version: 5.1.11(@unhead/vue@2.0.19(vue@3.5.22(typescript@5.9.3)))(h3@1.15.4)(magicast@0.3.5)(unstorage@1.17.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1))(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)) + version: 5.1.11(@unhead/vue@2.0.19(vue@3.5.22(typescript@5.9.3)))(h3@1.15.4)(magicast@0.3.5)(unstorage@1.17.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1))(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)) playground: dependencies: '@ai-sdk/vue': - specifier: ^2.0.68 - version: 2.0.68(vue@3.5.22(typescript@5.9.3))(zod@4.1.12) + specifier: ^2.0.76 + version: 2.0.76(vue@3.5.22(typescript@5.9.3))(zod@4.1.12) '@electric-sql/pglite': specifier: ^0.3.11 version: 0.3.11 '@iconify-json/simple-icons': - specifier: ^1.2.54 - version: 1.2.54 + specifier: ^1.2.55 + version: 1.2.55 '@kgierke/nuxt-basic-auth': specifier: ^1.7.0 version: 1.7.0(magicast@0.3.5) + '@libsql/client': + specifier: ^0.15.15 + version: 0.15.15 '@nuxt/ui': - specifier: 4.0.1 - version: 4.0.1(@babel/parser@7.28.4)(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(change-case@5.4.4)(db0@0.3.4(@electric-sql/pglite@0.3.11)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(embla-carousel@8.6.0)(ioredis@5.8.1)(magicast@0.3.5)(react@19.1.1)(typescript@5.9.3)(valibot@1.1.0(typescript@5.9.3))(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-router@4.5.1(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3))(zod@4.1.12) + specifier: ^4.0.1 + version: 4.0.1(@babel/parser@7.28.4)(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(change-case@5.4.4)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(embla-carousel@8.6.0)(ioredis@5.8.1)(magicast@0.3.5)(react@19.1.1)(typescript@5.9.3)(valibot@1.1.0(typescript@5.9.3))(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-router@4.5.1(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3))(zod@4.1.12) '@nuxthub/core': specifier: workspace:* version: link:.. @@ -227,19 +227,16 @@ importers: version: 13.9.0(vue@3.5.22(typescript@5.9.3)) '@vueuse/nuxt': specifier: ^13.9.0 - version: 13.9.0(magicast@0.3.5)(nuxt@4.1.3(@electric-sql/pglite@0.3.11)(@parcel/watcher@2.5.1)(@types/node@24.7.2)(@vercel/blob@2.0.0)(@vue/compiler-sfc@3.5.22)(aws4fetch@1.0.20)(better-sqlite3@12.4.1)(db0@0.3.4(@electric-sql/pglite@0.3.11)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3))(eslint@9.37.0(jiti@2.6.1))(ioredis@5.8.1)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rolldown@1.0.0-beta.9)(rollup@4.52.4)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.1(typescript@5.9.3))(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)) + version: 13.9.0(magicast@0.3.5)(nuxt@4.1.3(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@parcel/watcher@2.5.1)(@types/node@24.7.2)(@vercel/blob@2.0.0)(@vue/compiler-sfc@3.5.22)(aws4fetch@1.0.20)(better-sqlite3@12.4.1)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3))(eslint@9.37.0(jiti@2.6.1))(ioredis@5.8.1)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rolldown@1.0.0-beta.9)(rollup@4.52.4)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.1(typescript@5.9.3))(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)) ai: - specifier: ^5.0.68 - version: 5.0.68(zod@4.1.12) - better-sqlite3: - specifier: ^12.4.1 - version: 12.4.1 + specifier: ^5.0.76 + version: 5.0.76(zod@4.1.12) drizzle-orm: specifier: ^0.44.6 - version: 0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3) + version: 0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3) nuxt: specifier: ^4.1.3 - version: 4.1.3(@electric-sql/pglite@0.3.11)(@parcel/watcher@2.5.1)(@types/node@24.7.2)(@vercel/blob@2.0.0)(@vue/compiler-sfc@3.5.22)(aws4fetch@1.0.20)(better-sqlite3@12.4.1)(db0@0.3.4(@electric-sql/pglite@0.3.11)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3))(eslint@9.37.0(jiti@2.6.1))(ioredis@5.8.1)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rolldown@1.0.0-beta.9)(rollup@4.52.4)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.1(typescript@5.9.3))(yaml@2.8.1) + version: 4.1.3(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@parcel/watcher@2.5.1)(@types/node@24.7.2)(@vercel/blob@2.0.0)(@vue/compiler-sfc@3.5.22)(aws4fetch@1.0.20)(better-sqlite3@12.4.1)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3))(eslint@9.37.0(jiti@2.6.1))(ioredis@5.8.1)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rolldown@1.0.0-beta.9)(rollup@4.52.4)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.1(typescript@5.9.3))(yaml@2.8.1) nuxt-auth-utils: specifier: ^0.5.25 version: 0.5.25(magicast@0.3.5) @@ -247,8 +244,8 @@ importers: specifier: ^8.16.3 version: 8.16.3 tailwindcss: - specifier: ^4.1.14 - version: 4.1.14 + specifier: ^4.1.15 + version: 4.1.15 workers-ai-provider: specifier: ^2.0.0 version: 2.0.0(zod@4.1.12) @@ -280,6 +277,12 @@ packages: peerDependencies: zod: ^3.25.76 || ^4.1.8 + '@ai-sdk/gateway@2.0.0': + resolution: {integrity: sha512-Gj0PuawK7NkZuyYgO/h5kDK/l6hFOjhLdTq3/Lli1FTl47iGmwhH1IZQpAL3Z09BeFYWakcwUmn02ovIm2wy9g==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + '@ai-sdk/provider-utils@3.0.10': resolution: {integrity: sha512-T1gZ76gEIwffep6MWI0QNy9jgoybUHE7TRaHB5k54K8mF91ciGFlbtCGxDYhMH3nCRergKwYFIDeFF0hJSIQHQ==} engines: {node: '>=18'} @@ -296,8 +299,8 @@ packages: resolution: {integrity: sha512-6o7Y2SeO9vFKB8lArHXehNuusnpddKPk7xqL7T2/b+OvXMRIXUO1rR4wcv1hAFUAT9avGZshty3Wlua/XA7TvA==} engines: {node: '>=18'} - '@ai-sdk/vue@2.0.68': - resolution: {integrity: sha512-5UZs9+tKVIuh2GEIbE0LOuVE0bwlobUuQBy+3jbP9CmxHqZx9Uau1612XaKCFWhEPKNn7eGLqlfigoaKbcnoLQ==} + '@ai-sdk/vue@2.0.76': + resolution: {integrity: sha512-y9aNvzqWqi6P1v/GjrGtcWMA8HiO1Sp5S2Sp5teXyrsucssYqP35dGZMJfvh7+cDuW3BNHTEFPGkxIsbxOTAkQ==} engines: {node: '>=18'} peerDependencies: vue: ^3.3.4 @@ -758,6 +761,9 @@ packages: '@iconify-json/simple-icons@1.2.54': resolution: {integrity: sha512-OQQYl8yC5j3QklZOYnK31QYe5h47IhyCoxSLd53f0e0nA4dgi8VOZS30SgSAbsecQ+S0xlGJMjXIHTIqZ+ML3w==} + '@iconify-json/simple-icons@1.2.55': + resolution: {integrity: sha512-9vc04pmup/zcef8hDypWU8nMwMaFVkWuUzWkxyL++DVp5AA8baoJHK6RyKN1v+cvfR2agxkUb053XVggzFFkTA==} + '@iconify-json/vscode-icons@1.2.31': resolution: {integrity: sha512-lVb4R5CxosCsnGnQQ3NzrXWLgSeQoq+I2sYCowveVNHFwO2fGGbVmUTc6ApFkjxlqT1i43lNgM9zZuhnkL64hQ==} @@ -834,6 +840,67 @@ packages: '@kwsites/promise-deferred@1.1.1': resolution: {integrity: sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==} + '@libsql/client@0.15.15': + resolution: {integrity: sha512-twC0hQxPNHPKfeOv3sNT6u2pturQjLcI+CnpTM0SjRpocEGgfiZ7DWKXLNnsothjyJmDqEsBQJ5ztq9Wlu470w==} + + '@libsql/core@0.15.15': + resolution: {integrity: sha512-C88Z6UKl+OyuKKPwz224riz02ih/zHYI3Ho/LAcVOgjsunIRZoBw7fjRfaH9oPMmSNeQfhGklSG2il1URoOIsA==} + + '@libsql/darwin-arm64@0.5.22': + resolution: {integrity: sha512-4B8ZlX3nIDPndfct7GNe0nI3Yw6ibocEicWdC4fvQbSs/jdq/RC2oCsoJxJ4NzXkvktX70C1J4FcmmoBy069UA==} + cpu: [arm64] + os: [darwin] + + '@libsql/darwin-x64@0.5.22': + resolution: {integrity: sha512-ny2HYWt6lFSIdNFzUFIJ04uiW6finXfMNJ7wypkAD8Pqdm6nAByO+Fdqu8t7sD0sqJGeUCiOg480icjyQ2/8VA==} + cpu: [x64] + os: [darwin] + + '@libsql/hrana-client@0.7.0': + resolution: {integrity: sha512-OF8fFQSkbL7vJY9rfuegK1R7sPgQ6kFMkDamiEccNUvieQ+3urzfDFI616oPl8V7T9zRmnTkSjMOImYCAVRVuw==} + + '@libsql/isomorphic-fetch@0.3.1': + resolution: {integrity: sha512-6kK3SUK5Uu56zPq/Las620n5aS9xJq+jMBcNSOmjhNf/MUvdyji4vrMTqD7ptY7/4/CAVEAYDeotUz60LNQHtw==} + engines: {node: '>=18.0.0'} + + '@libsql/isomorphic-ws@0.1.5': + resolution: {integrity: sha512-DtLWIH29onUYR00i0GlQ3UdcTRC6EP4u9w/h9LxpUZJWRMARk6dQwZ6Jkd+QdwVpuAOrdxt18v0K2uIYR3fwFg==} + + '@libsql/linux-arm-gnueabihf@0.5.22': + resolution: {integrity: sha512-3Uo3SoDPJe/zBnyZKosziRGtszXaEtv57raWrZIahtQDsjxBVjuzYQinCm9LRCJCUT5t2r5Z5nLDPJi2CwZVoA==} + cpu: [arm] + os: [linux] + + '@libsql/linux-arm-musleabihf@0.5.22': + resolution: {integrity: sha512-LCsXh07jvSojTNJptT9CowOzwITznD+YFGGW+1XxUr7fS+7/ydUrpDfsMX7UqTqjm7xG17eq86VkWJgHJfvpNg==} + cpu: [arm] + os: [linux] + + '@libsql/linux-arm64-gnu@0.5.22': + resolution: {integrity: sha512-KSdnOMy88c9mpOFKUEzPskSaF3VLflfSUCBwas/pn1/sV3pEhtMF6H8VUCd2rsedwoukeeCSEONqX7LLnQwRMA==} + cpu: [arm64] + os: [linux] + + '@libsql/linux-arm64-musl@0.5.22': + resolution: {integrity: sha512-mCHSMAsDTLK5YH//lcV3eFEgiR23Ym0U9oEvgZA0667gqRZg/2px+7LshDvErEKv2XZ8ixzw3p1IrBzLQHGSsw==} + cpu: [arm64] + os: [linux] + + '@libsql/linux-x64-gnu@0.5.22': + resolution: {integrity: sha512-kNBHaIkSg78Y4BqAdgjcR2mBilZXs4HYkAmi58J+4GRwDQZh5fIUWbnQvB9f95DkWUIGVeenqLRFY2pcTmlsew==} + cpu: [x64] + os: [linux] + + '@libsql/linux-x64-musl@0.5.22': + resolution: {integrity: sha512-UZ4Xdxm4pu3pQXjvfJiyCzZop/9j/eA2JjmhMaAhe3EVLH2g11Fy4fwyUp9sT1QJYR1kpc2JLuybPM0kuXv/Tg==} + cpu: [x64] + os: [linux] + + '@libsql/win32-x64-msvc@0.5.22': + resolution: {integrity: sha512-Fj0j8RnBpo43tVZUVoNK6BV/9AtDUM5S7DF3LB4qTYg1LMSZqi3yeCneUTLJD6XomQJlZzbI4mst89yspVSAnA==} + cpu: [x64] + os: [win32] + '@lukeed/ms@2.0.2': resolution: {integrity: sha512-9I2Zn6+NJLfaGoz9jN3lpwDgAYvfGeNYdbAIjJOqzs4Tpc+VU3Jqq4IofSUBKajiDS8k9fZIg18/z13mpk1bsA==} engines: {node: '>=8'} @@ -849,6 +916,9 @@ packages: '@napi-rs/wasm-runtime@1.0.7': resolution: {integrity: sha512-SeDnOO0Tk7Okiq6DbXmmBODgOAb9dp9gjlphokTUxmt8U3liIP1ZsozBahH69j/RJv+Rfs6IwUKHTgQYJ/HBAw==} + '@neon-rs/load@0.0.4': + resolution: {integrity: sha512-kTPhdZyTQxB+2wpiRcFWrDcejc4JI6tkPuS7UZCG4l6Zvc5kU/gGQ/ozvHTh1XR5tS+UlfAfGuPajjzQjCiHCw==} + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -2519,6 +2589,9 @@ packages: '@types/web-bluetooth@0.0.21': resolution: {integrity: sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==} + '@types/ws@8.18.1': + resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} + '@typescript-eslint/eslint-plugin@8.42.0': resolution: {integrity: sha512-Aq2dPqsQkxHOLfb2OPv43RnIvfj05nw8v/6n3B2NABIPpHnjQnaLo9QGMTvml+tv4korl/Cjfrb/BYhoL8UUTQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -2713,6 +2786,10 @@ packages: resolution: {integrity: sha512-JekxQ0RApo4gS4un/iMGsIL1/k4KUBe3HmnGcDvzHuFBdQdudEJgTqcsJC7y6Ul4Yw5CeykgvQbX2XeEJd0+DA==} engines: {node: '>= 20'} + '@vercel/oidc@3.0.3': + resolution: {integrity: sha512-yNEQvPcVrK9sIe637+I0jD6leluPxzwJKx/Haw6F4H77CdDsszUn5V3o96LPziXkSNE2B83+Z3mjqGKBK/R6Gg==} + engines: {node: '>= 20'} + '@vitejs/plugin-vue-jsx@5.1.1': resolution: {integrity: sha512-uQkfxzlF8SGHJJVH966lFTdjM/lGcwJGzwAHpVqAPDD/QcsqoUGa+q31ox1BrUfi+FLP2ChVp7uLXE3DkHyDdQ==} engines: {node: ^20.19.0 || >=22.12.0} @@ -2985,6 +3062,12 @@ packages: peerDependencies: zod: ^3.25.76 || ^4.1.8 + ai@5.0.76: + resolution: {integrity: sha512-ZCxi1vrpyCUnDbtYrO/W8GLvyacV9689f00yshTIQ3mFFphbD7eIv40a2AOZBv3GGRA7SSRYIDnr56wcS/gyQg==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} @@ -3506,6 +3589,10 @@ packages: csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + data-uri-to-buffer@4.0.1: + resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} + engines: {node: '>= 12'} + db0@0.3.4: resolution: {integrity: sha512-RiXXi4WaNzPTHEOu8UPQKMooIbqOEyqA1t7Z6MsdxSCeb8iUC9ko3LcmsLmeUt2SM5bctfArZKkRQggKZz7JNw==} peerDependencies: @@ -3620,6 +3707,10 @@ packages: engines: {node: '>=0.10'} hasBin: true + detect-libc@2.0.2: + resolution: {integrity: sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==} + engines: {node: '>=8'} + detect-libc@2.1.2: resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} engines: {node: '>=8'} @@ -4109,6 +4200,10 @@ packages: resolution: {integrity: sha512-qGNhgYygnefSkAHHrNHqC7p3R8J0/xQDS/cYUud8er/qD9EFGWyCdUDfULHTJQN1d3H3WprzVwMc9MfB4J50Wg==} engines: {node: '>=20', pnpm: '>=10'} + fetch-blob@3.2.0: + resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} + engines: {node: ^12.20 || >= 14.13} + fflate@0.7.4: resolution: {integrity: sha512-5u2V/CDW15QM1XbbgS+0DfPxVB+jUKhWEKuuFuHncbk3tEEqzmoXL+2KyOFuKGqOnmdIy0/davWF1CkuwtibCw==} @@ -4164,6 +4259,10 @@ packages: resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} engines: {node: '>=14'} + formdata-polyfill@4.0.10: + resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} + engines: {node: '>=12.20.0'} + fraction.js@4.3.7: resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} @@ -4593,6 +4692,9 @@ packages: jose@6.1.0: resolution: {integrity: sha512-TTQJyoEoKcC1lscpVDCSsVgYzUDg/0Bt3WE//WiTPK6uOCQC2KZS4MpugbMWt/zyjkopgZoXhZuCi00gLudfUA==} + js-base64@3.7.8: + resolution: {integrity: sha512-hNngCeKxIUQiEUN3GPJOkz4wF/YvdUdbNL9hsBcMQTkKzboD7T/q3OYOuuPZLUE6dBxSGpwhk5mwuDud7JVAow==} + js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -4678,6 +4780,11 @@ packages: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} + libsql@0.5.22: + resolution: {integrity: sha512-NscWthMQt7fpU8lqd7LXMvT9pi+KhhmTHAJWUB/Lj6MWa0MKFv0F2V4C6WKKpjCVZl0VwcDz4nOI3CyaT1DDiA==} + cpu: [x64, arm64, wasm32, arm] + os: [darwin, linux, win32] + lighthouse-logger@2.0.2: resolution: {integrity: sha512-vWl2+u5jgOQuZR55Z1WM0XDdrJT6mzMP8zHUct7xTlWhuQs+eV0g+QL0RQdFjT54zVmbhLCP8vIVpy1wGn/gCg==} @@ -5121,6 +5228,11 @@ packages: node-addon-api@7.1.1: resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} + node-domexception@1.0.0: + resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} + engines: {node: '>=10.5.0'} + deprecated: Use your platform's native DOMException instead + node-emoji@2.2.0: resolution: {integrity: sha512-Z3lTE9pLaJF47NyMhd4ww1yFTAP8YhYI8SleJiHzM46Fgpm5cnNzSl9XfzFNqbaz+VlJrIj3fXQ4DeN1Rjm6cw==} engines: {node: '>=18'} @@ -5137,6 +5249,10 @@ packages: encoding: optional: true + node-fetch@3.3.2: + resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + node-forge@1.3.1: resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} engines: {node: '>= 6.13.0'} @@ -5704,6 +5820,9 @@ packages: resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} engines: {node: '>= 0.6.0'} + promise-limit@2.7.0: + resolution: {integrity: sha512-7nJ6v5lnJsXwGprnGXga4wx6d1POjvi5Qmf1ivTRxTjH4Z/9Czja/UCMLVmB9N93GeWOU93XaFaEt6jbuoagNw==} + prompts@2.4.2: resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} engines: {node: '>= 6'} @@ -6272,6 +6391,9 @@ packages: tailwindcss@4.1.14: resolution: {integrity: sha512-b7pCxjGO98LnxVkKjaZSDeNuljC4ueKUddjENJOADtubtdo8llTaJy7HwBMeLNSSo2N5QIAgklslK1+Ir8r6CA==} + tailwindcss@4.1.15: + resolution: {integrity: sha512-k2WLnWkYFkdpRv+Oby3EBXIyQC8/s1HOFMBUViwtAh6Z5uAozeUSMQlIsn/c6Q2iJzqG6aJT3wdPaRNj70iYxQ==} + tapable@2.3.0: resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} engines: {node: '>=6'} @@ -6907,6 +7029,10 @@ packages: web-namespaces@2.0.1: resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} + web-streams-polyfill@3.3.3: + resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} + engines: {node: '>= 8'} + webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} @@ -7068,18 +7194,25 @@ snapshots: '@phc/format': 1.0.0 '@poppinss/utils': 6.10.1 - '@ai-sdk/gateway@1.0.39(zod@3.25.76)': + '@ai-sdk/gateway@1.0.39(zod@4.1.12)': dependencies: '@ai-sdk/provider': 2.0.0 - '@ai-sdk/provider-utils': 3.0.12(zod@3.25.76) + '@ai-sdk/provider-utils': 3.0.12(zod@4.1.12) '@vercel/oidc': 3.0.2 + zod: 4.1.12 + + '@ai-sdk/gateway@2.0.0(zod@3.25.76)': + dependencies: + '@ai-sdk/provider': 2.0.0 + '@ai-sdk/provider-utils': 3.0.12(zod@3.25.76) + '@vercel/oidc': 3.0.3 zod: 3.25.76 - '@ai-sdk/gateway@1.0.39(zod@4.1.12)': + '@ai-sdk/gateway@2.0.0(zod@4.1.12)': dependencies: '@ai-sdk/provider': 2.0.0 '@ai-sdk/provider-utils': 3.0.12(zod@4.1.12) - '@vercel/oidc': 3.0.2 + '@vercel/oidc': 3.0.3 zod: 4.1.12 '@ai-sdk/provider-utils@3.0.10(zod@4.1.12)': @@ -7107,19 +7240,19 @@ snapshots: dependencies: json-schema: 0.4.0 - '@ai-sdk/vue@2.0.68(vue@3.5.22(typescript@5.9.3))(zod@3.25.76)': + '@ai-sdk/vue@2.0.76(vue@3.5.22(typescript@5.9.3))(zod@3.25.76)': dependencies: '@ai-sdk/provider-utils': 3.0.12(zod@3.25.76) - ai: 5.0.68(zod@3.25.76) + ai: 5.0.76(zod@3.25.76) swrv: 1.1.0(vue@3.5.22(typescript@5.9.3)) optionalDependencies: vue: 3.5.22(typescript@5.9.3) zod: 3.25.76 - '@ai-sdk/vue@2.0.68(vue@3.5.22(typescript@5.9.3))(zod@4.1.12)': + '@ai-sdk/vue@2.0.76(vue@3.5.22(typescript@5.9.3))(zod@4.1.12)': dependencies: '@ai-sdk/provider-utils': 3.0.12(zod@4.1.12) - ai: 5.0.68(zod@4.1.12) + ai: 5.0.76(zod@4.1.12) swrv: 1.1.0(vue@3.5.22(typescript@5.9.3)) optionalDependencies: vue: 3.5.22(typescript@5.9.3) @@ -7575,6 +7708,10 @@ snapshots: dependencies: '@iconify/types': 2.0.0 + '@iconify-json/simple-icons@1.2.55': + dependencies: + '@iconify/types': 2.0.0 + '@iconify-json/vscode-icons@1.2.31': dependencies: '@iconify/types': 2.0.0 @@ -7678,6 +7815,68 @@ snapshots: '@kwsites/promise-deferred@1.1.1': {} + '@libsql/client@0.15.15': + dependencies: + '@libsql/core': 0.15.15 + '@libsql/hrana-client': 0.7.0 + js-base64: 3.7.8 + libsql: 0.5.22 + promise-limit: 2.7.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@libsql/core@0.15.15': + dependencies: + js-base64: 3.7.8 + + '@libsql/darwin-arm64@0.5.22': + optional: true + + '@libsql/darwin-x64@0.5.22': + optional: true + + '@libsql/hrana-client@0.7.0': + dependencies: + '@libsql/isomorphic-fetch': 0.3.1 + '@libsql/isomorphic-ws': 0.1.5 + js-base64: 3.7.8 + node-fetch: 3.3.2 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@libsql/isomorphic-fetch@0.3.1': {} + + '@libsql/isomorphic-ws@0.1.5': + dependencies: + '@types/ws': 8.18.1 + ws: 8.18.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@libsql/linux-arm-gnueabihf@0.5.22': + optional: true + + '@libsql/linux-arm-musleabihf@0.5.22': + optional: true + + '@libsql/linux-arm64-gnu@0.5.22': + optional: true + + '@libsql/linux-arm64-musl@0.5.22': + optional: true + + '@libsql/linux-x64-gnu@0.5.22': + optional: true + + '@libsql/linux-x64-musl@0.5.22': + optional: true + + '@libsql/win32-x64-msvc@0.5.22': + optional: true + '@lukeed/ms@2.0.2': {} '@mapbox/node-pre-gyp@2.0.0': @@ -7707,6 +7906,8 @@ snapshots: '@tybys/wasm-util': 0.10.1 optional: true + '@neon-rs/load@0.0.4': {} + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -7751,7 +7952,7 @@ snapshots: transitivePeerDependencies: - magicast - '@nuxt/content@3.7.1(@electric-sql/pglite@0.3.11)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3))(magicast@0.3.5)(valibot@1.1.0(typescript@5.9.3))': + '@nuxt/content@3.7.1(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3))(magicast@0.3.5)(valibot@1.1.0(typescript@5.9.3))': dependencies: '@nuxt/kit': 4.1.3(magicast@0.3.5) '@nuxtjs/mdc': 0.17.4(magicast@0.3.5) @@ -7762,7 +7963,7 @@ snapshots: c12: 3.3.0(magicast@0.3.5) chokidar: 4.0.3 consola: 3.4.2 - db0: 0.3.4(@electric-sql/pglite@0.3.11)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)) + db0: 0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)) defu: 6.1.4 destr: 2.0.5 git-url-parse: 16.1.0 @@ -7802,6 +8003,7 @@ snapshots: zod-to-json-schema: 3.24.6(zod@3.25.76) optionalDependencies: '@electric-sql/pglite': 0.3.11 + '@libsql/client': 0.15.15 better-sqlite3: 12.4.1 valibot: 1.1.0(typescript@5.9.3) transitivePeerDependencies: @@ -7914,7 +8116,7 @@ snapshots: - supports-color - typescript - '@nuxt/fonts@0.11.4(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1)(magicast@0.3.5)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))': + '@nuxt/fonts@0.11.4(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1)(magicast@0.3.5)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))': dependencies: '@nuxt/devtools-kit': 2.6.5(magicast@0.3.5)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1)) '@nuxt/kit': 3.19.3(magicast@0.3.5) @@ -7935,7 +8137,7 @@ snapshots: ufo: 1.6.1 unifont: 0.4.1 unplugin: 2.3.10 - unstorage: 1.17.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1) + unstorage: 1.17.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -7982,7 +8184,7 @@ snapshots: - vite - vue - '@nuxt/image@1.11.0(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1)(magicast@0.3.5)': + '@nuxt/image@1.11.0(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1)(magicast@0.3.5)': dependencies: '@nuxt/kit': 3.19.3(magicast@0.3.5) consola: 3.4.2 @@ -7995,7 +8197,7 @@ snapshots: std-env: 3.9.0 ufo: 1.6.1 optionalDependencies: - ipx: 2.1.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1) + ipx: 2.1.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -8109,7 +8311,7 @@ snapshots: std-env: 3.9.0 ufo: 1.6.1 - '@nuxt/scripts@0.12.1(@googlemaps/markerclusterer@2.6.2)(@unhead/vue@2.0.19(vue@3.5.22(typescript@5.9.3)))(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1)(magicast@0.3.5)(typescript@5.9.3)(vue@3.5.22(typescript@5.9.3))': + '@nuxt/scripts@0.12.1(@googlemaps/markerclusterer@2.6.2)(@unhead/vue@2.0.19(vue@3.5.22(typescript@5.9.3)))(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1)(magicast@0.3.5)(typescript@5.9.3)(vue@3.5.22(typescript@5.9.3))': dependencies: '@googlemaps/markerclusterer': 2.6.2 '@nuxt/kit': 4.1.3(magicast@0.3.5) @@ -8127,7 +8329,7 @@ snapshots: std-env: 3.9.0 ufo: 1.6.1 unplugin: 2.3.10 - unstorage: 1.17.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1) + unstorage: 1.17.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1) valibot: 1.1.0(typescript@5.9.3) transitivePeerDependencies: - '@azure/app-configuration' @@ -8203,13 +8405,13 @@ snapshots: - magicast - typescript - '@nuxt/ui@4.0.1(@babel/parser@7.28.4)(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(change-case@5.4.4)(db0@0.3.4(@electric-sql/pglite@0.3.11)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(embla-carousel@8.6.0)(ioredis@5.8.1)(magicast@0.3.5)(react@19.1.1)(typescript@5.9.3)(valibot@1.1.0(typescript@5.9.3))(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-router@4.5.1(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3))(zod@3.25.76)': + '@nuxt/ui@4.0.1(@babel/parser@7.28.4)(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(change-case@5.4.4)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(embla-carousel@8.6.0)(ioredis@5.8.1)(magicast@0.3.5)(react@19.1.1)(typescript@5.9.3)(valibot@1.1.0(typescript@5.9.3))(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-router@4.5.1(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3))(zod@3.25.76)': dependencies: - '@ai-sdk/vue': 2.0.68(vue@3.5.22(typescript@5.9.3))(zod@3.25.76) + '@ai-sdk/vue': 2.0.76(vue@3.5.22(typescript@5.9.3))(zod@3.25.76) '@iconify/vue': 5.0.0(vue@3.5.22(typescript@5.9.3)) '@internationalized/date': 3.10.0 '@internationalized/number': 3.6.5 - '@nuxt/fonts': 0.11.4(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1)(magicast@0.3.5)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1)) + '@nuxt/fonts': 0.11.4(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1)(magicast@0.3.5)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1)) '@nuxt/icon': 2.0.0(magicast@0.3.5)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)) '@nuxt/kit': 4.1.3(magicast@0.3.5) '@nuxt/schema': 4.1.3 @@ -8242,8 +8444,8 @@ snapshots: reka-ui: 2.5.1(typescript@5.9.3)(vue@3.5.22(typescript@5.9.3)) scule: 1.3.0 tailwind-merge: 3.3.1 - tailwind-variants: 3.1.1(tailwind-merge@3.3.1)(tailwindcss@4.1.14) - tailwindcss: 4.1.14 + tailwind-variants: 3.1.1(tailwind-merge@3.3.1)(tailwindcss@4.1.15) + tailwindcss: 4.1.15 tinyglobby: 0.2.15 typescript: 5.9.3 unplugin: 2.3.10 @@ -8297,13 +8499,13 @@ snapshots: - vite - vue - '@nuxt/ui@4.0.1(@babel/parser@7.28.4)(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(change-case@5.4.4)(db0@0.3.4(@electric-sql/pglite@0.3.11)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(embla-carousel@8.6.0)(ioredis@5.8.1)(magicast@0.3.5)(react@19.1.1)(typescript@5.9.3)(valibot@1.1.0(typescript@5.9.3))(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-router@4.5.1(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3))(zod@4.1.12)': + '@nuxt/ui@4.0.1(@babel/parser@7.28.4)(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(change-case@5.4.4)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(embla-carousel@8.6.0)(ioredis@5.8.1)(magicast@0.3.5)(react@19.1.1)(typescript@5.9.3)(valibot@1.1.0(typescript@5.9.3))(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-router@4.5.1(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3))(zod@4.1.12)': dependencies: - '@ai-sdk/vue': 2.0.68(vue@3.5.22(typescript@5.9.3))(zod@4.1.12) + '@ai-sdk/vue': 2.0.76(vue@3.5.22(typescript@5.9.3))(zod@4.1.12) '@iconify/vue': 5.0.0(vue@3.5.22(typescript@5.9.3)) '@internationalized/date': 3.10.0 '@internationalized/number': 3.6.5 - '@nuxt/fonts': 0.11.4(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1)(magicast@0.3.5)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1)) + '@nuxt/fonts': 0.11.4(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1)(magicast@0.3.5)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1)) '@nuxt/icon': 2.0.0(magicast@0.3.5)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)) '@nuxt/kit': 4.1.3(magicast@0.3.5) '@nuxt/schema': 4.1.3 @@ -8336,8 +8538,8 @@ snapshots: reka-ui: 2.5.1(typescript@5.9.3)(vue@3.5.22(typescript@5.9.3)) scule: 1.3.0 tailwind-merge: 3.3.1 - tailwind-variants: 3.1.1(tailwind-merge@3.3.1)(tailwindcss@4.1.14) - tailwindcss: 4.1.14 + tailwind-variants: 3.1.1(tailwind-merge@3.3.1)(tailwindcss@4.1.15) + tailwindcss: 4.1.15 tinyglobby: 0.2.15 typescript: 5.9.3 unplugin: 2.3.10 @@ -9756,6 +9958,10 @@ snapshots: '@types/web-bluetooth@0.0.21': {} + '@types/ws@8.18.1': + dependencies: + '@types/node': 24.7.2 + '@typescript-eslint/eslint-plugin@8.42.0(@typescript-eslint/parser@8.42.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.1 @@ -9970,6 +10176,8 @@ snapshots: '@vercel/oidc@3.0.2': {} + '@vercel/oidc@3.0.3': {} + '@vitejs/plugin-vue-jsx@5.1.1(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3))': dependencies: '@babel/core': 7.28.4 @@ -10270,13 +10478,13 @@ snapshots: '@vueuse/metadata@13.9.0': {} - '@vueuse/nuxt@13.9.0(magicast@0.3.5)(nuxt@4.1.3(@electric-sql/pglite@0.3.11)(@parcel/watcher@2.5.1)(@types/node@24.7.2)(@vercel/blob@2.0.0)(@vue/compiler-sfc@3.5.22)(aws4fetch@1.0.20)(better-sqlite3@12.4.1)(db0@0.3.4(@electric-sql/pglite@0.3.11)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3))(eslint@9.37.0(jiti@2.6.1))(ioredis@5.8.1)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rolldown@1.0.0-beta.9)(rollup@4.52.4)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.1(typescript@5.9.3))(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3))': + '@vueuse/nuxt@13.9.0(magicast@0.3.5)(nuxt@4.1.3(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@parcel/watcher@2.5.1)(@types/node@24.7.2)(@vercel/blob@2.0.0)(@vue/compiler-sfc@3.5.22)(aws4fetch@1.0.20)(better-sqlite3@12.4.1)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3))(eslint@9.37.0(jiti@2.6.1))(ioredis@5.8.1)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rolldown@1.0.0-beta.9)(rollup@4.52.4)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.1(typescript@5.9.3))(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3))': dependencies: '@nuxt/kit': 3.19.3(magicast@0.3.5) '@vueuse/core': 13.9.0(vue@3.5.22(typescript@5.9.3)) '@vueuse/metadata': 13.9.0 local-pkg: 1.1.2 - nuxt: 4.1.3(@electric-sql/pglite@0.3.11)(@parcel/watcher@2.5.1)(@types/node@24.7.2)(@vercel/blob@2.0.0)(@vue/compiler-sfc@3.5.22)(aws4fetch@1.0.20)(better-sqlite3@12.4.1)(db0@0.3.4(@electric-sql/pglite@0.3.11)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3))(eslint@9.37.0(jiti@2.6.1))(ioredis@5.8.1)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rolldown@1.0.0-beta.9)(rollup@4.52.4)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.1(typescript@5.9.3))(yaml@2.8.1) + nuxt: 4.1.3(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@parcel/watcher@2.5.1)(@types/node@24.7.2)(@vercel/blob@2.0.0)(@vue/compiler-sfc@3.5.22)(aws4fetch@1.0.20)(better-sqlite3@12.4.1)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3))(eslint@9.37.0(jiti@2.6.1))(ioredis@5.8.1)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rolldown@1.0.0-beta.9)(rollup@4.52.4)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.1(typescript@5.9.3))(yaml@2.8.1) vue: 3.5.22(typescript@5.9.3) transitivePeerDependencies: - magicast @@ -10318,17 +10526,25 @@ snapshots: agent-base@7.1.4: {} - ai@5.0.68(zod@3.25.76): + ai@5.0.68(zod@4.1.12): + dependencies: + '@ai-sdk/gateway': 1.0.39(zod@4.1.12) + '@ai-sdk/provider': 2.0.0 + '@ai-sdk/provider-utils': 3.0.12(zod@4.1.12) + '@opentelemetry/api': 1.9.0 + zod: 4.1.12 + + ai@5.0.76(zod@3.25.76): dependencies: - '@ai-sdk/gateway': 1.0.39(zod@3.25.76) + '@ai-sdk/gateway': 2.0.0(zod@3.25.76) '@ai-sdk/provider': 2.0.0 '@ai-sdk/provider-utils': 3.0.12(zod@3.25.76) '@opentelemetry/api': 1.9.0 zod: 3.25.76 - ai@5.0.68(zod@4.1.12): + ai@5.0.76(zod@4.1.12): dependencies: - '@ai-sdk/gateway': 1.0.39(zod@4.1.12) + '@ai-sdk/gateway': 2.0.0(zod@4.1.12) '@ai-sdk/provider': 2.0.0 '@ai-sdk/provider-utils': 3.0.12(zod@4.1.12) '@opentelemetry/api': 1.9.0 @@ -10477,6 +10693,7 @@ snapshots: dependencies: bindings: 1.5.0 prebuild-install: 7.1.3 + optional: true binary-extensions@2.3.0: {} @@ -10491,6 +10708,7 @@ snapshots: buffer: 5.7.1 inherits: 2.0.4 readable-stream: 3.6.2 + optional: true blob-to-buffer@1.2.9: {} @@ -10536,6 +10754,7 @@ snapshots: dependencies: base64-js: 1.5.1 ieee754: 1.2.1 + optional: true buffer@6.0.3: dependencies: @@ -10647,7 +10866,8 @@ snapshots: dependencies: readdirp: 4.1.2 - chownr@1.1.4: {} + chownr@1.1.4: + optional: true chownr@3.0.0: {} @@ -10890,11 +11110,14 @@ snapshots: csstype@3.1.3: {} - db0@0.3.4(@electric-sql/pglite@0.3.11)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)): + data-uri-to-buffer@4.0.1: {} + + db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)): optionalDependencies: '@electric-sql/pglite': 0.3.11 + '@libsql/client': 0.15.15 better-sqlite3: 12.4.1 - drizzle-orm: 0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3) + drizzle-orm: 0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3) debug@4.3.7: dependencies: @@ -10915,10 +11138,12 @@ snapshots: decompress-response@6.0.0: dependencies: mimic-response: 3.1.0 + optional: true deep-eql@5.0.2: {} - deep-extend@0.6.0: {} + deep-extend@0.6.0: + optional: true deep-is@0.1.4: {} @@ -10949,6 +11174,8 @@ snapshots: detect-libc@1.0.3: {} + detect-libc@2.0.2: {} + detect-libc@2.1.2: {} devalue@5.3.2: {} @@ -10987,10 +11214,11 @@ snapshots: dotenv@17.2.3: {} - drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3): + drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3): optionalDependencies: '@cloudflare/workers-types': 4.20251011.0 '@electric-sql/pglite': 0.3.11 + '@libsql/client': 0.15.15 '@opentelemetry/api': 1.9.0 better-sqlite3: 12.4.1 pg: 8.16.3 @@ -11059,6 +11287,7 @@ snapshots: end-of-stream@1.4.5: dependencies: once: 1.4.0 + optional: true engine.io-client@6.6.3: dependencies: @@ -11356,7 +11585,8 @@ snapshots: strip-final-newline: 4.0.0 yoctocolors: 2.1.2 - expand-template@2.0.3: {} + expand-template@2.0.3: + optional: true expect-type@1.2.2: {} @@ -11398,6 +11628,11 @@ snapshots: dependencies: xml-js: 1.6.11 + fetch-blob@3.2.0: + dependencies: + node-domexception: 1.0.0 + web-streams-polyfill: 3.3.3 + fflate@0.7.4: {} figures@6.1.0: @@ -11468,6 +11703,10 @@ snapshots: cross-spawn: 7.0.6 signal-exit: 4.1.0 + formdata-polyfill@4.0.10: + dependencies: + fetch-blob: 3.2.0 + fraction.js@4.3.7: {} framer-motion@12.23.12(react@19.1.1): @@ -11480,7 +11719,8 @@ snapshots: fresh@2.0.0: {} - fs-constants@1.0.0: {} + fs-constants@1.0.0: + optional: true fsevents@2.3.3: optional: true @@ -11524,7 +11764,8 @@ snapshots: dependencies: git-up: 8.1.1 - github-from-package@0.0.0: {} + github-from-package@0.0.0: + optional: true github-slugger@2.0.0: {} @@ -11794,7 +12035,8 @@ snapshots: inherits@2.0.4: {} - ini@1.3.8: {} + ini@1.3.8: + optional: true ini@4.1.1: {} @@ -11812,7 +12054,7 @@ snapshots: transitivePeerDependencies: - supports-color - ipx@2.1.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1): + ipx@2.1.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1): dependencies: '@fastify/accept-negotiator': 1.1.0 citty: 0.1.6 @@ -11828,7 +12070,7 @@ snapshots: sharp: 0.32.6 svgo: 3.3.2 ufo: 1.6.1 - unstorage: 1.17.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1) + unstorage: 1.17.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1) xss: 1.0.15 transitivePeerDependencies: - '@azure/app-configuration' @@ -11970,6 +12212,8 @@ snapshots: jose@6.1.0: {} + js-base64@3.7.8: {} + js-tokens@4.0.0: {} js-tokens@9.0.1: {} @@ -12038,6 +12282,21 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 + libsql@0.5.22: + dependencies: + '@neon-rs/load': 0.0.4 + detect-libc: 2.0.2 + optionalDependencies: + '@libsql/darwin-arm64': 0.5.22 + '@libsql/darwin-x64': 0.5.22 + '@libsql/linux-arm-gnueabihf': 0.5.22 + '@libsql/linux-arm-musleabihf': 0.5.22 + '@libsql/linux-arm64-gnu': 0.5.22 + '@libsql/linux-arm64-musl': 0.5.22 + '@libsql/linux-x64-gnu': 0.5.22 + '@libsql/linux-x64-musl': 0.5.22 + '@libsql/win32-x64-msvc': 0.5.22 + lighthouse-logger@2.0.2: dependencies: debug: 4.4.3 @@ -12515,7 +12774,8 @@ snapshots: mimic-fn@4.0.0: {} - mimic-response@3.1.0: {} + mimic-response@3.1.0: + optional: true min-indent@1.0.1: {} @@ -12547,7 +12807,8 @@ snapshots: mitt@3.0.1: {} - mkdirp-classic@0.5.3: {} + mkdirp-classic@0.5.3: + optional: true mkdist@2.3.0(typescript@5.9.3)(vue-sfc-transformer@0.1.16(@vue/compiler-core@3.5.22)(esbuild@0.25.10)(vue@3.5.22(typescript@5.9.3)))(vue-tsc@3.1.1(typescript@5.9.3))(vue@3.5.22(typescript@5.9.3)): dependencies: @@ -12611,7 +12872,8 @@ snapshots: nanotar@0.2.0: {} - napi-build-utils@2.0.0: {} + napi-build-utils@2.0.0: + optional: true napi-postinstall@0.3.3: {} @@ -12623,7 +12885,7 @@ snapshots: mlly: 1.8.0 pkg-types: 2.3.0 - nitropack@2.12.7(@electric-sql/pglite@0.3.11)(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3))(rolldown@1.0.0-beta.9): + nitropack@2.12.7(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3))(rolldown@1.0.0-beta.9): dependencies: '@cloudflare/kv-asset-handler': 0.4.0 '@rollup/plugin-alias': 5.1.1(rollup@4.52.4) @@ -12644,7 +12906,7 @@ snapshots: cookie-es: 2.0.0 croner: 9.1.0 crossws: 0.3.5 - db0: 0.3.4(@electric-sql/pglite@0.3.11)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)) + db0: 0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)) defu: 6.1.4 destr: 2.0.5 dot-prop: 10.1.0 @@ -12690,7 +12952,7 @@ snapshots: unenv: 2.0.0-rc.21 unimport: 5.4.1 unplugin-utils: 0.3.1 - unstorage: 1.17.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1) + unstorage: 1.17.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1) untyped: 2.0.0 unwasm: 0.3.11 youch: 4.1.0-beta.11 @@ -12728,12 +12990,15 @@ snapshots: node-abi@3.78.0: dependencies: semver: 7.7.3 + optional: true node-addon-api@6.1.0: optional: true node-addon-api@7.1.1: {} + node-domexception@1.0.0: {} + node-emoji@2.2.0: dependencies: '@sindresorhus/is': 4.6.0 @@ -12747,6 +13012,12 @@ snapshots: dependencies: whatwg-url: 5.0.0 + node-fetch@3.3.2: + dependencies: + data-uri-to-buffer: 4.0.1 + fetch-blob: 3.2.0 + formdata-polyfill: 4.0.10 + node-forge@1.3.1: {} node-gyp-build@4.8.4: {} @@ -12816,7 +13087,7 @@ snapshots: transitivePeerDependencies: - magicast - nuxt-og-image@5.1.11(@unhead/vue@2.0.19(vue@3.5.22(typescript@5.9.3)))(h3@1.15.4)(magicast@0.3.5)(unstorage@1.17.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1))(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)): + nuxt-og-image@5.1.11(@unhead/vue@2.0.19(vue@3.5.22(typescript@5.9.3)))(h3@1.15.4)(magicast@0.3.5)(unstorage@1.17.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1))(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)): dependencies: '@nuxt/devtools-kit': 2.6.5(magicast@0.3.5)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1)) '@nuxt/kit': 4.1.3(magicast@0.3.5) @@ -12847,7 +13118,7 @@ snapshots: strip-literal: 3.1.0 ufo: 1.6.1 unplugin: 2.3.10 - unstorage: 1.17.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1) + unstorage: 1.17.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1) unwasm: 0.3.11 yoga-wasm-web: 0.3.3 transitivePeerDependencies: @@ -12882,7 +13153,7 @@ snapshots: - magicast - vue - nuxt@4.1.3(@electric-sql/pglite@0.3.11)(@parcel/watcher@2.5.1)(@types/node@24.7.2)(@vercel/blob@2.0.0)(@vue/compiler-sfc@3.5.22)(aws4fetch@1.0.20)(better-sqlite3@12.4.1)(db0@0.3.4(@electric-sql/pglite@0.3.11)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3))(eslint@9.37.0(jiti@2.6.1))(ioredis@5.8.1)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rolldown@1.0.0-beta.9)(rollup@4.50.0)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.1(typescript@5.9.3))(yaml@2.8.1): + nuxt@4.1.3(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@parcel/watcher@2.5.1)(@types/node@24.7.2)(@vercel/blob@2.0.0)(@vue/compiler-sfc@3.5.22)(aws4fetch@1.0.20)(better-sqlite3@12.4.1)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3))(eslint@9.37.0(jiti@2.6.1))(ioredis@5.8.1)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rolldown@1.0.0-beta.9)(rollup@4.50.0)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.1(typescript@5.9.3))(yaml@2.8.1): dependencies: '@nuxt/cli': 3.29.3(magicast@0.3.5) '@nuxt/devalue': 2.0.2 @@ -12917,7 +13188,7 @@ snapshots: mlly: 1.8.0 mocked-exports: 0.1.1 nanotar: 0.2.0 - nitropack: 2.12.7(@electric-sql/pglite@0.3.11)(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3))(rolldown@1.0.0-beta.9) + nitropack: 2.12.7(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3))(rolldown@1.0.0-beta.9) nypm: 0.6.2 ofetch: 1.4.1 ohash: 2.0.11 @@ -12941,7 +13212,7 @@ snapshots: unimport: 5.4.1 unplugin: 2.3.10 unplugin-vue-router: 0.15.0(@vue/compiler-sfc@3.5.22)(typescript@5.9.3)(vue-router@4.5.1(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3)) - unstorage: 1.17.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1) + unstorage: 1.17.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1) untyped: 2.0.0 vue: 3.5.22(typescript@5.9.3) vue-bundle-renderer: 2.2.0 @@ -13008,7 +13279,7 @@ snapshots: - xml2js - yaml - nuxt@4.1.3(@electric-sql/pglite@0.3.11)(@parcel/watcher@2.5.1)(@types/node@24.7.2)(@vercel/blob@2.0.0)(@vue/compiler-sfc@3.5.22)(aws4fetch@1.0.20)(better-sqlite3@12.4.1)(db0@0.3.4(@electric-sql/pglite@0.3.11)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3))(eslint@9.37.0(jiti@2.6.1))(ioredis@5.8.1)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rolldown@1.0.0-beta.9)(rollup@4.52.4)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.1(typescript@5.9.3))(yaml@2.8.1): + nuxt@4.1.3(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@parcel/watcher@2.5.1)(@types/node@24.7.2)(@vercel/blob@2.0.0)(@vue/compiler-sfc@3.5.22)(aws4fetch@1.0.20)(better-sqlite3@12.4.1)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3))(eslint@9.37.0(jiti@2.6.1))(ioredis@5.8.1)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rolldown@1.0.0-beta.9)(rollup@4.52.4)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.1(typescript@5.9.3))(yaml@2.8.1): dependencies: '@nuxt/cli': 3.29.3(magicast@0.3.5) '@nuxt/devalue': 2.0.2 @@ -13043,7 +13314,7 @@ snapshots: mlly: 1.8.0 mocked-exports: 0.1.1 nanotar: 0.2.0 - nitropack: 2.12.7(@electric-sql/pglite@0.3.11)(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3))(rolldown@1.0.0-beta.9) + nitropack: 2.12.7(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3))(rolldown@1.0.0-beta.9) nypm: 0.6.2 ofetch: 1.4.1 ohash: 2.0.11 @@ -13067,7 +13338,7 @@ snapshots: unimport: 5.4.1 unplugin: 2.3.10 unplugin-vue-router: 0.15.0(@vue/compiler-sfc@3.5.22)(typescript@5.9.3)(vue-router@4.5.1(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3)) - unstorage: 1.17.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1) + unstorage: 1.17.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1) untyped: 2.0.0 vue: 3.5.22(typescript@5.9.3) vue-bundle-renderer: 2.2.0 @@ -13184,6 +13455,7 @@ snapshots: once@1.4.0: dependencies: wrappy: 1.0.2 + optional: true onetime@6.0.0: dependencies: @@ -13680,6 +13952,7 @@ snapshots: simple-get: 4.0.1 tar-fs: 2.1.4 tunnel-agent: 0.6.0 + optional: true prelude-ls@1.2.1: {} @@ -13697,6 +13970,8 @@ snapshots: process@0.11.10: {} + promise-limit@2.7.0: {} + prompts@2.4.2: dependencies: kleur: 3.0.3 @@ -13712,6 +13987,7 @@ snapshots: dependencies: end-of-stream: 1.4.5 once: 1.4.0 + optional: true punycode@2.3.1: {} @@ -13738,6 +14014,7 @@ snapshots: ini: 1.3.8 minimist: 1.2.8 strip-json-comments: 2.0.1 + optional: true react@19.1.1: optional: true @@ -13757,6 +14034,7 @@ snapshots: inherits: 2.0.4 string_decoder: 1.3.0 util-deprecate: 1.0.2 + optional: true readable-stream@4.7.0: dependencies: @@ -14246,13 +14524,15 @@ snapshots: signal-exit@4.1.0: {} - simple-concat@1.0.1: {} + simple-concat@1.0.1: + optional: true simple-get@4.0.1: dependencies: decompress-response: 6.0.0 once: 1.4.0 simple-concat: 1.0.1 + optional: true simple-git@3.28.0: dependencies: @@ -14400,7 +14680,8 @@ snapshots: dependencies: min-indent: 1.0.1 - strip-json-comments@2.0.1: {} + strip-json-comments@2.0.1: + optional: true strip-json-comments@3.1.1: {} @@ -14467,14 +14748,16 @@ snapshots: tailwind-merge@3.3.1: {} - tailwind-variants@3.1.1(tailwind-merge@3.3.1)(tailwindcss@4.1.14): + tailwind-variants@3.1.1(tailwind-merge@3.3.1)(tailwindcss@4.1.15): dependencies: - tailwindcss: 4.1.14 + tailwindcss: 4.1.15 optionalDependencies: tailwind-merge: 3.3.1 tailwindcss@4.1.14: {} + tailwindcss@4.1.15: {} + tapable@2.3.0: {} tar-fs@2.1.4: @@ -14483,6 +14766,7 @@ snapshots: mkdirp-classic: 0.5.3 pump: 3.0.3 tar-stream: 2.2.0 + optional: true tar-fs@3.1.1: dependencies: @@ -14504,6 +14788,7 @@ snapshots: fs-constants: 1.0.0 inherits: 2.0.4 readable-stream: 3.6.2 + optional: true tar-stream@3.1.7: dependencies: @@ -14596,6 +14881,7 @@ snapshots: tunnel-agent@0.6.0: dependencies: safe-buffer: 5.2.1 + optional: true type-check@0.4.0: dependencies: @@ -14854,7 +15140,7 @@ snapshots: '@unrs/resolver-binding-win32-ia32-msvc': 1.11.1 '@unrs/resolver-binding-win32-x64-msvc': 1.11.1 - unstorage@1.17.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1): + unstorage@1.17.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1): dependencies: anymatch: 3.1.3 chokidar: 4.0.3 @@ -14867,7 +15153,7 @@ snapshots: optionalDependencies: '@vercel/blob': 2.0.0 aws4fetch: 1.0.20 - db0: 0.3.4(@electric-sql/pglite@0.3.11)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)) + db0: 0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)) ioredis: 5.8.1 untun@0.1.3: @@ -15180,6 +15466,8 @@ snapshots: web-namespaces@2.0.1: {} + web-streams-polyfill@3.3.3: {} + webidl-conversions@3.0.1: {} webpack-virtual-modules@0.6.2: {} @@ -15225,7 +15513,8 @@ snapshots: string-width: 5.1.2 strip-ansi: 7.1.2 - wrappy@1.0.2: {} + wrappy@1.0.2: + optional: true ws@8.17.1: {} diff --git a/src/features.ts b/src/features.ts index 31eb677d..9b758495 100644 --- a/src/features.ts +++ b/src/features.ts @@ -1,5 +1,6 @@ import type { Nuxt } from '@nuxt/schema' import { logger } from '@nuxt/kit' +import type { DatabaseConfig } from './types/module' const log = logger.withTag('nuxt:hub') @@ -7,7 +8,7 @@ export { setupAI } from './features/ai' export { setupBase } from './features/base' export { setupBlob } from './features/blob' export { setupCache } from './features/cache' -export { setupDatabase } from './features/database' +export { setupDatabase, resolveDatabaseConfig } from './features/database' export { setupKV } from './features/kv' export { setupOpenAPI } from './features/openapi' @@ -19,11 +20,17 @@ export function logWhenReady(nuxt: Nuxt, message: string, type: 'info' | 'warn' } } +export interface ResolvedDatabaseConfig { + dialect: 'sqlite' | 'postgresql' | 'mysql' + driver: string + connection: Record +} + export interface HubConfig { ai?: 'vercel' | 'cloudflare' blob?: boolean cache?: boolean - database?: boolean | 'postgresql' | 'sqlite' | 'mysql' + database?: boolean | 'postgresql' | 'sqlite' | 'mysql' | DatabaseConfig | ResolvedDatabaseConfig kv?: boolean dir?: string diff --git a/src/features/database.ts b/src/features/database.ts index a3a7a6bc..c44b9a68 100644 --- a/src/features/database.ts +++ b/src/features/database.ts @@ -1,147 +1,120 @@ -import { mkdir, writeFile } from 'node:fs/promises' +import { mkdir } from 'node:fs/promises' import { defu } from 'defu' import { join } from 'pathe' -import { addServerImportsDir, addServerScanDir, addServerTemplate, addTemplate, addTypeTemplate, logger } from '@nuxt/kit' +import { addServerImportsDir, addServerScanDir, addTemplate, addTypeTemplate, logger } from '@nuxt/kit' import { copyDatabaseMigrationsToHubDir, copyDatabaseQueriesToHubDir } from '../runtime/database/server/utils/migrations/helpers' import { logWhenReady } from '../features' import { resolve } from '../module' import type { Nuxt } from '@nuxt/schema' -import type { NitroOptions, Nitro } from 'nitropack' -import type { ConnectorName } from 'db0' -import type { HubConfig } from '../features' +import type { Nitro } from 'nitropack' +import type { HubConfig, ResolvedDatabaseConfig } from '../features' +import type { DatabaseConfig } from '../types/module' const log = logger.withTag('nuxt:hub') -export async function setupDatabase(nuxt: Nuxt, hub: HubConfig, deps: Record) { - // Configure dev storage - if (typeof hub.database === 'string' && !['postgresql', 'sqlite', 'mysql'].includes(hub.database)) { - return logWhenReady(nuxt, `Unknown database dialect set in hub.database: ${hub.database}`, 'error') +/** + * Resolve database configuration from string or object format + */ +export function resolveDatabaseConfig(database: string | DatabaseConfig, isDev: boolean): ResolvedDatabaseConfig { + let dialect: 'sqlite' | 'postgresql' | 'mysql' + let connection: Record = {} + let driver: string | undefined + + // If it's a string, parse it and auto-detect connection + if (typeof database === 'string') { + dialect = database as 'sqlite' | 'postgresql' | 'mysql' + + // Auto-detect connection based on environment variables + if (dialect === 'sqlite') { + if (process.env.TURSO_DATABASE_URL && process.env.TURSO_AUTH_TOKEN) { + connection = { + url: process.env.TURSO_DATABASE_URL, + authToken: process.env.TURSO_AUTH_TOKEN + } + } else { + // Local SQLite - connection will be set later based on hub.dir + connection = {} + } + } else if (dialect === 'postgresql') { + const url = process.env.DATABASE_URL || process.env.POSTGRES_URL || process.env.POSTGRESQL_URL + if (url) { + connection = { connectionString: url } + } else { + // PGlite - connection will be set later based on hub.dir + connection = {} + } + } else if (dialect === 'mysql') { + connection = { url: process.env.DATABASE_URL || process.env.MYSQL_URL } + if (!connection.url) { + throw new Error('MySQL requires DATABASE_URL or MYSQL_URL environment variable') + } + } + } else { + // It's a DatabaseConfig object + dialect = database.dialect + connection = { ...database.connection } + driver = database.driver // Use user-specified driver if provided } - let dialect: string - const productionDriver = nuxt.options.nitro.database?.db?.connector as ConnectorName - const isDialectConfigured = typeof hub.database === 'string' && (['postgresql', 'sqlite', 'mysql'].includes(hub.database)) - if (isDialectConfigured) { - dialect = hub.database as string - } else { - // Infer dialect from production database driver - // Map connectors to dialects based on the mappings: - // "postgresql" -> "postgresql", pglite - // "sqlite" -> "better-sqlite3", bun-sqlite, bun, node-sqlite, sqlite3 - // "mysql" -> mysql2 - // "libsql" -> libsql-core, libsql-http, libsql-node, libsql-web - if (productionDriver === 'postgresql' || productionDriver === 'pglite') { - dialect = 'postgresql' - } else if (['better-sqlite3', 'bun-sqlite', 'bun', 'node-sqlite', 'sqlite3'].includes(productionDriver)) { - dialect = 'sqlite' - } else if (productionDriver === 'mysql2') { - dialect = 'mysql' - } else if (['libsql', 'libsql-core', 'libsql-http', 'libsql-node', 'libsql-web'].includes(productionDriver)) { - // NOTE: libSQL implements additional functionality beyond sqlite, but users can manually configure a libsql database within Nitro if they require them - dialect = 'sqlite' // libsql is SQLite-compatible + // Auto-detect driver if not explicitly provided + if (!driver) { + if (dialect === 'sqlite') { + driver = 'libsql' + } else if (dialect === 'postgresql') { + if (connection.connectionString || connection.url || connection.host) { + driver = 'node-postgres' + } else { + driver = 'pglite' + } } else { - return logWhenReady(nuxt, 'Please specify a database dialect in `hub.database: \'\'` or configure `nitro.database.db` within `nuxt.config.ts`. Learn more at https://hub.nuxt.com/docs/features/database.', 'error') + driver = 'mysql2' } } - // Check if the configured dialect matches the production driver - if (isDialectConfigured && productionDriver) { - const dialectMatchesDriver = ( - (dialect === 'postgresql' && (productionDriver === 'postgresql' || productionDriver === 'pglite')) - || (dialect === 'sqlite' && ['better-sqlite3', 'bun-sqlite', 'bun', 'node-sqlite', 'sqlite3', 'libsql', 'libsql-core', 'libsql-http', 'libsql-node', 'libsql-web'].includes(productionDriver)) - || (dialect === 'mysql' && productionDriver === 'mysql2') - ) - - if (!dialectMatchesDriver) { - // Infer the dialect from the production driver for the error message - let inferredDialect: string - if (productionDriver === 'postgresql' || productionDriver === 'pglite') { - inferredDialect = 'postgresql' - } else if (['better-sqlite3', 'bun-sqlite', 'bun', 'node-sqlite', 'sqlite3', 'libsql', 'libsql-core', 'libsql-http', 'libsql-node', 'libsql-web'].includes(productionDriver)) { - inferredDialect = 'sqlite' - } else if (productionDriver === 'mysql2') { - inferredDialect = 'mysql' - } else { - inferredDialect = 'unknown' - } + return { dialect, driver, connection } +} - logWhenReady(nuxt, `Database dialect mismatch: \`hub.database\` is set to \`${dialect}\` but \`nitro.database.db\` is \`${inferredDialect}\` (\`${productionDriver}\`). Set \`hub.database\` to \`'${inferredDialect}'\` in your \`nuxt.config.ts\`.`, 'warn') - } +export async function setupDatabase(nuxt: Nuxt, hub: HubConfig, deps: Record) { + // Database config is already resolved in module.ts + const dbConfig = hub.database + if (!dbConfig || typeof dbConfig === 'boolean' || typeof dbConfig === 'string' || !('driver' in dbConfig)) { + throw new Error('Database configuration should be resolved before setupDatabase is called') } - // Configure dev database based on dialect - let devDatabaseConfig: NitroOptions['database']['default'] - - if (dialect === 'postgresql') { - if (process.env.POSTGRES_URL || process.env.POSTGRESQL_URL || process.env.DATABASE_URL) { - // Use postgresql if env variable is set - const setEnvVarName = process.env.POSTGRES_URL ? 'POSTGRES_URL' : process.env.POSTGRESQL_URL ? 'POSTGRESQL_URL' : 'DATABASE_URL' - logWhenReady(nuxt, `\`hubDatabase()\` configured with \`PostgreSQL\` using provided \`${setEnvVarName}\``) - devDatabaseConfig = { - connector: 'postgresql', - options: { - url: process.env.POSTGRES_URL || process.env.POSTGRESQL_URL || process.env.DATABASE_URL - } - } - } else { - // Use pglite if env variable not provided - logWhenReady(nuxt, '`hubDatabase()` configured with `PGlite` during local development') - devDatabaseConfig = { - connector: 'pglite', - options: { - dataDir: join(hub.dir!, 'database/pglite') - } - } - await mkdir(join(hub.dir!, 'database/pglite'), { recursive: true }) - } - } else if (dialect === 'sqlite') { - if (process.env.TURSO_DATABASE_URL && process.env.TURSO_AUTH_TOKEN) { - logWhenReady(nuxt, `\`hubDatabase()\` configured with \`SQLite\` and \`Turso\` using provided \`TURSO_DATABASE_URL\` and \`TURSO_AUTH_TOKEN\``) - devDatabaseConfig = { - connector: 'libsql-node', - options: { - url: process.env.TURSO_DATABASE_URL, - authToken: process.env.TURSO_AUTH_TOKEN - } - } - } else { - logWhenReady(nuxt, '`hubDatabase()` configured with `SQLite` during local development') - devDatabaseConfig = { - connector: 'better-sqlite3', - options: { - path: join(hub.dir!, 'database/sqlite/db.sqlite3') - } - } - await mkdir(join(hub.dir!, 'database/sqlite'), { recursive: true }) - } - } else if (dialect === 'mysql') { - if (!nuxt.options.nitro.devDatabase?.db?.connector) { - logWhenReady(nuxt, '`hubDatabase()` configured with `MySQL` during local development is not supported yet. Please manually configure your development database in `nitro.devDatabase.db` in `nuxt.config.ts`. Learn more at https://hub.nuxt.com/docs/features/database.', 'warn') + const { driver, connection } = dbConfig as ResolvedDatabaseConfig + + // Set up local storage paths for local databases + if (driver === 'libsql' && !connection.url) { + connection.url = `file:${join(hub.dir!, 'database/sqlite.db')}` + await mkdir(join(hub.dir!, 'database/sqlite'), { recursive: true }) + logWhenReady(nuxt, '`drizzle()` configured with `SQLite` during local development') + } else if (driver === 'libsql' && connection.url && connection.authToken) { + logWhenReady(nuxt, `\`drizzle()\` configured with \`Turso\` using provided \`TURSO_DATABASE_URL\` and \`TURSO_AUTH_TOKEN\``) + } else if (driver === 'pglite' && !connection.connectionString) { + connection.dataDir = join(hub.dir!, 'database/pglite') + await mkdir(join(hub.dir!, 'database/pglite'), { recursive: true }) + logWhenReady(nuxt, '`drizzle()` configured with `PGlite` during local development') + } else if (driver === 'node-postgres' && connection.connectionString) { + const envVarName = process.env.POSTGRES_URL ? 'POSTGRES_URL' : process.env.POSTGRESQL_URL ? 'POSTGRESQL_URL' : 'DATABASE_URL' + logWhenReady(nuxt, `\`drizzle()\` configured with \`PostgreSQL\` using provided \`${envVarName}\``) + } else if (driver === 'mysql2') { + if (!connection.url) { + logWhenReady(nuxt, '`drizzle()` configured with `MySQL` requires DATABASE_URL or MYSQL_URL environment variable', 'warn') } } - nuxt.options.nitro.devDatabase ||= {} - nuxt.options.nitro.devDatabase.db = defu(nuxt.options.nitro.devDatabase.db, devDatabaseConfig!) as NitroOptions['database']['default'] - // Verify development database dependencies are installed - const developmentDriver = nuxt.options.nitro.devDatabase?.db?.connector as ConnectorName - if (developmentDriver === 'postgresql' && !deps.pg) { + if (driver === 'node-postgres' && !deps.pg) { logWhenReady(nuxt, 'Please run `npx nypm i pg` to use PostgreSQL as database.', 'error') - } else if (developmentDriver === 'pglite' && !deps['@electric-sql/pglite']) { + } else if (driver === 'pglite' && !deps['@electric-sql/pglite']) { logWhenReady(nuxt, 'Please run `npx nypm i @electric-sql/pglite` to use PGlite as database.', 'error') - } else if (developmentDriver === 'mysql2' && !deps.mysql2) { + } else if (driver === 'mysql2' && !deps.mysql2) { logWhenReady(nuxt, 'Please run `npx nypm i mysql2` to use MySQL as database.', 'error') - } else if (developmentDriver === 'better-sqlite3' && !deps['better-sqlite3']) { - logWhenReady(nuxt, 'Please run `npx nypm i better-sqlite3` to use SQLite as database.', 'error') - } else if (developmentDriver.includes('libsql') && !deps['@libsql/client']) { - logWhenReady(nuxt, 'Please run `npx nypm i @libsql/client` to use libSQL as database.', 'error') + } else if (driver === 'libsql' && !deps['@libsql/client']) { + logWhenReady(nuxt, 'Please run `npx nypm i @libsql/client` to use Turso as database.', 'error') } - // Enable Nitro database - nuxt.options.nitro.experimental ||= {} - nuxt.options.nitro.experimental.database = true - // Add Server scanning addServerScanDir(resolve('runtime/database/server')) addServerImportsDir(resolve('runtime/database/server/utils')) @@ -152,91 +125,64 @@ export async function setupDatabase(nuxt: Nuxt, hub: HubConfig, deps: Record = { - postgresql: 'node-postgres', - pglite: 'pg-proxy', - mysql2: 'mysql2', - planetscale: 'planetscale-serverless', - 'better-sqlite3': 'better-sqlite3', - 'bun-sqlite': 'bun-sqlite', - bun: 'bun-sqlite', - sqlite3: 'better-sqlite3', - libsql: 'libsql/node', - 'libsql-core': 'libsql', - 'libsql-http': 'libsql/http', - 'libsql-node': 'libsql/node', - 'libsql-web': 'libsql/web', - 'cloudflare-d1': 'd1' - // unsupported: sqlite & node-sqlite - } + const drizzleOrmTypes = `import type { DrizzleConfig } from 'drizzle-orm' +import { drizzle as drizzleCore } from 'drizzle-orm/${driver}' - // node-postgres requires connectionString instead of url - let connectionConfig = dbConfig - if (connector === 'postgresql' && dbConfig?.url) { - connectionConfig = { connectionString: dbConfig.url, ...dbConfig.options } - } else if (connector === 'better-sqlite3' && dbConfig?.path) { - connectionConfig = { source: dbConfig.path, ...dbConfig.options } - } +declare module '#hub/database' { + export function drizzle = Record>(options?: DrizzleConfig): ReturnType> +}` - let drizzleOrmContent = `import { drizzle } from 'drizzle-orm/${db0ToDrizzle[connector]}' + // Generate simplified drizzle() implementation + let drizzleOrmContent = '' -export function hubDrizzle(options) { - return drizzle({ - ...options, - connection: ${JSON.stringify(connectionConfig)} - }) -}` - const drizzleOrmTypes = `import type { DrizzleConfig } from 'drizzle-orm' -import { drizzle } from 'drizzle-orm/${db0ToDrizzle[connector]}' + if (driver === 'd1') { + // D1 requires binding from environment + drizzleOrmContent = `import { drizzle as drizzleCore } from 'drizzle-orm/d1' + +let _drizzle = null -declare module '#hub/drizzle-orm' { - export function hubDrizzle = Record>(options?: DrizzleConfig): ReturnType> +export function drizzle(options) { + if (_drizzle) return _drizzle + const binding = process.env.DB || globalThis.DB + if (!binding) { + throw new Error('D1 binding "DB" not found') + } + _drizzle = drizzleCore(binding, options) + return _drizzle }` + } else { + // All other drivers support connection config + drizzleOrmContent = `import { drizzle as drizzleCore } from 'drizzle-orm/${driver}' - if (connector === 'pglite') { - drizzleOrmContent = `import { drizzle } from 'drizzle-orm/pg-proxy' +let _drizzle = null -export function hubDrizzle(options) { - return drizzle(async (sql, params, method) => { - try { - const rows = await $fetch('/api/_hub/database/query', { method: 'POST', body: { sql, params, method } }) - return { rows } - } catch (e) { - return { rows: [] } - } - }, { - ...options, +export function drizzle(options) { + if (_drizzle) return _drizzle + _drizzle = drizzleCore({ + connection: ${JSON.stringify(connection)}, + ...options }) + return _drizzle }` } - - // addServerTemplate({ - // filename: '#hub-drizzle-orm.mjs', - // getContents: () => drizzleOrmContent - // }) const template = addTemplate({ - filename: 'hub/drizzle-orm.mjs', + filename: 'hub/database.mjs', getContents: () => drizzleOrmContent, write: true }) - nuxt.options.nitro.alias!['#hub/drizzle-orm'] = template.dst + nuxt.options.nitro.alias!['#hub/database'] = template.dst addTypeTemplate({ - filename: 'hub/drizzle-orm.d.ts', + filename: 'hub/database.d.ts', getContents: () => drizzleOrmTypes, }, { nitro: true }) - addServerImportsDir(resolve('runtime/database/server/drizzle-utils')) } } @@ -244,27 +190,23 @@ export async function setupProductionDatabase(nitro: Nitro, hub: HubConfig, deps const preset = nitro.options.preset if (!preset) return - // Only configure if production database connector is not already set - if (nitro.options.database?.db?.connector) { - log.info(`\`hubDatabase()\` configured with \`${nitro.options.database.db.connector}\` driver (defined in \`nuxt.config.ts\`)`) + // Get the resolved database configuration from runtime config + const dbConfig = nitro.options.runtimeConfig?.hub?.database + if (!dbConfig || typeof dbConfig === 'boolean' || typeof dbConfig === 'string') { + log.warn('Database configuration not resolved, skipping production database setup') return } - const dialect = typeof hub.database === 'string' ? hub.database : hub.database - - let databaseConfig: NitroOptions['database']['default'] + let { dialect, driver, connection } = dbConfig + // Override driver based on preset switch (preset) { - // Does your favourite cloud provider require special configuration? Feel free to open a PR to add zero-config support for other presets case 'vercel': { - if (dialect === true || dialect === 'postgresql') { - databaseConfig = { - connector: 'postgresql', - options: { - url: process.env.POSTGRES_URL || process.env.POSTGRESQL_URL || process.env.DATABASE_URL - } - } - if (!process.env.POSTGRES_URL && !process.env.POSTGRESQL_URL && !process.env.DATABASE_URL) { + if (dialect === 'postgresql') { + if (connection.connectionString || process.env.POSTGRES_URL || process.env.POSTGRESQL_URL || process.env.DATABASE_URL) { + connection.connectionString = connection.connectionString || process.env.POSTGRES_URL || process.env.POSTGRESQL_URL || process.env.DATABASE_URL + driver = 'node-postgres' + } else { log.warn('Set POSTGRES_URL, POSTGRESQL_URL, or DATABASE_URL environment variable to configure PostgreSQL database') if (hub.applyDatabaseMigrationsDuringBuild) { hub.applyDatabaseMigrationsDuringBuild = false @@ -272,18 +214,20 @@ export async function setupProductionDatabase(nitro: Nitro, hub: HubConfig, deps } } } else if (dialect === 'mysql') { - throw new Error('MySQL connector requires manual configuration in `nitro.database.db` within `nuxt.config.ts`') + if (!connection.url && !process.env.DATABASE_URL && !process.env.MYSQL_URL) { + throw new Error('MySQL requires DATABASE_URL or MYSQL_URL environment variable') + } + connection.url = connection.url || process.env.DATABASE_URL || process.env.MYSQL_URL + driver = 'mysql2' } else if (dialect === 'sqlite') { if (process.env.TURSO_DATABASE_URL && process.env.TURSO_AUTH_TOKEN) { - databaseConfig = { - connector: 'libsql-node', - options: { - url: process.env.TURSO_DATABASE_URL, - authToken: process.env.TURSO_AUTH_TOKEN - } + connection = { + url: process.env.TURSO_DATABASE_URL, + authToken: process.env.TURSO_AUTH_TOKEN } + driver = 'libsql' } else { - throw new Error('SQLite connector requires manual configuration in `nitro.database.db` within `nuxt.config.ts` or connect a Turso database') + throw new Error('SQLite on Vercel requires Turso (TURSO_DATABASE_URL and TURSO_AUTH_TOKEN)') } } break @@ -294,54 +238,40 @@ export async function setupProductionDatabase(nitro: Nitro, hub: HubConfig, deps case 'cloudflare-pages': { nitro.options.cloudflare ||= {} - const isPages = preset === 'cloudflare-pages' - if (dialect === true || dialect === 'sqlite') { + if (dialect === 'sqlite') { if (process.env.TURSO_DATABASE_URL && process.env.TURSO_AUTH_TOKEN) { - databaseConfig = { - connector: 'libsql-web', - options: { - url: process.env.TURSO_DATABASE_URL, - authToken: process.env.TURSO_AUTH_TOKEN - } + connection = { + url: process.env.TURSO_DATABASE_URL, + authToken: process.env.TURSO_AUTH_TOKEN } + driver = 'libsql' } else { - databaseConfig = { - connector: 'cloudflare-d1', - options: { - bindingName: 'DB' - } - } - } - log.info(`Ensure a \`DB\` binding is set in your Cloudflare ${isPages ? 'Pages' : 'Workers'} configuration`) + // Use D1 + driver = 'd1' + connection = { bindingName: 'DB' } - nitro.options.cloudflare.wrangler ||= {} - nitro.options.cloudflare.wrangler.d1_databases ||= [] + log.info(`Ensure a \`DB\` binding is set in your Cloudflare ${preset === 'cloudflare-pages' ? 'Pages' : 'Workers'} configuration`) - let dbBinding = nitro.options.cloudflare.wrangler.d1_databases.find(db => db.binding === 'DB') - if (!dbBinding) { - dbBinding = { binding: 'DB' } - nitro.options.cloudflare.wrangler.d1_databases.push(dbBinding) - } + nitro.options.cloudflare.wrangler ||= {} + nitro.options.cloudflare.wrangler.d1_databases ||= [] - dbBinding.migrations_table ||= '_hub_migrations' - dbBinding.migrations_dir ||= 'migrations' - } else if (dialect === 'postgresql') { - databaseConfig = { - connector: 'cloudflare-hyperdrive-postgresql', - options: { - bindingName: 'DB' + let dbBinding = nitro.options.cloudflare.wrangler.d1_databases.find(db => db.binding === 'DB') + if (!dbBinding) { + dbBinding = { binding: 'DB' } + nitro.options.cloudflare.wrangler.d1_databases.push(dbBinding) } - } - log.info(`Ensure a \`DB\` binding is set in your Cloudflare ${isPages ? 'Pages' : 'Workers'} configuration`) - } else if (dialect === 'mysql') { - databaseConfig = { - connector: 'cloudflare-hyperdrive-mysql', - options: { - bindingName: 'DB' - } + dbBinding.migrations_table ||= '_hub_migrations' + dbBinding.migrations_dir ||= 'migrations' } - log.info(`Ensure a \`DB\` binding is set in your Cloudflare ${isPages ? 'Pages' : 'Workers'} configuration`) + } else if (dialect === 'postgresql') { + driver = 'cloudflare-hyperdrive-postgresql' + connection = { bindingName: 'DB' } + log.info(`Ensure a \`DB\` Hyperdrive binding is set in your Cloudflare ${preset === 'cloudflare-pages' ? 'Pages' : 'Workers'} configuration`) + } else if (dialect === 'mysql') { + driver = 'cloudflare-hyperdrive-mysql' + connection = { bindingName: 'DB' } + log.info(`Ensure a \`DB\` Hyperdrive binding is set in your Cloudflare ${preset === 'cloudflare-pages' ? 'Pages' : 'Workers'} configuration`) } // TODO: D1 migrations via wrangler migrations dir @@ -353,16 +283,12 @@ export async function setupProductionDatabase(nitro: Nitro, hub: HubConfig, deps } default: { - if (dialect === true) { - throw new Error('Database dialect must be set in `hub.database`, or a production database connector must be set in `nitro.database.db` within `nuxt.config.ts`') - } else if (dialect === 'postgresql') { - databaseConfig = { - connector: 'postgresql', - options: { - url: process.env.POSTGRES_URL || process.env.POSTGRESQL_URL || process.env.DATABASE_URL - } - } - if (!process.env.POSTGRES_URL && !process.env.POSTGRESQL_URL && !process.env.DATABASE_URL) { + if (dialect === 'postgresql') { + const url = connection.connectionString || process.env.POSTGRES_URL || process.env.POSTGRESQL_URL || process.env.DATABASE_URL + if (url) { + connection.connectionString = url + driver = 'node-postgres' + } else { log.info('Set `POSTGRES_URL`, `POSTGRESQL_URL`, or `DATABASE_URL` environment variable to configure PostgreSQL database') if (hub.applyDatabaseMigrationsDuringBuild) { hub.applyDatabaseMigrationsDuringBuild = false @@ -370,34 +296,36 @@ export async function setupProductionDatabase(nitro: Nitro, hub: HubConfig, deps } } } else if (dialect === 'mysql') { - throw new Error('MySQL connector requires manual configuration in `nitro.database.db` within `nuxt.config.ts`') + const url = connection.url || process.env.DATABASE_URL || process.env.MYSQL_URL + if (!url) { + throw new Error('MySQL requires DATABASE_URL or MYSQL_URL environment variable') + } + connection.url = url + driver = 'mysql2' } else if (dialect === 'sqlite') { if (process.env.TURSO_DATABASE_URL && process.env.TURSO_AUTH_TOKEN) { - databaseConfig = { - connector: 'libsql-node', - options: { - url: process.env.TURSO_DATABASE_URL, - authToken: process.env.TURSO_AUTH_TOKEN - } + connection = { + url: process.env.TURSO_DATABASE_URL, + authToken: process.env.TURSO_AUTH_TOKEN } + driver = 'libsql' } else { - databaseConfig = { - connector: 'sqlite', - options: { - path: '.data/database/sqlite/db.sqlite3' - } - } + connection.url = 'file:.data/database/sqlite.db' + driver = 'libsql' } } break } } - if (databaseConfig!) { - // set connector - // @ts-expect-error temporarily set to empty object - nitro.options.database ||= {} - nitro.options.database.db = defu(nitro.options.database?.db, databaseConfig) as any - log.info(`\`hubDatabase()\` configured with \`${databaseConfig.connector}\` driver`) + // Store the resolved production configuration + nitro.options.runtimeConfig = nitro.options.runtimeConfig || {} + nitro.options.runtimeConfig.hub = nitro.options.runtimeConfig.hub || {} + nitro.options.runtimeConfig.hub.database = { + dialect, + driver, + connection } + + log.info(`\`drizzle()\` configured with \`${driver}\` driver for production`) } diff --git a/src/module.ts b/src/module.ts index b02783ab..da65faf7 100644 --- a/src/module.ts +++ b/src/module.ts @@ -5,8 +5,8 @@ import { defu } from 'defu' import { findWorkspaceDir, readPackageJSON } from 'pkg-types' import type { Nuxt } from '@nuxt/schema' import { version } from '../package.json' -import { setupAI, setupCache, setupOpenAPI, setupDatabase, setupKV, setupBase, setupBlob, type HubConfig } from './features' -import type { ModuleOptions } from './types/module' +import { setupAI, setupCache, setupOpenAPI, setupDatabase, setupKV, setupBase, setupBlob, resolveDatabaseConfig, type HubConfig } from './features' +import type { ModuleOptions, DatabaseConfig } from './types/module' import { addBuildHooks } from './utils/build' export * from './types' @@ -51,7 +51,12 @@ export default defineNuxtModule({ applyDatabaseMigrationsDuringBuild: true }) - runtimeConfig.hub = hub + // Resolve database configuration if enabled + if (hub.database) { + hub.database = resolveDatabaseConfig(hub.database as string | DatabaseConfig, nuxt.options.dev) + } + + runtimeConfig.hub = hub as any runtimeConfig.public.hub = {} if (nuxt.options.nitro.preset?.includes('cloudflare')) { @@ -74,7 +79,7 @@ export default defineNuxtModule({ return } - addBuildHooks(nuxt, hub as HubConfig) + addBuildHooks(nuxt, hub as HubConfig, deps) // Enable Async Local Storage nuxt.options.nitro.experimental = nuxt.options.nitro.experimental || {} diff --git a/src/runtime/database/server/api/_hub/database/query.post.dev.ts b/src/runtime/database/server/api/_hub/database/query.post.dev.ts index f9570df8..eaedbab4 100644 --- a/src/runtime/database/server/api/_hub/database/query.post.dev.ts +++ b/src/runtime/database/server/api/_hub/database/query.post.dev.ts @@ -1,5 +1,5 @@ import { eventHandler, createError, readValidatedBody } from 'h3' -import { useDatabase } from '#imports' +import { sql } from 'drizzle-orm' import z from 'zod' const schema = z.object({ @@ -9,20 +9,27 @@ const schema = z.object({ }) export default eventHandler(async (event) => { - const { sql, params, method } = await readValidatedBody(event, schema.parse) - const sqlBody = sql.replace(/;/g, '') + const { sql: sqlQuery, params, method } = await readValidatedBody(event, schema.parse) + const sqlBody = sqlQuery.replace(/;/g, '') try { - const client = useDatabase('db') - const result = await client.prepare(sqlBody).bind(...params)[method === 'run' ? 'run' : method === 'get' ? 'get' : 'all']() + // @ts-expect-error - drizzle is generated dynamically + const { drizzle } = await import('#hub/database') + const db = drizzle() - // convert methods except "get" into string[][] - see https://orm.drizzle.team/docs/connect-drizzle-proxy + // Use Drizzle's sql.raw to execute the query + const result = await db.execute(sql.raw(sqlBody)) + + // Handle different response formats based on method if (method === 'get') { - return Object.values(result) + // Return first row as array of values + const row = result.rows?.[0] || result[0] + return row ? Object.values(row) : [] } - return result.map((result: any) => { - return Object.values(result) - }) + + // For 'all', 'run', 'values' - return rows as array of arrays + const rows = result.rows || result || [] + return rows.map((row: any) => Object.values(row)) } catch (e: any) { console.error(`[hub:database]: ${e.message}`) return createError({ diff --git a/src/runtime/database/server/drizzle-utils/drizzle.ts b/src/runtime/database/server/drizzle-utils/drizzle.ts deleted file mode 100644 index 1188ef1d..00000000 --- a/src/runtime/database/server/drizzle-utils/drizzle.ts +++ /dev/null @@ -1 +0,0 @@ -export { hubDrizzle } from '#hub/drizzle-orm' diff --git a/src/runtime/database/server/plugins/migrations.dev.ts b/src/runtime/database/server/plugins/migrations.dev.ts index a68e9083..c8687e24 100644 --- a/src/runtime/database/server/plugins/migrations.dev.ts +++ b/src/runtime/database/server/plugins/migrations.dev.ts @@ -1,16 +1,24 @@ -import type { NitroApp } from 'nitropack/types' import { applyDatabaseMigrations, applyDatabaseQueries } from '../utils/migrations/migrations' -import { useRuntimeConfig, defineNitroPlugin, useDatabase } from '#imports' +// @ts-expect-error - Generated at runtime +import { drizzle } from '#hub/database' -export default defineNitroPlugin(async (nitroApp: NitroApp) => { +// @ts-expect-error - Nitro global +export default defineNitroPlugin(async (nitroApp: any) => { if (!import.meta.dev) return + // @ts-expect-error - Nitro global const hub = useRuntimeConfig().hub if (!hub.database) return - const db = useDatabase('db') - await applyDatabaseMigrations(hub, db) - await applyDatabaseQueries(hub, db) + const dbConfig = hub.database + if (!dbConfig || typeof dbConfig === 'boolean' || typeof dbConfig === 'string') { + console.error('Database configuration not resolved properly') + return + } + + const db = drizzle() + await applyDatabaseMigrations(hub, db, dbConfig.dialect) + await applyDatabaseQueries(hub, db, dbConfig.dialect) nitroApp.hooks.callHookParallel('hub:database:migrations:done') }) diff --git a/src/runtime/database/server/utils/database.ts b/src/runtime/database/server/utils/database.ts deleted file mode 100644 index fbed2b74..00000000 --- a/src/runtime/database/server/utils/database.ts +++ /dev/null @@ -1,152 +0,0 @@ -import type { ExecResult, Database, Statement as DB0Statement, PreparedStatement as DB0PreparedStatement, Primitive } from 'db0' -import { requireNuxtHubFeature } from '../../../utils/features' -import { useDatabase } from '#imports' - -import type { HubDatabase, D1PreparedStatement, D1AllResult, D1RunResult, D1Statement } from '../../../../types' - -let _db: HubDatabase - -// Wrapper functions to create D1-compatible interfaces since db0 differs very slightly -function createD1PreparedStatement(preparedStmt: DB0PreparedStatement, originalStmt?: any): D1PreparedStatement { - const statement: D1PreparedStatement = { - bind(...params: Primitive[]): D1PreparedStatement { - return createD1PreparedStatement(preparedStmt.bind(...params), originalStmt) - }, - // adds results object to all() - async all(): Promise { - const results = await preparedStmt.all() - return { - success: true, - meta: {}, - results: results as any[] - } - }, - async run(): Promise { - return preparedStmt.run() - }, - // changes db0 .get() to .first() - first() { - return preparedStmt.get() - } - } - - // Store reference to original statement for batch operations - if (originalStmt) { - ;(statement as any)._originalStmt = originalStmt - } - - return statement -} - -function createD1Statement(stmt: DB0Statement, originalStmt?: any): D1Statement { - return { - bind(...params: Primitive[]): D1PreparedStatement { - return createD1PreparedStatement(stmt.bind(...params), originalStmt) - }, - async all(...params: Primitive[]): Promise { - const results = await stmt.all(...params) - return { - success: true, - meta: {}, - results: results as any[] - } - }, - async run(...params: Primitive[]): Promise { - return stmt.run(...params) - }, - // db0 get() method - async get(...params: Primitive[]): Promise { - return stmt.get(...params) - }, - // D1 first() method (alias for get()) - async first(...params: Primitive[]): Promise { - return stmt.get(...params) - } - } -} - -function createD1CompatibleDatabase(db: Database): HubDatabase { - return { - dialect: db.dialect, - exec(sql: string): Promise { - return db.exec(sql) - }, - prepare(sql: string): D1Statement { - return createD1Statement(db.prepare(sql)) - }, - sql(strings: TemplateStringsArray, ...values: Primitive[]): Promise { - return db.sql(strings, ...values) - }, - getInstance(): Promise { - return db.getInstance() - }, - async batch(statements: D1PreparedStatement[]): Promise { - // Try to detect the actual driver type and use native batch functionality - try { - const instance = await db.getInstance() - - // Check if this is a D1 database by looking for the batch method - if (instance && typeof instance === 'object' && 'batch' in instance && typeof instance.batch === 'function') { - // Use native D1 batch functionality - const d1Statements = statements.map((stmt) => { - // Extract the original prepared statement from our wrapper - // This is a bit hacky but necessary to get the underlying D1 prepared statement - return (stmt as any)._originalStmt || stmt - }) - const results = await (instance as any).batch(d1Statements) - return results.map((result: any) => ({ - success: true, - meta: result.meta || {}, - results: result.results || [] - })) - } - } catch (error) { - // Fall through to custom implementation if D1 batch fails - } - - // For SQLite (better-sqlite3), PostgreSQL, and PGlite - // we'll fall through to sequential execution to avoid complexity - // TODO: Implement proper batch/transaction support in db0 - - // Fallback: execute statements sequentially - const results: D1AllResult[] = [] - for (const stmt of statements) { - try { - const result = await stmt.all() - results.push(result) - } catch (error: any) { - // If all() fails (for INSERT/UPDATE/DELETE), use run() - if (error?.message?.includes('does not return data')) { - const runResult = await stmt.run() - results.push({ - success: runResult.success, - meta: {}, - results: [] - }) - } else { - throw error - } - } - } - return results - } - } -} - -/** - * Access the NuxtHub database. - * - * @deprecated Use `useDatabase('db')` instead. - * @see https://hub.nuxt.com/docs/features/database - */ -export function hubDatabase(): HubDatabase { - requireNuxtHubFeature('database') - - if (_db) { - return _db - } - const db = useDatabase('db') as Database - - _db = createD1CompatibleDatabase(db) - return _db -} diff --git a/src/runtime/database/server/utils/migrations/helpers.ts b/src/runtime/database/server/utils/migrations/helpers.ts index 5be493b8..39da6263 100644 --- a/src/runtime/database/server/utils/migrations/helpers.ts +++ b/src/runtime/database/server/utils/migrations/helpers.ts @@ -37,12 +37,19 @@ export function getMigrationMetadata(filename: string): { filename: string, name export async function getDatabaseMigrationFiles(hub: HubConfig) { const storage = useDatabaseMigrationsStorage(hub) + // Get database dialect from hub config + const dialect = typeof hub.database === 'string' + ? hub.database + : (typeof hub.database === 'object' && hub.database !== null && 'dialect' in hub.database) + ? hub.database.dialect + : undefined + // Get migrations and exclude if dialect specified but not the current database dialect - const migrationsFiles = (await storage.getKeys()).map(file => getMigrationMetadata(file)).filter(migration => migration.dialect === hub.database || !migration.dialect) + const migrationsFiles = (await storage.getKeys()).map(file => getMigrationMetadata(file)).filter(migration => migration.dialect === dialect || !migration.dialect) return migrationsFiles.filter(migration => { // if generic SQL migration file, exclude it if same migration name for current database dialect exists - if (!migration.dialect && migrationsFiles.findIndex(m => m.name === migration.name && m.dialect === hub.database) !== -1) { + if (!migration.dialect && migrationsFiles.findIndex(m => m.name === migration.name && m.dialect === dialect) !== -1) { return false } return true @@ -122,11 +129,18 @@ export function useDatabaseQueriesStorage(hub: HubConfig) { export async function getDatabaseQueryFiles(hub: HubConfig) { const storage = useDatabaseQueriesStorage(hub) - const queriesFiles = (await storage.getKeys()).map(file => getMigrationMetadata(file)).filter(query => query.dialect === hub.database || !query.dialect) + // Get database dialect from hub config + const dialect = typeof hub.database === 'string' + ? hub.database + : (typeof hub.database === 'object' && hub.database !== null && 'dialect' in hub.database) + ? hub.database.dialect + : undefined + + const queriesFiles = (await storage.getKeys()).map(file => getMigrationMetadata(file)).filter(query => query.dialect === dialect || !query.dialect) return queriesFiles.filter(query => { // if generic SQL query file, exclude it if same query name for current database dialect exists - if (!query.dialect && queriesFiles.findIndex(q => q.name === query.name && q.dialect === hub.database) !== -1) { + if (!query.dialect && queriesFiles.findIndex(q => q.name === query.name && q.dialect === dialect) !== -1) { return false } return true diff --git a/src/runtime/database/server/utils/migrations/migrations.ts b/src/runtime/database/server/utils/migrations/migrations.ts index 6ca41ce6..0f967a08 100644 --- a/src/runtime/database/server/utils/migrations/migrations.ts +++ b/src/runtime/database/server/utils/migrations/migrations.ts @@ -1,8 +1,8 @@ import { consola } from 'consola' import { join, relative } from 'pathe' +import { sql } from 'drizzle-orm' import type { HubConfig } from '../../../../../features' import { AppliedDatabaseMigrationsQuery, getCreateMigrationsTableQuery, getDatabaseMigrationFiles, getDatabaseQueryFiles, splitSqlQueries, useDatabaseMigrationsStorage, useDatabaseQueriesStorage } from './helpers' -import type { Database } from 'db0' const log = consola.withTag('nuxt:hub') @@ -10,21 +10,26 @@ function getRelativePath(fullPath: string) { return relative(process.cwd(), fullPath) } -export async function applyDatabaseMigrations(hub: HubConfig, db: Database) { +export async function applyDatabaseMigrations(hub: HubConfig, db: any, dialect: 'sqlite' | 'postgresql' | 'mysql') { const migrationsStorage = useDatabaseMigrationsStorage(hub) + const execute = dialect === 'sqlite' ? 'run' : 'execute' - const createMigrationsTableQuery = getCreateMigrationsTableQuery(db) + const createMigrationsTableQuery = getCreateMigrationsTableQuery({ dialect }) log.debug('Creating migrations table if not exists...') - await db.prepare(createMigrationsTableQuery).run() + await db[execute](sql.raw(createMigrationsTableQuery)) log.debug('Successfully created migrations table if not exists') - const appliedMigrations = await db.prepare(AppliedDatabaseMigrationsQuery).all() + const appliedMigrations = await db[execute](sql.raw(AppliedDatabaseMigrationsQuery)) + const appliedRows = appliedMigrations.rows || appliedMigrations || [] if (!import.meta.dev) { - log.info(`Found ${appliedMigrations.length} applied migration${appliedMigrations.length === 1 ? '' : 's'}`) + log.info(`Found ${appliedRows.length} applied migration${appliedRows.length === 1 ? '' : 's'}`) } const localMigrations = await getDatabaseMigrationFiles(hub) - const pendingMigrations = localMigrations.filter((migration) => !appliedMigrations.find(({ name }: any) => name === migration.name)) + const pendingMigrations = localMigrations.filter((migration) => !appliedRows.find((row: any) => { + const name = row.name || row[1] // Handle both object and array responses + return name === migration.name + })) if (!pendingMigrations.length) return log.success('Database migrations up to date') for (const migration of pendingMigrations) { @@ -36,7 +41,7 @@ export async function applyDatabaseMigrations(hub: HubConfig, db: Database) { try { log.debug(`Applying database migration \`${getRelativePath(join(hub.dir!, 'database/migrations', migration.filename))}\`...`) for (const query of queries) { - await db.prepare(query).run() + await db[execute](sql.raw(query)) } } catch (error: any) { log.error(`Failed to apply migration \`${getRelativePath(join(hub.dir!, 'database/migrations', migration.filename))}\`\n`, error?.message) @@ -50,19 +55,19 @@ export async function applyDatabaseMigrations(hub: HubConfig, db: Database) { } } -export async function applyDatabaseQueries(hub: HubConfig, db: Database) { +export async function applyDatabaseQueries(hub: HubConfig, db: any, dialect: 'sqlite' | 'postgresql' | 'mysql') { const queriesStorage = useDatabaseQueriesStorage(hub) const queriesFiles = await getDatabaseQueryFiles(hub) if (!queriesFiles.length) return for (const queryFile of queriesFiles) { - const sql = await queriesStorage.getItem(queryFile.filename) - if (!sql) continue - const queries = splitSqlQueries(sql) + const sqlQuery = await queriesStorage.getItem(queryFile.filename) + if (!sqlQuery) continue + const queries = splitSqlQueries(sqlQuery) try { log.debug(`Applying database query \`${getRelativePath(join(hub.dir!, 'database/queries', queryFile.filename))}\`...`) for (const query of queries) { - await db.prepare(query).run() + await db[dialect === 'sqlite' ? 'run' : 'execute'](sql.raw(query)) } } catch (error: any) { log.error(`Failed to apply query \`${getRelativePath(join(hub.dir!, 'database/queries', queryFile.filename))}\`\n`, error?.message) diff --git a/src/types/database.ts b/src/types/database.ts index 0d4a7037..af52c498 100644 --- a/src/types/database.ts +++ b/src/types/database.ts @@ -1,43 +1,13 @@ -import type { Database, Primitive } from 'db0' - -// D1-compatible types that wrap db0 results -export type D1RunResult = { - success: boolean -} - -export type D1AllResult = { - success: boolean - meta: object - results: any[] -} - -export type D1PreparedStatement = { - bind(...params: Primitive[]): D1PreparedStatement - all(): Promise - run(): Promise - first(): Promise -} - -export type D1Statement = { - bind(...params: Primitive[]): D1PreparedStatement - all(...params: Primitive[]): Promise - run(...params: Primitive[]): Promise - get(...params: Primitive[]): Promise - // D1-specific method (alias for get()) - first(...params: Primitive[]): Promise +// Database migration types +export interface DatabaseMigration { + name: string + filename: string + appliedAt?: Date } -// Extends db0's Database interface with D1-specific additions -type D1CompatibleDatabase = { - // db0 Database properties and methods - readonly dialect: Database['dialect'] - getInstance: Database['getInstance'] - exec: Database['exec'] - sql: Database['sql'] - // Override prepare to return D1-compatible statement - prepare(sql: string): D1Statement - // D1-specific addition - batch(statements: D1PreparedStatement[]): Promise +export interface DatabaseConnection { + dialect: 'sqlite' | 'postgresql' | 'mysql' + execute: (sql: string) => Promise + run: (sql: string) => Promise + all: (sql: string) => Promise } - -export type HubDatabase = D1CompatibleDatabase diff --git a/src/types/module.ts b/src/types/module.ts index 5bc5b97f..33301df0 100644 --- a/src/types/module.ts +++ b/src/types/module.ts @@ -1,3 +1,59 @@ +export interface DatabaseConfig { + /** + * Database dialect + */ + dialect: 'sqlite' | 'postgresql' | 'mysql' + /** + * Database driver (optional, auto-detected if not provided) + * + * SQLite drivers: 'better-sqlite3', 'libsql', 'bun-sqlite', 'd1' + * PostgreSQL drivers: 'node-postgres', 'pglite' + * MySQL drivers: 'mysql2' + */ + driver?: string + /** + * Database connection configuration + */ + connection: { + /** + * Database connection URL + */ + url?: string + /** + * Auth token (for Turso/libSQL) + */ + authToken?: string + /** + * Connection string (for PostgreSQL) + */ + connectionString?: string + /** + * Database host + */ + host?: string + /** + * Database port + */ + port?: number + /** + * Database username + */ + user?: string + /** + * Database password + */ + password?: string + /** + * Database name + */ + database?: string + /** + * Additional connection options + */ + [key: string]: any + } +} + export interface ModuleOptions { /** * Set `'vercel'` or `'cloudflare'` to enable the AI for the project. @@ -22,11 +78,12 @@ export interface ModuleOptions { cache?: boolean /** * Set to `'postgresql'`, `'sqlite'`, or `'mysql'` to use a specific database dialect with a zero-config development database. + * Or provide a DatabaseConfig object with dialect and connection details. * * @default false * @see https://hub.nuxt.com/docs/features/database */ - database?: 'postgresql' | 'sqlite' | 'mysql' | false + database?: 'postgresql' | 'sqlite' | 'mysql' | DatabaseConfig | false /** * Set `true` to enable the key-value storage for the project. * diff --git a/src/utils/database.ts b/src/utils/database.ts index a350b27b..120b46bf 100644 --- a/src/utils/database.ts +++ b/src/utils/database.ts @@ -1,7 +1,6 @@ import { cp } from 'node:fs/promises' import { logger } from '@nuxt/kit' import { resolve } from 'pathe' -import { createDatabase } from 'db0' import type { Nitro } from 'nitropack' import type { HubConfig } from '../features' @@ -10,35 +9,37 @@ import { applyDatabaseMigrations, applyDatabaseQueries } from '../runtime/databa const log = logger.withTag('nuxt:hub') /** - * Dynamically imports the correct db0 connector based on the Nitro database configuration + * Creates a Drizzle client for the given configuration */ -export async function getDb0Connector(nitro: Nitro) { - const dbConfig = nitro.options.database?.db - if (!dbConfig?.connector) { - throw new Error('No database connector configured in nitro.options.database.db') +async function createDrizzleClient(config: any) { + const { dialect, driver, connection } = config + + if (driver === 'libsql') { + const { drizzle } = await import('drizzle-orm/libsql') + // @ts-expect-error - @libsql/client is an optional dependency + const { createClient } = await import('@libsql/client') + const client = createClient(connection) + return drizzle(client) + } else if (driver === 'node-postgres') { + const { drizzle } = await import('drizzle-orm/node-postgres') + // @ts-expect-error - pg is an optional dependency + const pg = await import('pg') + const pool = new pg.Pool(connection) + return drizzle(pool) + } else if (driver === 'mysql2') { + const { drizzle } = await import('drizzle-orm/mysql2') + // @ts-expect-error - mysql2 is an optional dependency + const mysql = await import('mysql2/promise') + const pool = mysql.createPool(connection) + return drizzle(pool) + } else if (driver === 'pglite') { + const { drizzle } = await import('drizzle-orm/pglite') + const { PGlite } = await import('@electric-sql/pglite') + const client = new PGlite(connection.dataDir) + return drizzle(client) } - const connector = dbConfig.connector === 'sqlite' ? 'better-sqlite3' : dbConfig.connector - const connectorPath = `db0/connectors/${connector.replace('-', '/')}` - - try { - // Use createRequire to resolve from the consumer's context - // This ensures that dependencies like 'pg' are found in the consumer's node_modules - const { createRequire } = await import('node:module') - const require = createRequire(process.cwd() + '/package.json') - const resolvedPath = require.resolve(connectorPath) - const connectorModule = await import(resolvedPath) - return connectorModule.default || connectorModule - } catch (error) { - // Fallback: try direct import (original behavior) - try { - console.debug('Fallback to direct import of db0 connector', connectorPath) - const connectorModule = await import(connectorPath) - return connectorModule.default || connectorModule - } catch (fallbackError) { - throw new Error(`Failed to import db0 connector "${connector}" from "${connectorPath}": ${error}. Fallback also failed: ${fallbackError}`) - } - } + throw new Error(`Unsupported driver: ${driver}`) } /** @@ -89,8 +90,12 @@ export async function applyBuildTimeMigrations(nitro: Nitro, hub: HubConfig) { if (!hub.database || !hub.applyDatabaseMigrationsDuringBuild) return try { - const driver = await getDb0Connector(nitro) - const db = createDatabase(driver(nitro.options.database.db?.options)) + const dbConfig = nitro.options.runtimeConfig?.hub?.database + if (!dbConfig || typeof dbConfig === 'boolean' || typeof dbConfig === 'string') { + throw new Error('Database configuration not resolved properly') + } + + const db = await createDrizzleClient(dbConfig) const buildHubConfig = { ...hub, @@ -99,8 +104,8 @@ export async function applyBuildTimeMigrations(nitro: Nitro, hub: HubConfig) { log.info('Applying database migrations...') - await applyDatabaseMigrations(buildHubConfig, db) - await applyDatabaseQueries(buildHubConfig, db) + await applyDatabaseMigrations(buildHubConfig, db, dbConfig.dialect) + await applyDatabaseQueries(buildHubConfig, db, dbConfig.dialect) log.info('Database migrations applied successfully') } catch (error: unknown) { diff --git a/src/utils/devtools.ts b/src/utils/devtools.ts index 247cb942..656d8e37 100644 --- a/src/utils/devtools.ts +++ b/src/utils/devtools.ts @@ -1,6 +1,6 @@ import { logger } from '@nuxt/kit' import type { Nuxt } from 'nuxt/schema' -import type { HubConfig } from '../features' +import type { HubConfig, ResolvedDatabaseConfig } from '../features' import { checkPort, getPort } from 'get-port-please' import { writeFile } from 'node:fs/promises' import { detectPackageManager, dlxCommand } from 'nypm' @@ -22,57 +22,46 @@ async function launchDrizzleStudio(nuxt: Nuxt) { port = await getPort({ port: 4983 }) try { - const dbConfig = nuxt.options.nitro.devDatabase?.db - if (!dbConfig?.connector) { - throw new Error('No database configuration found. Please configure your database in nuxt.config.ts') + const dbConfig = nuxt.options.runtimeConfig?.hub?.database as unknown as ResolvedDatabaseConfig | undefined + if (!dbConfig || typeof dbConfig === 'boolean' || typeof dbConfig === 'string') { + throw new Error('Database configuration not resolved properly. Please ensure database is configured in hub.database') } // TODO: custom drizzle connector - if (dbConfig.connector === 'pglite') { + if (dbConfig.driver === 'pglite') { throw new Error('Database viewer currently does not support PGlite.') } - // Determine dialect from connector - let dialect: string - let dbCredentials: any - - if (dbConfig.connector === 'postgresql' || dbConfig.connector === 'pglite') { - dialect = 'postgresql' - if (dbConfig.connector === 'pglite') { - dbCredentials = { - url: dbConfig.options?.dataDir || './database/' - } - } else { - dbCredentials = { - url: dbConfig.options?.url - } - } - } else if (['better-sqlite3', 'bun-sqlite', 'bun', 'node-sqlite', 'sqlite3'].includes(dbConfig.connector)) { - dialect = 'sqlite' - dbCredentials = { - url: dbConfig.options?.path - } - } else if (dbConfig.connector === 'mysql2') { - dialect = 'mysql' - dbCredentials = { - url: dbConfig.options?.url || process.env.DATABASE_URL - } - } else { - throw new Error(`Unsupported database connector: ${dbConfig.connector}`) + const { dialect, driver, connection } = dbConfig + + // Prepare database credentials for Drizzle Studio + let dbCredentials = connection + + if (driver === 'node-postgres') { + dbCredentials = { url: connection.connectionString } } // Generate drizzle config content const drizzleConfig = `import { defineConfig } from "drizzle-kit"; export default defineConfig({ - dialect: "${dialect}"${dbConfig.connector === 'pglite' ? ',\n driver: "pglite"' : ''}, + dialect: "${dialect}", dbCredentials: ${JSON.stringify(dbCredentials, null, 2)} });` const drizzleConfigNuxtPath = join(nuxt.options.buildDir, 'drizzle.config.ts') await writeFile(drizzleConfigNuxtPath, drizzleConfig, 'utf-8') - const connectorDependency = dbConfig.connector === 'pglite' ? '@electric-sql/pglite' : dbConfig.connector + // Map driver to package dependency + const driverToPackage: Record = { + 'better-sqlite3': 'better-sqlite3', + 'libsql': '@libsql/client', + 'node-postgres': 'pg', + 'mysql2': 'mysql2', + 'pglite': '@electric-sql/pglite' + } + + const connectorDependency = driverToPackage[driver] || driver const cmd = dlxCommand(packageManager.name, 'drizzle-kit', { args: [ From 39171518960b96fbf42fe6bbb45e3601e5629f4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Chopin?= Date: Mon, 20 Oct 2025 21:29:48 +0200 Subject: [PATCH 02/22] Update db.ts --- playground/server/api/tests/db.ts | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/playground/server/api/tests/db.ts b/playground/server/api/tests/db.ts index b54ee592..8c27de74 100644 --- a/playground/server/api/tests/db.ts +++ b/playground/server/api/tests/db.ts @@ -1,22 +1,17 @@ export default defineEventHandler(async () => { + if (useRuntimeConfig().hub.database.dialect !== 'sqlite') { + return { + error: 'SQLite is not enabled', + } + } const db = useDrizzle() - const drizzleTables = await db.execute(sql` - SELECT - name, - type - FROM - sqlite_schema - WHERE - type = 'table' AND - name NOT LIKE 'sqlite_%' and name NOT LIKE '_litestream_%' and name NOT LIKE '__drizzle%' - ; - `) + const { rows } = await db.run(`SELECT name, type FROM sqlite_schema WHERE type = 'table' AND name NOT LIKE 'sqlite_%' and name NOT LIKE '_litestream_%' and name NOT LIKE '__drizzle%';`) - const all = await db.select().from(tables.todos).limit(3) + const todos = await db.select().from(tables.todos).limit(3) return { - drizzleTables: drizzleTables.rows || drizzleTables, - all + drizzleTables: rows, + todos, } }) From 0248d09c98f22c59feefb2cd40b5d8dd4b75e105 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Chopin?= Date: Tue, 21 Oct 2025 10:09:24 +0200 Subject: [PATCH 03/22] lint fix --- playground/server/api/tests/db.ts | 4 ++-- src/features/database.ts | 10 +++++----- src/module.ts | 4 ++-- .../server/api/_hub/database/query.post.dev.ts | 6 ++++-- .../database/server/utils/migrations/helpers.ts | 12 ++++++------ .../database/server/utils/migrations/migrations.ts | 2 +- src/utils/database.ts | 3 +-- src/utils/devtools.ts | 6 +++--- test/basic.test.ts | 2 +- 9 files changed, 25 insertions(+), 24 deletions(-) diff --git a/playground/server/api/tests/db.ts b/playground/server/api/tests/db.ts index 8c27de74..97c47b4d 100644 --- a/playground/server/api/tests/db.ts +++ b/playground/server/api/tests/db.ts @@ -1,7 +1,7 @@ export default defineEventHandler(async () => { if (useRuntimeConfig().hub.database.dialect !== 'sqlite') { return { - error: 'SQLite is not enabled', + error: 'SQLite is not enabled' } } const db = useDrizzle() @@ -12,6 +12,6 @@ export default defineEventHandler(async () => { return { drizzleTables: rows, - todos, + todos } }) diff --git a/src/features/database.ts b/src/features/database.ts index c44b9a68..da1cb562 100644 --- a/src/features/database.ts +++ b/src/features/database.ts @@ -1,5 +1,4 @@ import { mkdir } from 'node:fs/promises' -import { defu } from 'defu' import { join } from 'pathe' import { addServerImportsDir, addServerScanDir, addTemplate, addTypeTemplate, logger } from '@nuxt/kit' import { copyDatabaseMigrationsToHubDir, copyDatabaseQueriesToHubDir } from '../runtime/database/server/utils/migrations/helpers' @@ -16,7 +15,7 @@ const log = logger.withTag('nuxt:hub') /** * Resolve database configuration from string or object format */ -export function resolveDatabaseConfig(database: string | DatabaseConfig, isDev: boolean): ResolvedDatabaseConfig { +export function resolveDatabaseConfig(database: string | DatabaseConfig): ResolvedDatabaseConfig { let dialect: 'sqlite' | 'postgresql' | 'mysql' let connection: Record = {} let driver: string | undefined @@ -181,12 +180,12 @@ export function drizzle(options) { nuxt.options.nitro.alias!['#hub/database'] = template.dst addTypeTemplate({ filename: 'hub/database.d.ts', - getContents: () => drizzleOrmTypes, + getContents: () => drizzleOrmTypes }, { nitro: true }) } } -export async function setupProductionDatabase(nitro: Nitro, hub: HubConfig, deps: Record) { +export async function setupProductionDatabase(nitro: Nitro, hub: HubConfig, _deps: Record) { const preset = nitro.options.preset if (!preset) return @@ -197,7 +196,8 @@ export async function setupProductionDatabase(nitro: Nitro, hub: HubConfig, deps return } - let { dialect, driver, connection } = dbConfig + const { dialect } = dbConfig + let { driver, connection } = dbConfig // Override driver based on preset switch (preset) { diff --git a/src/module.ts b/src/module.ts index da65faf7..51378c25 100644 --- a/src/module.ts +++ b/src/module.ts @@ -11,7 +11,7 @@ import { addBuildHooks } from './utils/build' export * from './types' -const log = logger.withTag('nuxt:hub'); +const log = logger.withTag('nuxt:hub') export const { resolve, resolvePath } = createResolver(import.meta.url) @@ -53,7 +53,7 @@ export default defineNuxtModule({ // Resolve database configuration if enabled if (hub.database) { - hub.database = resolveDatabaseConfig(hub.database as string | DatabaseConfig, nuxt.options.dev) + hub.database = resolveDatabaseConfig(hub.database as string | DatabaseConfig) } runtimeConfig.hub = hub as any diff --git a/src/runtime/database/server/api/_hub/database/query.post.dev.ts b/src/runtime/database/server/api/_hub/database/query.post.dev.ts index eaedbab4..9ea3c61e 100644 --- a/src/runtime/database/server/api/_hub/database/query.post.dev.ts +++ b/src/runtime/database/server/api/_hub/database/query.post.dev.ts @@ -1,6 +1,7 @@ import { eventHandler, createError, readValidatedBody } from 'h3' import { sql } from 'drizzle-orm' import z from 'zod' +import { useRuntimeConfig } from '#imports' const schema = z.object({ sql: z.string(), @@ -9,7 +10,7 @@ const schema = z.object({ }) export default eventHandler(async (event) => { - const { sql: sqlQuery, params, method } = await readValidatedBody(event, schema.parse) + const { sql: sqlQuery, method } = await readValidatedBody(event, schema.parse) const sqlBody = sqlQuery.replace(/;/g, '') try { @@ -18,7 +19,8 @@ export default eventHandler(async (event) => { const db = drizzle() // Use Drizzle's sql.raw to execute the query - const result = await db.execute(sql.raw(sqlBody)) + const execute = (useRuntimeConfig().hub.database as any).dialect === 'sqlite' ? 'run' : 'execute' + const result = await db[execute](sql.raw(sqlBody)) // Handle different response formats based on method if (method === 'get') { diff --git a/src/runtime/database/server/utils/migrations/helpers.ts b/src/runtime/database/server/utils/migrations/helpers.ts index 39da6263..07320cd6 100644 --- a/src/runtime/database/server/utils/migrations/helpers.ts +++ b/src/runtime/database/server/utils/migrations/helpers.ts @@ -41,13 +41,13 @@ export async function getDatabaseMigrationFiles(hub: HubConfig) { const dialect = typeof hub.database === 'string' ? hub.database : (typeof hub.database === 'object' && hub.database !== null && 'dialect' in hub.database) - ? hub.database.dialect - : undefined + ? hub.database.dialect + : undefined // Get migrations and exclude if dialect specified but not the current database dialect const migrationsFiles = (await storage.getKeys()).map(file => getMigrationMetadata(file)).filter(migration => migration.dialect === dialect || !migration.dialect) - return migrationsFiles.filter(migration => { + return migrationsFiles.filter((migration) => { // if generic SQL migration file, exclude it if same migration name for current database dialect exists if (!migration.dialect && migrationsFiles.findIndex(m => m.name === migration.name && m.dialect === dialect) !== -1) { return false @@ -133,12 +133,12 @@ export async function getDatabaseQueryFiles(hub: HubConfig) { const dialect = typeof hub.database === 'string' ? hub.database : (typeof hub.database === 'object' && hub.database !== null && 'dialect' in hub.database) - ? hub.database.dialect - : undefined + ? hub.database.dialect + : undefined const queriesFiles = (await storage.getKeys()).map(file => getMigrationMetadata(file)).filter(query => query.dialect === dialect || !query.dialect) - return queriesFiles.filter(query => { + return queriesFiles.filter((query) => { // if generic SQL query file, exclude it if same query name for current database dialect exists if (!query.dialect && queriesFiles.findIndex(q => q.name === query.name && q.dialect === dialect) !== -1) { return false diff --git a/src/runtime/database/server/utils/migrations/migrations.ts b/src/runtime/database/server/utils/migrations/migrations.ts index 0f967a08..59027927 100644 --- a/src/runtime/database/server/utils/migrations/migrations.ts +++ b/src/runtime/database/server/utils/migrations/migrations.ts @@ -26,7 +26,7 @@ export async function applyDatabaseMigrations(hub: HubConfig, db: any, dialect: } const localMigrations = await getDatabaseMigrationFiles(hub) - const pendingMigrations = localMigrations.filter((migration) => !appliedRows.find((row: any) => { + const pendingMigrations = localMigrations.filter(migration => !appliedRows.find((row: any) => { const name = row.name || row[1] // Handle both object and array responses return name === migration.name })) diff --git a/src/utils/database.ts b/src/utils/database.ts index 120b46bf..3041d2f9 100644 --- a/src/utils/database.ts +++ b/src/utils/database.ts @@ -12,11 +12,10 @@ const log = logger.withTag('nuxt:hub') * Creates a Drizzle client for the given configuration */ async function createDrizzleClient(config: any) { - const { dialect, driver, connection } = config + const { driver, connection } = config if (driver === 'libsql') { const { drizzle } = await import('drizzle-orm/libsql') - // @ts-expect-error - @libsql/client is an optional dependency const { createClient } = await import('@libsql/client') const client = createClient(connection) return drizzle(client) diff --git a/src/utils/devtools.ts b/src/utils/devtools.ts index 656d8e37..81953786 100644 --- a/src/utils/devtools.ts +++ b/src/utils/devtools.ts @@ -55,10 +55,10 @@ export default defineConfig({ // Map driver to package dependency const driverToPackage: Record = { 'better-sqlite3': 'better-sqlite3', - 'libsql': '@libsql/client', + libsql: '@libsql/client', 'node-postgres': 'pg', - 'mysql2': 'mysql2', - 'pglite': '@electric-sql/pglite' + mysql2: 'mysql2', + pglite: '@electric-sql/pglite' } const connectorDependency = driverToPackage[driver] || driver diff --git a/test/basic.test.ts b/test/basic.test.ts index 8a1bf748..e8898ee0 100644 --- a/test/basic.test.ts +++ b/test/basic.test.ts @@ -5,7 +5,7 @@ import { setup, $fetch } from '@nuxt/test-utils/e2e' describe('ssr', async () => { await setup({ rootDir: fileURLToPath(new URL('./fixtures/basic', import.meta.url)), - dev: true, + dev: true }) it('Check all features are disabled', async () => { From 26677ae3a8f33ad6f3eb3161f2c9342a60584999 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Chopin?= Date: Tue, 21 Oct 2025 15:33:50 +0200 Subject: [PATCH 04/22] chore: remove production setup and handle CF --- playground/_wrangler.jsonc | 10 + playground/nuxt.config.ts | 2 +- playground/server/api/cf.ts | 1 + playground/server/utils/drizzle.ts | 2 +- pnpm-lock.yaml | 692 +++++++++++++++++- src/features/database.ts | 305 +++----- src/module.ts | 13 +- .../api/_hub/database/query.post.dev.ts | 2 +- .../database/server/plugins/migrations.dev.ts | 2 +- src/utils/build.ts | 2 - 10 files changed, 791 insertions(+), 240 deletions(-) create mode 100644 playground/_wrangler.jsonc diff --git a/playground/_wrangler.jsonc b/playground/_wrangler.jsonc new file mode 100644 index 00000000..738c7327 --- /dev/null +++ b/playground/_wrangler.jsonc @@ -0,0 +1,10 @@ +{ + "d1_databases": [ + { + "binding": "DB", + "database_name": "nuxthub-playground", + "database_id": "local" + } + ] +} + diff --git a/playground/nuxt.config.ts b/playground/nuxt.config.ts index 37e8c196..0516f35a 100644 --- a/playground/nuxt.config.ts +++ b/playground/nuxt.config.ts @@ -32,7 +32,7 @@ export default defineNuxtConfig({ hub: { ai: 'cloudflare', - database: process.env.TEST ? 'sqlite' : 'postgresql', + database: process.env.TEST || process.env.NITRO_PRESET?.includes('cloudflare') ? 'sqlite' : 'postgresql', blob: true, kv: true, cache: true diff --git a/playground/server/api/cf.ts b/playground/server/api/cf.ts index 87ed4dad..daab826f 100644 --- a/playground/server/api/cf.ts +++ b/playground/server/api/cf.ts @@ -1,5 +1,6 @@ export default eventHandler(async () => { const event = useEvent() + console.log(event.context) const { isEUCountry, continent, city, timezone, country, region, latitude, longitude, botManagement } = event.context.cf const ip = getHeader(event, 'cf-connecting-ip') || getRequestIP(event, { xForwardedFor: true }) diff --git a/playground/server/utils/drizzle.ts b/playground/server/utils/drizzle.ts index 4124aa2f..a9f1393d 100644 --- a/playground/server/utils/drizzle.ts +++ b/playground/server/utils/drizzle.ts @@ -1,6 +1,6 @@ import { sqliteTable, text, integer } from 'drizzle-orm/sqlite-core' // import { pgTable, text as pgText, boolean as pgBoolean, serial as pgSerial, timestamp as pgTimestamp } from 'drizzle-orm/pg-core' -import { drizzle } from '#hub/database' +import { drizzle } from 'hub:database' export { sql } from 'drizzle-orm' diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f1a08a9c..f9517882 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -256,6 +256,9 @@ importers: '@nuxt/devtools': specifier: latest version: 2.6.5(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)) + wrangler: + specifier: ^4.43.0 + version: 4.43.0(@cloudflare/workers-types@4.20251011.0) packages: @@ -467,9 +470,52 @@ packages: resolution: {integrity: sha512-+tv3z+SPp+gqTIcImN9o0hqE9xyfQjI1XD9pL6NuKjua9B1y7mNYv0S9cP+QEbA4ppVgGZEmKOvHX5G5Ei1CVA==} engines: {node: '>=18.0.0'} + '@cloudflare/unenv-preset@2.7.7': + resolution: {integrity: sha512-HtZuh166y0Olbj9bqqySckz0Rw9uHjggJeoGbDx5x+sgezBXlxO6tQSig2RZw5tgObF8mWI8zaPvQMkQZtAODw==} + peerDependencies: + unenv: 2.0.0-rc.21 + workerd: ^1.20250927.0 + peerDependenciesMeta: + workerd: + optional: true + + '@cloudflare/workerd-darwin-64@1.20251008.0': + resolution: {integrity: sha512-yph0H+8mMOK5Z9oDwjb8rI96oTVt4no5lZ43aorcbzsWG9VUIaXSXlBBoB3von6p4YCRW+J3n36fBM9XZ6TLaA==} + engines: {node: '>=16'} + cpu: [x64] + os: [darwin] + + '@cloudflare/workerd-darwin-arm64@1.20251008.0': + resolution: {integrity: sha512-Yc4lMGSbM4AEtYRpyDpmk77MsHb6X2BSwJgMgGsLVPmckM7ZHivZkJChfcNQjZ/MGR6nkhYc4iF6TcVS+UMEVw==} + engines: {node: '>=16'} + cpu: [arm64] + os: [darwin] + + '@cloudflare/workerd-linux-64@1.20251008.0': + resolution: {integrity: sha512-AjoQnylw4/5G6SmfhZRsli7EuIK7ZMhmbxtU0jkpciTlVV8H01OsFOgS1d8zaTXMfkWamEfMouy8oH/L7B9YcQ==} + engines: {node: '>=16'} + cpu: [x64] + os: [linux] + + '@cloudflare/workerd-linux-arm64@1.20251008.0': + resolution: {integrity: sha512-hRy9yyvzVq1HsqHZUmFkAr0C8JGjAD/PeeVEGCKL3jln3M9sNCKIrbDXiL+efe+EwajJNNlDxpO+s30uVWVaRg==} + engines: {node: '>=16'} + cpu: [arm64] + os: [linux] + + '@cloudflare/workerd-windows-64@1.20251008.0': + resolution: {integrity: sha512-Gm0RR+ehfNMsScn2pUcn3N9PDUpy7FyvV9ecHEyclKttvztyFOcmsF14bxEaSVv7iM4TxWEBn1rclmYHxDM4ow==} + engines: {node: '>=16'} + cpu: [x64] + os: [win32] + '@cloudflare/workers-types@4.20251011.0': resolution: {integrity: sha512-gQpih+pbq3sP4uXltUeCSbPgZxTNp2gQd8639SaIbQMwgA6oJNHLhIART1fWy6DQACngiRzDVULA2x0ohmkGTQ==} + '@cspotcode/source-map-support@0.8.1': + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + '@electric-sql/pglite@0.3.11': resolution: {integrity: sha512-FJtjnEyez8XgmgyE5Ewmx89TGVN+75ZjykFoExApRIbJBMT4dsbsuZkF/YWLuymGDfGFHDACjvENPMEqg4FoWg==} @@ -492,126 +538,252 @@ packages: cpu: [ppc64] os: [aix] + '@esbuild/aix-ppc64@0.25.4': + resolution: {integrity: sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + '@esbuild/android-arm64@0.25.10': resolution: {integrity: sha512-LSQa7eDahypv/VO6WKohZGPSJDq5OVOo3UoFR1E4t4Gj1W7zEQMUhI+lo81H+DtB+kP+tDgBp+M4oNCwp6kffg==} engines: {node: '>=18'} cpu: [arm64] os: [android] + '@esbuild/android-arm64@0.25.4': + resolution: {integrity: sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm@0.25.10': resolution: {integrity: sha512-dQAxF1dW1C3zpeCDc5KqIYuZ1tgAdRXNoZP7vkBIRtKZPYe2xVr/d3SkirklCHudW1B45tGiUlz2pUWDfbDD4w==} engines: {node: '>=18'} cpu: [arm] os: [android] + '@esbuild/android-arm@0.25.4': + resolution: {integrity: sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + '@esbuild/android-x64@0.25.10': resolution: {integrity: sha512-MiC9CWdPrfhibcXwr39p9ha1x0lZJ9KaVfvzA0Wxwz9ETX4v5CHfF09bx935nHlhi+MxhA63dKRRQLiVgSUtEg==} engines: {node: '>=18'} cpu: [x64] os: [android] + '@esbuild/android-x64@0.25.4': + resolution: {integrity: sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + '@esbuild/darwin-arm64@0.25.10': resolution: {integrity: sha512-JC74bdXcQEpW9KkV326WpZZjLguSZ3DfS8wrrvPMHgQOIEIG/sPXEN/V8IssoJhbefLRcRqw6RQH2NnpdprtMA==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] + '@esbuild/darwin-arm64@0.25.4': + resolution: {integrity: sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-x64@0.25.10': resolution: {integrity: sha512-tguWg1olF6DGqzws97pKZ8G2L7Ig1vjDmGTwcTuYHbuU6TTjJe5FXbgs5C1BBzHbJ2bo1m3WkQDbWO2PvamRcg==} engines: {node: '>=18'} cpu: [x64] os: [darwin] + '@esbuild/darwin-x64@0.25.4': + resolution: {integrity: sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + '@esbuild/freebsd-arm64@0.25.10': resolution: {integrity: sha512-3ZioSQSg1HT2N05YxeJWYR+Libe3bREVSdWhEEgExWaDtyFbbXWb49QgPvFH8u03vUPX10JhJPcz7s9t9+boWg==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-arm64@0.25.4': + resolution: {integrity: sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-x64@0.25.10': resolution: {integrity: sha512-LLgJfHJk014Aa4anGDbh8bmI5Lk+QidDmGzuC2D+vP7mv/GeSN+H39zOf7pN5N8p059FcOfs2bVlrRr4SK9WxA==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] + '@esbuild/freebsd-x64@0.25.4': + resolution: {integrity: sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + '@esbuild/linux-arm64@0.25.10': resolution: {integrity: sha512-5luJWN6YKBsawd5f9i4+c+geYiVEw20FVW5x0v1kEMWNq8UctFjDiMATBxLvmmHA4bf7F6hTRaJgtghFr9iziQ==} engines: {node: '>=18'} cpu: [arm64] os: [linux] + '@esbuild/linux-arm64@0.25.4': + resolution: {integrity: sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm@0.25.10': resolution: {integrity: sha512-oR31GtBTFYCqEBALI9r6WxoU/ZofZl962pouZRTEYECvNF/dtXKku8YXcJkhgK/beU+zedXfIzHijSRapJY3vg==} engines: {node: '>=18'} cpu: [arm] os: [linux] + '@esbuild/linux-arm@0.25.4': + resolution: {integrity: sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + '@esbuild/linux-ia32@0.25.10': resolution: {integrity: sha512-NrSCx2Kim3EnnWgS4Txn0QGt0Xipoumb6z6sUtl5bOEZIVKhzfyp/Lyw4C1DIYvzeW/5mWYPBFJU3a/8Yr75DQ==} engines: {node: '>=18'} cpu: [ia32] os: [linux] + '@esbuild/linux-ia32@0.25.4': + resolution: {integrity: sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-loong64@0.25.10': resolution: {integrity: sha512-xoSphrd4AZda8+rUDDfD9J6FUMjrkTz8itpTITM4/xgerAZZcFW7Dv+sun7333IfKxGG8gAq+3NbfEMJfiY+Eg==} engines: {node: '>=18'} cpu: [loong64] os: [linux] + '@esbuild/linux-loong64@0.25.4': + resolution: {integrity: sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-mips64el@0.25.10': resolution: {integrity: sha512-ab6eiuCwoMmYDyTnyptoKkVS3k8fy/1Uvq7Dj5czXI6DF2GqD2ToInBI0SHOp5/X1BdZ26RKc5+qjQNGRBelRA==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] + '@esbuild/linux-mips64el@0.25.4': + resolution: {integrity: sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-ppc64@0.25.10': resolution: {integrity: sha512-NLinzzOgZQsGpsTkEbdJTCanwA5/wozN9dSgEl12haXJBzMTpssebuXR42bthOF3z7zXFWH1AmvWunUCkBE4EA==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] + '@esbuild/linux-ppc64@0.25.4': + resolution: {integrity: sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-riscv64@0.25.10': resolution: {integrity: sha512-FE557XdZDrtX8NMIeA8LBJX3dC2M8VGXwfrQWU7LB5SLOajfJIxmSdyL/gU1m64Zs9CBKvm4UAuBp5aJ8OgnrA==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] + '@esbuild/linux-riscv64@0.25.4': + resolution: {integrity: sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-s390x@0.25.10': resolution: {integrity: sha512-3BBSbgzuB9ajLoVZk0mGu+EHlBwkusRmeNYdqmznmMc9zGASFjSsxgkNsqmXugpPk00gJ0JNKh/97nxmjctdew==} engines: {node: '>=18'} cpu: [s390x] os: [linux] + '@esbuild/linux-s390x@0.25.4': + resolution: {integrity: sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-x64@0.25.10': resolution: {integrity: sha512-QSX81KhFoZGwenVyPoberggdW1nrQZSvfVDAIUXr3WqLRZGZqWk/P4T8p2SP+de2Sr5HPcvjhcJzEiulKgnxtA==} engines: {node: '>=18'} cpu: [x64] os: [linux] + '@esbuild/linux-x64@0.25.4': + resolution: {integrity: sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + '@esbuild/netbsd-arm64@0.25.10': resolution: {integrity: sha512-AKQM3gfYfSW8XRk8DdMCzaLUFB15dTrZfnX8WXQoOUpUBQ+NaAFCP1kPS/ykbbGYz7rxn0WS48/81l9hFl3u4A==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] + '@esbuild/netbsd-arm64@0.25.4': + resolution: {integrity: sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + '@esbuild/netbsd-x64@0.25.10': resolution: {integrity: sha512-7RTytDPGU6fek/hWuN9qQpeGPBZFfB4zZgcz2VK2Z5VpdUxEI8JKYsg3JfO0n/Z1E/6l05n0unDCNc4HnhQGig==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] + '@esbuild/netbsd-x64@0.25.4': + resolution: {integrity: sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + '@esbuild/openbsd-arm64@0.25.10': resolution: {integrity: sha512-5Se0VM9Wtq797YFn+dLimf2Zx6McttsH2olUBsDml+lm0GOCRVebRWUvDtkY4BWYv/3NgzS8b/UM3jQNh5hYyw==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] + '@esbuild/openbsd-arm64@0.25.4': + resolution: {integrity: sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + '@esbuild/openbsd-x64@0.25.10': resolution: {integrity: sha512-XkA4frq1TLj4bEMB+2HnI0+4RnjbuGZfet2gs/LNs5Hc7D89ZQBHQ0gL2ND6Lzu1+QVkjp3x1gIcPKzRNP8bXw==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] + '@esbuild/openbsd-x64@0.25.4': + resolution: {integrity: sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + '@esbuild/openharmony-arm64@0.25.10': resolution: {integrity: sha512-AVTSBhTX8Y/Fz6OmIVBip9tJzZEUcY8WLh7I59+upa5/GPhh2/aM6bvOMQySspnCCHvFi79kMtdJS1w0DXAeag==} engines: {node: '>=18'} @@ -624,24 +796,48 @@ packages: cpu: [x64] os: [sunos] + '@esbuild/sunos-x64@0.25.4': + resolution: {integrity: sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + '@esbuild/win32-arm64@0.25.10': resolution: {integrity: sha512-ah+9b59KDTSfpaCg6VdJoOQvKjI33nTaQr4UluQwW7aEwZQsbMCfTmfEO4VyewOxx4RaDT/xCy9ra2GPWmO7Kw==} engines: {node: '>=18'} cpu: [arm64] os: [win32] + '@esbuild/win32-arm64@0.25.4': + resolution: {integrity: sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-ia32@0.25.10': resolution: {integrity: sha512-QHPDbKkrGO8/cz9LKVnJU22HOi4pxZnZhhA2HYHez5Pz4JeffhDjf85E57Oyco163GnzNCVkZK0b/n4Y0UHcSw==} engines: {node: '>=18'} cpu: [ia32] os: [win32] + '@esbuild/win32-ia32@0.25.4': + resolution: {integrity: sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-x64@0.25.10': resolution: {integrity: sha512-9KpxSVFCu0iK1owoez6aC/s/EdUQLDN3adTxGCqxMVhrPDj6bt5dbrHDXUuq+Bs2vATFBBrQS5vdQ/Ed2P+nbw==} engines: {node: '>=18'} cpu: [x64] os: [win32] + '@esbuild/win32-x64@0.25.4': + resolution: {integrity: sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + '@eslint-community/eslint-utils@4.8.0': resolution: {integrity: sha512-MJQFqrZgcW0UNYLGOuQpey/oTN59vyWwplvCGZztn1cKz9agZPPYpJB7h2OMmuu7VLqkvEjN8feFZJmxNF9D+Q==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -781,6 +977,111 @@ packages: peerDependencies: vue: '>=3' + '@img/sharp-darwin-arm64@0.33.5': + resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [darwin] + + '@img/sharp-darwin-x64@0.33.5': + resolution: {integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-darwin-arm64@1.0.4': + resolution: {integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.0.4': + resolution: {integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-linux-arm64@1.0.4': + resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linux-arm@1.0.5': + resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==} + cpu: [arm] + os: [linux] + + '@img/sharp-libvips-linux-s390x@1.0.4': + resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==} + cpu: [s390x] + os: [linux] + + '@img/sharp-libvips-linux-x64@1.0.4': + resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==} + cpu: [x64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-arm64@1.0.4': + resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-x64@1.0.4': + resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==} + cpu: [x64] + os: [linux] + + '@img/sharp-linux-arm64@0.33.5': + resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linux-arm@0.33.5': + resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm] + os: [linux] + + '@img/sharp-linux-s390x@0.33.5': + resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [s390x] + os: [linux] + + '@img/sharp-linux-x64@0.33.5': + resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-linuxmusl-arm64@0.33.5': + resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linuxmusl-x64@0.33.5': + resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-wasm32@0.33.5': + resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] + + '@img/sharp-win32-ia32@0.33.5': + resolution: {integrity: sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] + + '@img/sharp-win32-x64@0.33.5': + resolution: {integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + '@internationalized/date@3.10.0': resolution: {integrity: sha512-oxDR/NTEJ1k+UFVQElaNIk65E/Z83HK1z1WI3lQyhTtnNg4R5oVXaPzK3jcpKG8UHKDVuDQHzn+wsxSz8RP3aw==} @@ -828,6 +1129,9 @@ packages: '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + '@jridgewell/trace-mapping@0.3.9': + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + '@jsdevtools/ono@7.1.3': resolution: {integrity: sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==} @@ -3047,6 +3351,15 @@ packages: peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + acorn-walk@8.3.2: + resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==} + engines: {node: '>=0.4.0'} + + acorn@8.14.0: + resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==} + engines: {node: '>=0.4.0'} + hasBin: true + acorn@8.15.0: resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} engines: {node: '>=0.4.0'} @@ -3232,6 +3545,9 @@ packages: bl@4.1.0: resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + blake3-wasm@2.1.5: + resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==} + blob-to-buffer@1.2.9: resolution: {integrity: sha512-BF033y5fN6OCofD3vgHmNtwZWRcq9NLyyxyILx9hfMy1sXYy4ojFl765hJ2lP0YaN2fuxPaLO2Vzzoxy0FLFFA==} @@ -3969,6 +4285,11 @@ packages: engines: {node: '>=18'} hasBin: true + esbuild@0.25.4: + resolution: {integrity: sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q==} + engines: {node: '>=18'} + hasBin: true + escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} @@ -4143,6 +4464,10 @@ packages: resolution: {integrity: sha512-jpWzZ1ZhwUmeWRhS7Qv3mhpOhLfwI+uAX4e5fOcXqwMR7EcJ0pj2kV1CVzHVMX/LphnKWD3LObjZCoJ71lKpHw==} engines: {node: ^18.19.0 || >=20.5.0} + exit-hook@2.2.1: + resolution: {integrity: sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==} + engines: {node: '>=6'} + expand-template@2.0.3: resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} engines: {node: '>=6'} @@ -4345,6 +4670,9 @@ packages: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} + glob-to-regexp@0.4.1: + resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} + glob@10.4.5: resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} hasBin: true @@ -5093,6 +5421,11 @@ packages: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} engines: {node: '>=4'} + miniflare@4.20251008.0: + resolution: {integrity: sha512-sKCNYNzXG6l8qg0Oo7y8WcDKcpbgw0qwZsxNpdZilFTR4EavRow2TlcwuPSVN99jqAjhz0M4VXvTdSGdtJ2VfQ==} + engines: {node: '>=18.0.0'} + hasBin: true + minimark@0.2.0: resolution: {integrity: sha512-AmtWU9pO0C2/3AM2pikaVhJ//8E5rOpJ7+ioFQfjIq+wCsBeuZoxPd97hBFZ9qrI7DMHZudwGH3r8A7BMnsIew==} @@ -5508,6 +5841,9 @@ packages: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} + path-to-regexp@6.3.0: + resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} + path-type@6.0.0: resolution: {integrity: sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==} engines: {node: '>=18'} @@ -6137,6 +6473,10 @@ packages: resolution: {integrity: sha512-KyLTWwgcR9Oe4d9HwCwNM2l7+J0dUQwn/yf7S0EnTtb0eVS4RxO0eUSvxPtzT4F3SY+C4K6fqdv/DO27sJ/v/w==} engines: {node: '>=14.15.0'} + sharp@0.33.5: + resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -6267,6 +6607,10 @@ packages: std-env@3.9.0: resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==} + stoppable@1.1.0: + resolution: {integrity: sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==} + engines: {node: '>=4', npm: '>=6'} + streamx@2.23.0: resolution: {integrity: sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg==} @@ -6559,6 +6903,10 @@ packages: resolution: {integrity: sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==} engines: {node: '>=14.0'} + undici@7.14.0: + resolution: {integrity: sha512-Vqs8HTzjpQXZeXdpsfChQTlafcMQaaIwnGwLam1wudSSjlJeQ3bw1j+TLPePgrCnCpUXx7Ba5Pdpf5OBih62NQ==} + engines: {node: '>=20.18.1'} + undici@7.16.0: resolution: {integrity: sha512-QEg3HPMll0o3t2ourKwOeUAZ159Kn9mx5pnzHRQO8+Wixmh88YdZRiIwat0iNzNNXn0yoEtXJqFpyW7eM8BV7g==} engines: {node: '>=20.18.1'} @@ -7065,9 +7413,24 @@ packages: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} + workerd@1.20251008.0: + resolution: {integrity: sha512-HwaJmXO3M1r4S8x2ea2vy8Rw/y/38HRQuK/gNDRQ7w9cJXn6xSl1sIIqKCffULSUjul3wV3I3Nd/GfbmsRReEA==} + engines: {node: '>=16'} + hasBin: true + workers-ai-provider@2.0.0: resolution: {integrity: sha512-AoGGy8aOR3lzCzRouSxA6mgrCKuZfrnzxvOHHy9kOzwz4Mm4Hb55a/9G8zz+v0I/mn8bYLs/4I6JABSl/zXJ7w==} + wrangler@4.43.0: + resolution: {integrity: sha512-IBNqXlYHSUSCNNWj/tQN4hFiQy94l7fTxEnJWETXyW69+cjUyjQ7MfeoId3vIV9KBgY8y5M5uf2XulU95OikJg==} + engines: {node: '>=18.0.0'} + hasBin: true + peerDependencies: + '@cloudflare/workers-types': ^4.20251008.0 + peerDependenciesMeta: + '@cloudflare/workers-types': + optional: true + wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} @@ -7091,6 +7454,18 @@ packages: utf-8-validate: optional: true + ws@8.18.0: + resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + ws@8.18.3: resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} engines: {node: '>=10.0.0'} @@ -7166,6 +7541,9 @@ packages: youch-core@0.3.3: resolution: {integrity: sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA==} + youch@4.1.0-beta.10: + resolution: {integrity: sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ==} + youch@4.1.0-beta.11: resolution: {integrity: sha512-sQi6PERyO/mT8w564ojOVeAlYTtVQmC2GaktQAf+IdI75/GKIggosBuvyVXvEV+FATAT6RbLdIjFoiIId4ozoQ==} @@ -7178,6 +7556,9 @@ packages: peerDependencies: zod: ^3.24.1 + zod@3.22.3: + resolution: {integrity: sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug==} + zod@3.25.76: resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} @@ -7474,8 +7855,33 @@ snapshots: dependencies: mime: 3.0.0 + '@cloudflare/unenv-preset@2.7.7(unenv@2.0.0-rc.21)(workerd@1.20251008.0)': + dependencies: + unenv: 2.0.0-rc.21 + optionalDependencies: + workerd: 1.20251008.0 + + '@cloudflare/workerd-darwin-64@1.20251008.0': + optional: true + + '@cloudflare/workerd-darwin-arm64@1.20251008.0': + optional: true + + '@cloudflare/workerd-linux-64@1.20251008.0': + optional: true + + '@cloudflare/workerd-linux-arm64@1.20251008.0': + optional: true + + '@cloudflare/workerd-windows-64@1.20251008.0': + optional: true + '@cloudflare/workers-types@4.20251011.0': {} + '@cspotcode/source-map-support@0.8.1': + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + '@electric-sql/pglite@0.3.11': {} '@emnapi/core@1.5.0': @@ -7505,81 +7911,156 @@ snapshots: '@esbuild/aix-ppc64@0.25.10': optional: true + '@esbuild/aix-ppc64@0.25.4': + optional: true + '@esbuild/android-arm64@0.25.10': optional: true + '@esbuild/android-arm64@0.25.4': + optional: true + '@esbuild/android-arm@0.25.10': optional: true + '@esbuild/android-arm@0.25.4': + optional: true + '@esbuild/android-x64@0.25.10': optional: true + '@esbuild/android-x64@0.25.4': + optional: true + '@esbuild/darwin-arm64@0.25.10': optional: true + '@esbuild/darwin-arm64@0.25.4': + optional: true + '@esbuild/darwin-x64@0.25.10': optional: true + '@esbuild/darwin-x64@0.25.4': + optional: true + '@esbuild/freebsd-arm64@0.25.10': optional: true + '@esbuild/freebsd-arm64@0.25.4': + optional: true + '@esbuild/freebsd-x64@0.25.10': optional: true + '@esbuild/freebsd-x64@0.25.4': + optional: true + '@esbuild/linux-arm64@0.25.10': optional: true + '@esbuild/linux-arm64@0.25.4': + optional: true + '@esbuild/linux-arm@0.25.10': optional: true + '@esbuild/linux-arm@0.25.4': + optional: true + '@esbuild/linux-ia32@0.25.10': optional: true + '@esbuild/linux-ia32@0.25.4': + optional: true + '@esbuild/linux-loong64@0.25.10': optional: true + '@esbuild/linux-loong64@0.25.4': + optional: true + '@esbuild/linux-mips64el@0.25.10': optional: true + '@esbuild/linux-mips64el@0.25.4': + optional: true + '@esbuild/linux-ppc64@0.25.10': optional: true + '@esbuild/linux-ppc64@0.25.4': + optional: true + '@esbuild/linux-riscv64@0.25.10': optional: true + '@esbuild/linux-riscv64@0.25.4': + optional: true + '@esbuild/linux-s390x@0.25.10': optional: true + '@esbuild/linux-s390x@0.25.4': + optional: true + '@esbuild/linux-x64@0.25.10': optional: true + '@esbuild/linux-x64@0.25.4': + optional: true + '@esbuild/netbsd-arm64@0.25.10': optional: true + '@esbuild/netbsd-arm64@0.25.4': + optional: true + '@esbuild/netbsd-x64@0.25.10': optional: true + '@esbuild/netbsd-x64@0.25.4': + optional: true + '@esbuild/openbsd-arm64@0.25.10': optional: true + '@esbuild/openbsd-arm64@0.25.4': + optional: true + '@esbuild/openbsd-x64@0.25.10': optional: true + '@esbuild/openbsd-x64@0.25.4': + optional: true + '@esbuild/openharmony-arm64@0.25.10': optional: true '@esbuild/sunos-x64@0.25.10': optional: true + '@esbuild/sunos-x64@0.25.4': + optional: true + '@esbuild/win32-arm64@0.25.10': optional: true + '@esbuild/win32-arm64@0.25.4': + optional: true + '@esbuild/win32-ia32@0.25.10': optional: true + '@esbuild/win32-ia32@0.25.4': + optional: true + '@esbuild/win32-x64@0.25.10': optional: true + '@esbuild/win32-x64@0.25.4': + optional: true + '@eslint-community/eslint-utils@4.8.0(eslint@9.37.0(jiti@2.6.1))': dependencies: eslint: 9.37.0(jiti@2.6.1) @@ -7740,6 +8221,81 @@ snapshots: '@iconify/types': 2.0.0 vue: 3.5.22(typescript@5.9.3) + '@img/sharp-darwin-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.0.4 + optional: true + + '@img/sharp-darwin-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.0.4 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.0.4': + optional: true + + '@img/sharp-libvips-darwin-x64@1.0.4': + optional: true + + '@img/sharp-libvips-linux-arm64@1.0.4': + optional: true + + '@img/sharp-libvips-linux-arm@1.0.5': + optional: true + + '@img/sharp-libvips-linux-s390x@1.0.4': + optional: true + + '@img/sharp-libvips-linux-x64@1.0.4': + optional: true + + '@img/sharp-libvips-linuxmusl-arm64@1.0.4': + optional: true + + '@img/sharp-libvips-linuxmusl-x64@1.0.4': + optional: true + + '@img/sharp-linux-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.0.4 + optional: true + + '@img/sharp-linux-arm@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.0.5 + optional: true + + '@img/sharp-linux-s390x@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.0.4 + optional: true + + '@img/sharp-linux-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.0.4 + optional: true + + '@img/sharp-linuxmusl-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 + optional: true + + '@img/sharp-linuxmusl-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.0.4 + optional: true + + '@img/sharp-wasm32@0.33.5': + dependencies: + '@emnapi/runtime': 1.5.0 + optional: true + + '@img/sharp-win32-ia32@0.33.5': + optional: true + + '@img/sharp-win32-x64@0.33.5': + optional: true + '@internationalized/date@3.10.0': dependencies: '@swc/helpers': 0.5.17 @@ -7798,6 +8354,11 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping@0.3.9': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + '@jsdevtools/ono@7.1.3': {} '@kgierke/nuxt-basic-auth@1.7.0(magicast@0.3.5)': @@ -10522,6 +11083,10 @@ snapshots: dependencies: acorn: 8.15.0 + acorn-walk@8.3.2: {} + + acorn@8.14.0: {} + acorn@8.15.0: {} agent-base@7.1.4: {} @@ -10710,6 +11275,8 @@ snapshots: readable-stream: 3.6.2 optional: true + blake3-wasm@2.1.5: {} + blob-to-buffer@1.2.9: {} boolbase@1.0.0: {} @@ -10923,13 +11490,11 @@ snapshots: dependencies: color-name: 1.1.4 simple-swizzle: 0.2.2 - optional: true color@4.2.3: dependencies: color-convert: 2.0.1 color-string: 1.9.1 - optional: true colord@2.9.3: {} @@ -11347,6 +11912,34 @@ snapshots: '@esbuild/win32-ia32': 0.25.10 '@esbuild/win32-x64': 0.25.10 + esbuild@0.25.4: + optionalDependencies: + '@esbuild/aix-ppc64': 0.25.4 + '@esbuild/android-arm': 0.25.4 + '@esbuild/android-arm64': 0.25.4 + '@esbuild/android-x64': 0.25.4 + '@esbuild/darwin-arm64': 0.25.4 + '@esbuild/darwin-x64': 0.25.4 + '@esbuild/freebsd-arm64': 0.25.4 + '@esbuild/freebsd-x64': 0.25.4 + '@esbuild/linux-arm': 0.25.4 + '@esbuild/linux-arm64': 0.25.4 + '@esbuild/linux-ia32': 0.25.4 + '@esbuild/linux-loong64': 0.25.4 + '@esbuild/linux-mips64el': 0.25.4 + '@esbuild/linux-ppc64': 0.25.4 + '@esbuild/linux-riscv64': 0.25.4 + '@esbuild/linux-s390x': 0.25.4 + '@esbuild/linux-x64': 0.25.4 + '@esbuild/netbsd-arm64': 0.25.4 + '@esbuild/netbsd-x64': 0.25.4 + '@esbuild/openbsd-arm64': 0.25.4 + '@esbuild/openbsd-x64': 0.25.4 + '@esbuild/sunos-x64': 0.25.4 + '@esbuild/win32-arm64': 0.25.4 + '@esbuild/win32-ia32': 0.25.4 + '@esbuild/win32-x64': 0.25.4 + escalade@3.2.0: {} escape-html@1.0.3: {} @@ -11585,6 +12178,8 @@ snapshots: strip-final-newline: 4.0.0 yoctocolors: 2.1.2 + exit-hook@2.2.1: {} + expand-template@2.0.3: optional: true @@ -11777,6 +12372,8 @@ snapshots: dependencies: is-glob: 4.0.3 + glob-to-regexp@0.4.1: {} + glob@10.4.5: dependencies: foreground-child: 3.3.1 @@ -12108,8 +12705,7 @@ snapshots: is-alphabetical: 2.0.1 is-decimal: 2.0.1 - is-arrayish@0.3.2: - optional: true + is-arrayish@0.3.2: {} is-binary-path@2.1.0: dependencies: @@ -12779,6 +13375,24 @@ snapshots: min-indent@1.0.1: {} + miniflare@4.20251008.0: + dependencies: + '@cspotcode/source-map-support': 0.8.1 + acorn: 8.14.0 + acorn-walk: 8.3.2 + exit-hook: 2.2.1 + glob-to-regexp: 0.4.1 + sharp: 0.33.5 + stoppable: 1.1.0 + undici: 7.14.0 + workerd: 1.20251008.0 + ws: 8.18.0 + youch: 4.1.0-beta.10 + zod: 3.22.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + minimark@0.2.0: {} minimatch@10.0.3: @@ -13687,6 +14301,8 @@ snapshots: lru-cache: 10.4.3 minipass: 7.1.2 + path-to-regexp@6.3.0: {} + path-type@6.0.0: {} pathe@1.1.2: {} @@ -14501,6 +15117,32 @@ snapshots: - react-native-b4a optional: true + sharp@0.33.5: + dependencies: + color: 4.2.3 + detect-libc: 2.1.2 + semver: 7.7.3 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.33.5 + '@img/sharp-darwin-x64': 0.33.5 + '@img/sharp-libvips-darwin-arm64': 1.0.4 + '@img/sharp-libvips-darwin-x64': 1.0.4 + '@img/sharp-libvips-linux-arm': 1.0.5 + '@img/sharp-libvips-linux-arm64': 1.0.4 + '@img/sharp-libvips-linux-s390x': 1.0.4 + '@img/sharp-libvips-linux-x64': 1.0.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 + '@img/sharp-libvips-linuxmusl-x64': 1.0.4 + '@img/sharp-linux-arm': 0.33.5 + '@img/sharp-linux-arm64': 0.33.5 + '@img/sharp-linux-s390x': 0.33.5 + '@img/sharp-linux-x64': 0.33.5 + '@img/sharp-linuxmusl-arm64': 0.33.5 + '@img/sharp-linuxmusl-x64': 0.33.5 + '@img/sharp-wasm32': 0.33.5 + '@img/sharp-win32-ia32': 0.33.5 + '@img/sharp-win32-x64': 0.33.5 + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 @@ -14545,7 +15187,6 @@ snapshots: simple-swizzle@0.2.2: dependencies: is-arrayish: 0.3.2 - optional: true sirv@3.0.2: dependencies: @@ -14628,6 +15269,8 @@ snapshots: std-env@3.9.0: {} + stoppable@1.1.0: {} + streamx@2.23.0: dependencies: events-universal: 1.0.1 @@ -14948,6 +15591,8 @@ snapshots: dependencies: '@fastify/busboy': 2.1.1 + undici@7.14.0: {} + undici@7.16.0: {} unenv@2.0.0-rc.21: @@ -15494,6 +16139,14 @@ snapshots: word-wrap@1.2.5: {} + workerd@1.20251008.0: + optionalDependencies: + '@cloudflare/workerd-darwin-64': 1.20251008.0 + '@cloudflare/workerd-darwin-arm64': 1.20251008.0 + '@cloudflare/workerd-linux-64': 1.20251008.0 + '@cloudflare/workerd-linux-arm64': 1.20251008.0 + '@cloudflare/workerd-windows-64': 1.20251008.0 + workers-ai-provider@2.0.0(zod@4.1.12): dependencies: '@ai-sdk/provider': 2.0.0 @@ -15501,6 +16154,23 @@ snapshots: transitivePeerDependencies: - zod + wrangler@4.43.0(@cloudflare/workers-types@4.20251011.0): + dependencies: + '@cloudflare/kv-asset-handler': 0.4.0 + '@cloudflare/unenv-preset': 2.7.7(unenv@2.0.0-rc.21)(workerd@1.20251008.0) + blake3-wasm: 2.1.5 + esbuild: 0.25.4 + miniflare: 4.20251008.0 + path-to-regexp: 6.3.0 + unenv: 2.0.0-rc.21 + workerd: 1.20251008.0 + optionalDependencies: + '@cloudflare/workers-types': 4.20251011.0 + fsevents: 2.3.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + wrap-ansi@7.0.0: dependencies: ansi-styles: 4.3.0 @@ -15518,6 +16188,8 @@ snapshots: ws@8.17.1: {} + ws@8.18.0: {} + ws@8.18.3: {} wsl-utils@0.1.0: @@ -15571,6 +16243,14 @@ snapshots: '@poppinss/exception': 1.2.2 error-stack-parser-es: 1.0.5 + youch@4.1.0-beta.10: + dependencies: + '@poppinss/colors': 4.1.5 + '@poppinss/dumper': 0.6.4 + '@speed-highlight/core': 1.2.7 + cookie: 1.0.2 + youch-core: 0.3.3 + youch@4.1.0-beta.11: dependencies: '@poppinss/colors': 4.1.5 @@ -15589,6 +16269,8 @@ snapshots: dependencies: zod: 3.25.76 + zod@3.22.3: {} + zod@3.25.76: {} zod@4.1.12: {} diff --git a/src/features/database.ts b/src/features/database.ts index da1cb562..7ff80a0c 100644 --- a/src/features/database.ts +++ b/src/features/database.ts @@ -1,6 +1,7 @@ import { mkdir } from 'node:fs/promises' import { join } from 'pathe' import { addServerImportsDir, addServerScanDir, addTemplate, addTypeTemplate, logger } from '@nuxt/kit' +import { provider } from 'std-env' import { copyDatabaseMigrationsToHubDir, copyDatabaseQueriesToHubDir } from '../runtime/database/server/utils/migrations/helpers' import { logWhenReady } from '../features' import { resolve } from '../module' @@ -8,14 +9,15 @@ import { resolve } from '../module' import type { Nuxt } from '@nuxt/schema' import type { Nitro } from 'nitropack' import type { HubConfig, ResolvedDatabaseConfig } from '../features' -import type { DatabaseConfig } from '../types/module' +import type { ModuleOptions, DatabaseConfig } from '../types/module' const log = logger.withTag('nuxt:hub') /** * Resolve database configuration from string or object format */ -export function resolveDatabaseConfig(database: string | DatabaseConfig): ResolvedDatabaseConfig { +export async function resolveDatabaseConfig(nuxt: Nuxt, hub: HubConfig, hosting: string): Promise { + const database = ((nuxt.options as any).hub as ModuleOptions).database let dialect: 'sqlite' | 'postgresql' | 'mysql' let connection: Record = {} let driver: string | undefined @@ -26,24 +28,49 @@ export function resolveDatabaseConfig(database: string | DatabaseConfig): Resolv // Auto-detect connection based on environment variables if (dialect === 'sqlite') { + // Tursor Cloud if (process.env.TURSO_DATABASE_URL && process.env.TURSO_AUTH_TOKEN) { connection = { url: process.env.TURSO_DATABASE_URL, authToken: process.env.TURSO_AUTH_TOKEN } - } else { - // Local SQLite - connection will be set later based on hub.dir - connection = {} } - } else if (dialect === 'postgresql') { + // Cloudflare D1 + else if (hosting.includes('cloudflare')) { + driver = 'd1' + nuxt.options.nitro.cloudflare ||= {} + nuxt.options.nitro.cloudflare.deployConfig = true + nuxt.options.nitro.cloudflare.wrangler ||= {} + nuxt.options.nitro.cloudflare.wrangler.d1_databases ||= [] + + let dbBinding = nuxt.options.nitro.cloudflare.wrangler.d1_databases!.find(db => db?.binding === 'DB') + if (!dbBinding) { + dbBinding = { binding: 'DB' } + nuxt.options.nitro.cloudflare.wrangler.d1_databases.push(dbBinding as any) + } + + dbBinding.migrations_table ||= '_hub_migrations' + dbBinding.migrations_dir ||= 'migrations' + } + // Local SQLite + else { + connection = { url: `file:${join(hub.dir!, 'database/sqlite.db')}` } + await mkdir(join(hub.dir!, 'database/sqlite'), { recursive: true }) + } + } + else if (dialect === 'postgresql') { const url = process.env.DATABASE_URL || process.env.POSTGRES_URL || process.env.POSTGRESQL_URL + driver = 'node-postgres' if (url) { connection = { connectionString: url } - } else { - // PGlite - connection will be set later based on hub.dir - connection = {} } - } else if (dialect === 'mysql') { + else { + driver = 'pglite' + connection = { dataDir: join(hub.dir!, 'database/pglite') } + await mkdir(join(hub.dir!, 'database/pglite'), { recursive: true }) + } + } + else if (dialect === 'mysql') { connection = { url: process.env.DATABASE_URL || process.env.MYSQL_URL } if (!connection.url) { throw new Error('MySQL requires DATABASE_URL or MYSQL_URL environment variable') @@ -51,9 +78,9 @@ export function resolveDatabaseConfig(database: string | DatabaseConfig): Resolv } } else { // It's a DatabaseConfig object - dialect = database.dialect - connection = { ...database.connection } - driver = database.driver // Use user-specified driver if provided + dialect = (database as DatabaseConfig).dialect + connection = (database as DatabaseConfig).connection || {} + driver = (database as DatabaseConfig).driver } // Auto-detect driver if not explicitly provided @@ -61,11 +88,7 @@ export function resolveDatabaseConfig(database: string | DatabaseConfig): Resolv if (dialect === 'sqlite') { driver = 'libsql' } else if (dialect === 'postgresql') { - if (connection.connectionString || connection.url || connection.host) { - driver = 'node-postgres' - } else { - driver = 'pglite' - } + driver = 'node-postgres' } else { driver = 'mysql2' } @@ -75,33 +98,12 @@ export function resolveDatabaseConfig(database: string | DatabaseConfig): Resolv } export async function setupDatabase(nuxt: Nuxt, hub: HubConfig, deps: Record) { - // Database config is already resolved in module.ts - const dbConfig = hub.database - if (!dbConfig || typeof dbConfig === 'boolean' || typeof dbConfig === 'string' || !('driver' in dbConfig)) { - throw new Error('Database configuration should be resolved before setupDatabase is called') - } + const hosting = process.env.NITRO_PRESET || nuxt.options.nitro.preset || provider + hub.database = await resolveDatabaseConfig(nuxt, hub, hosting) - const { driver, connection } = dbConfig as ResolvedDatabaseConfig + const { dialect, driver, connection } = hub.database as ResolvedDatabaseConfig - // Set up local storage paths for local databases - if (driver === 'libsql' && !connection.url) { - connection.url = `file:${join(hub.dir!, 'database/sqlite.db')}` - await mkdir(join(hub.dir!, 'database/sqlite'), { recursive: true }) - logWhenReady(nuxt, '`drizzle()` configured with `SQLite` during local development') - } else if (driver === 'libsql' && connection.url && connection.authToken) { - logWhenReady(nuxt, `\`drizzle()\` configured with \`Turso\` using provided \`TURSO_DATABASE_URL\` and \`TURSO_AUTH_TOKEN\``) - } else if (driver === 'pglite' && !connection.connectionString) { - connection.dataDir = join(hub.dir!, 'database/pglite') - await mkdir(join(hub.dir!, 'database/pglite'), { recursive: true }) - logWhenReady(nuxt, '`drizzle()` configured with `PGlite` during local development') - } else if (driver === 'node-postgres' && connection.connectionString) { - const envVarName = process.env.POSTGRES_URL ? 'POSTGRES_URL' : process.env.POSTGRESQL_URL ? 'POSTGRESQL_URL' : 'DATABASE_URL' - logWhenReady(nuxt, `\`drizzle()\` configured with \`PostgreSQL\` using provided \`${envVarName}\``) - } else if (driver === 'mysql2') { - if (!connection.url) { - logWhenReady(nuxt, '`drizzle()` configured with `MySQL` requires DATABASE_URL or MYSQL_URL environment variable', 'warn') - } - } + logWhenReady(nuxt, `\`drizzle()\` using \`${dialect}\` database with \`${driver}\` driver`, 'info') // Verify development database dependencies are installed if (driver === 'node-postgres' && !deps.pg) { @@ -111,7 +113,7 @@ export async function setupDatabase(nuxt: Nuxt, hub: HubConfig, deps: Record = Record>(options?: DrizzleConfig): ReturnType> }` - // Generate simplified drizzle() implementation - let drizzleOrmContent = '' - - if (driver === 'd1') { - // D1 requires binding from environment - drizzleOrmContent = `import { drizzle as drizzleCore } from 'drizzle-orm/d1' + // Generate simplified drizzle() implementation + let drizzleOrmContent = `import { drizzle as drizzleClient } from 'drizzle-orm/${driver}' let _drizzle = null - export function drizzle(options) { - if (_drizzle) return _drizzle - const binding = process.env.DB || globalThis.DB - if (!binding) { - throw new Error('D1 binding "DB" not found') + if (!_drizzle) { + _drizzle = drizzleClient({ connection: ${JSON.stringify(connection)}, ...options }) } - _drizzle = drizzleCore(binding, options) return _drizzle }` - } else { - // All other drivers support connection config - drizzleOrmContent = `import { drizzle as drizzleCore } from 'drizzle-orm/${driver}' -let _drizzle = null + if (driver === 'd1') { + // D1 requires binding from environment + drizzleOrmContent = `import { drizzle as drizzleClient } from 'drizzle-orm/d1' +// import { env } from 'cloudflare:workers' +let _drizzle = null export function drizzle(options) { - if (_drizzle) return _drizzle - _drizzle = drizzleCore({ - connection: ${JSON.stringify(connection)}, - ...options - }) + // if (!env.DB) throw new Error('Cannot find the D1 database attached to DB binding') + if (!_drizzle) { + // _drizzle = drizzleClient(env.DB, options) + const binding = process.env.DB || globalThis.DB + if (!binding) throw new Error('Cannot find the D1 database attached to DB binding') + _drizzle = drizzleClient(binding, options) + } return _drizzle }` - } - - const template = addTemplate({ - filename: 'hub/database.mjs', - getContents: () => drizzleOrmContent, - write: true - }) - nuxt.options.nitro.alias!['#hub/database'] = template.dst - addTypeTemplate({ - filename: 'hub/database.d.ts', - getContents: () => drizzleOrmTypes - }, { nitro: true }) } -} - -export async function setupProductionDatabase(nitro: Nitro, hub: HubConfig, _deps: Record) { - const preset = nitro.options.preset - if (!preset) return - - // Get the resolved database configuration from runtime config - const dbConfig = nitro.options.runtimeConfig?.hub?.database - if (!dbConfig || typeof dbConfig === 'boolean' || typeof dbConfig === 'string') { - log.warn('Database configuration not resolved, skipping production database setup') - return - } - - const { dialect } = dbConfig - let { driver, connection } = dbConfig + if (['node-postgres', 'mysql2'].includes(driver) && hosting.includes('cloudflare')) { + drizzleOrmContent = `import { drizzle as drizzleClient } from 'drizzle-orm/${driver}' - // Override driver based on preset - switch (preset) { - case 'vercel': { - if (dialect === 'postgresql') { - if (connection.connectionString || process.env.POSTGRES_URL || process.env.POSTGRESQL_URL || process.env.DATABASE_URL) { - connection.connectionString = connection.connectionString || process.env.POSTGRES_URL || process.env.POSTGRESQL_URL || process.env.DATABASE_URL - driver = 'node-postgres' - } else { - log.warn('Set POSTGRES_URL, POSTGRESQL_URL, or DATABASE_URL environment variable to configure PostgreSQL database') - if (hub.applyDatabaseMigrationsDuringBuild) { - hub.applyDatabaseMigrationsDuringBuild = false - log.warn('Skipping database migrations - missing database environment variables') - } - } - } else if (dialect === 'mysql') { - if (!connection.url && !process.env.DATABASE_URL && !process.env.MYSQL_URL) { - throw new Error('MySQL requires DATABASE_URL or MYSQL_URL environment variable') - } - connection.url = connection.url || process.env.DATABASE_URL || process.env.MYSQL_URL - driver = 'mysql2' - } else if (dialect === 'sqlite') { - if (process.env.TURSO_DATABASE_URL && process.env.TURSO_AUTH_TOKEN) { - connection = { - url: process.env.TURSO_DATABASE_URL, - authToken: process.env.TURSO_AUTH_TOKEN - } - driver = 'libsql' - } else { - throw new Error('SQLite on Vercel requires Turso (TURSO_DATABASE_URL and TURSO_AUTH_TOKEN)') - } - } - break - } - - case 'cloudflare-module': - case 'cloudflare-durable': - case 'cloudflare-pages': { - nitro.options.cloudflare ||= {} - - if (dialect === 'sqlite') { - if (process.env.TURSO_DATABASE_URL && process.env.TURSO_AUTH_TOKEN) { - connection = { - url: process.env.TURSO_DATABASE_URL, - authToken: process.env.TURSO_AUTH_TOKEN - } - driver = 'libsql' - } else { - // Use D1 - driver = 'd1' - connection = { bindingName: 'DB' } - - log.info(`Ensure a \`DB\` binding is set in your Cloudflare ${preset === 'cloudflare-pages' ? 'Pages' : 'Workers'} configuration`) - - nitro.options.cloudflare.wrangler ||= {} - nitro.options.cloudflare.wrangler.d1_databases ||= [] - - let dbBinding = nitro.options.cloudflare.wrangler.d1_databases.find(db => db.binding === 'DB') - if (!dbBinding) { - dbBinding = { binding: 'DB' } - nitro.options.cloudflare.wrangler.d1_databases.push(dbBinding) - } - - dbBinding.migrations_table ||= '_hub_migrations' - dbBinding.migrations_dir ||= 'migrations' - } - } else if (dialect === 'postgresql') { - driver = 'cloudflare-hyperdrive-postgresql' - connection = { bindingName: 'DB' } - log.info(`Ensure a \`DB\` Hyperdrive binding is set in your Cloudflare ${preset === 'cloudflare-pages' ? 'Pages' : 'Workers'} configuration`) - } else if (dialect === 'mysql') { - driver = 'cloudflare-hyperdrive-mysql' - connection = { bindingName: 'DB' } - log.info(`Ensure a \`DB\` Hyperdrive binding is set in your Cloudflare ${preset === 'cloudflare-pages' ? 'Pages' : 'Workers'} configuration`) - } - - // TODO: D1 migrations via wrangler migrations dir - if (hub.applyDatabaseMigrationsDuringBuild) { - hub.applyDatabaseMigrationsDuringBuild = false - log.warn('Skipping database migrations - Currently Cloudflare is not supported') - } - break - } - - default: { - if (dialect === 'postgresql') { - const url = connection.connectionString || process.env.POSTGRES_URL || process.env.POSTGRESQL_URL || process.env.DATABASE_URL - if (url) { - connection.connectionString = url - driver = 'node-postgres' - } else { - log.info('Set `POSTGRES_URL`, `POSTGRESQL_URL`, or `DATABASE_URL` environment variable to configure PostgreSQL database') - if (hub.applyDatabaseMigrationsDuringBuild) { - hub.applyDatabaseMigrationsDuringBuild = false - log.warn('Skipping database migrations - missing database environment variables') - } - } - } else if (dialect === 'mysql') { - const url = connection.url || process.env.DATABASE_URL || process.env.MYSQL_URL - if (!url) { - throw new Error('MySQL requires DATABASE_URL or MYSQL_URL environment variable') - } - connection.url = url - driver = 'mysql2' - } else if (dialect === 'sqlite') { - if (process.env.TURSO_DATABASE_URL && process.env.TURSO_AUTH_TOKEN) { - connection = { - url: process.env.TURSO_DATABASE_URL, - authToken: process.env.TURSO_AUTH_TOKEN - } - driver = 'libsql' - } else { - connection.url = 'file:.data/database/sqlite.db' - driver = 'libsql' - } - } - break - } +let _drizzle = null +export function drizzle(options) { + if (!_drizzle) { + const hyperdrive = process.env.POSTGRES || globalThis.__env__?.POSTGRES || globalThis.POSTGRES + if (!hyperdrive?.connectionString) throw new Error('Cannot find the Hyperdrive database attached to DB binding') + _drizzle = drizzleClient({ connection: hyperdrive.connectionString, ...options }) } - - // Store the resolved production configuration - nitro.options.runtimeConfig = nitro.options.runtimeConfig || {} - nitro.options.runtimeConfig.hub = nitro.options.runtimeConfig.hub || {} - nitro.options.runtimeConfig.hub.database = { - dialect, - driver, - connection + return _drizzle +}` } - log.info(`\`drizzle()\` configured with \`${driver}\` driver for production`) + const template = addTemplate({ + filename: 'hub/database.mjs', + getContents: () => drizzleOrmContent, + write: true + }) + nuxt.options.nitro.alias!['hub:database'] = template.dst + addTypeTemplate({ + filename: 'hub/database.d.ts', + getContents: () => drizzleOrmTypes + }, { nitro: true }) } diff --git a/src/module.ts b/src/module.ts index 51378c25..f458ce05 100644 --- a/src/module.ts +++ b/src/module.ts @@ -51,14 +51,6 @@ export default defineNuxtModule({ applyDatabaseMigrationsDuringBuild: true }) - // Resolve database configuration if enabled - if (hub.database) { - hub.database = resolveDatabaseConfig(hub.database as string | DatabaseConfig) - } - - runtimeConfig.hub = hub as any - runtimeConfig.public.hub = {} - if (nuxt.options.nitro.preset?.includes('cloudflare')) { nuxt.options.nitro.cloudflare ||= {} nuxt.options.nitro.cloudflare.nodeCompat = true @@ -74,6 +66,11 @@ export default defineNuxtModule({ hub.database && await setupDatabase(nuxt, hub as HubConfig, deps) hub.kv && await setupKV(nuxt, hub as HubConfig, deps) + // @ts-expect-error - runtimeConfig is not typed here + runtimeConfig.hub = hub as HubConfig + runtimeConfig.public.hub ||= {} + + // nuxt prepare, stop here if (nuxt.options._prepare) { return diff --git a/src/runtime/database/server/api/_hub/database/query.post.dev.ts b/src/runtime/database/server/api/_hub/database/query.post.dev.ts index 9ea3c61e..1c227b7c 100644 --- a/src/runtime/database/server/api/_hub/database/query.post.dev.ts +++ b/src/runtime/database/server/api/_hub/database/query.post.dev.ts @@ -15,7 +15,7 @@ export default eventHandler(async (event) => { try { // @ts-expect-error - drizzle is generated dynamically - const { drizzle } = await import('#hub/database') + const { drizzle } = await import('hub:database') const db = drizzle() // Use Drizzle's sql.raw to execute the query diff --git a/src/runtime/database/server/plugins/migrations.dev.ts b/src/runtime/database/server/plugins/migrations.dev.ts index c8687e24..8b3f5b07 100644 --- a/src/runtime/database/server/plugins/migrations.dev.ts +++ b/src/runtime/database/server/plugins/migrations.dev.ts @@ -1,6 +1,6 @@ import { applyDatabaseMigrations, applyDatabaseQueries } from '../utils/migrations/migrations' // @ts-expect-error - Generated at runtime -import { drizzle } from '#hub/database' +import { drizzle } from 'hub:database' // @ts-expect-error - Nitro global export default defineNitroPlugin(async (nitroApp: any) => { diff --git a/src/utils/build.ts b/src/utils/build.ts index ce6329c8..afe0600a 100644 --- a/src/utils/build.ts +++ b/src/utils/build.ts @@ -6,7 +6,6 @@ import type { HubConfig } from '../features' import { setupProductionAI } from '../features/ai' import { setupProductionBlob } from '../features/blob' import { setupProductionCache } from '../features/cache' -import { setupProductionDatabase } from '../features/database' import { setupProductionKV } from '../features/kv' import { copyDatabaseAssets, applyBuildTimeMigrations } from './database' @@ -42,7 +41,6 @@ export function addBuildHooks(nuxt: Nuxt, hub: HubConfig, deps: Record Date: Tue, 21 Oct 2025 16:59:59 +0200 Subject: [PATCH 05/22] up --- pnpm-lock.yaml | 692 +-------------------------------------- src/features/database.ts | 26 +- src/module.ts | 5 +- 3 files changed, 16 insertions(+), 707 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f9517882..f1a08a9c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -256,9 +256,6 @@ importers: '@nuxt/devtools': specifier: latest version: 2.6.5(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)) - wrangler: - specifier: ^4.43.0 - version: 4.43.0(@cloudflare/workers-types@4.20251011.0) packages: @@ -470,52 +467,9 @@ packages: resolution: {integrity: sha512-+tv3z+SPp+gqTIcImN9o0hqE9xyfQjI1XD9pL6NuKjua9B1y7mNYv0S9cP+QEbA4ppVgGZEmKOvHX5G5Ei1CVA==} engines: {node: '>=18.0.0'} - '@cloudflare/unenv-preset@2.7.7': - resolution: {integrity: sha512-HtZuh166y0Olbj9bqqySckz0Rw9uHjggJeoGbDx5x+sgezBXlxO6tQSig2RZw5tgObF8mWI8zaPvQMkQZtAODw==} - peerDependencies: - unenv: 2.0.0-rc.21 - workerd: ^1.20250927.0 - peerDependenciesMeta: - workerd: - optional: true - - '@cloudflare/workerd-darwin-64@1.20251008.0': - resolution: {integrity: sha512-yph0H+8mMOK5Z9oDwjb8rI96oTVt4no5lZ43aorcbzsWG9VUIaXSXlBBoB3von6p4YCRW+J3n36fBM9XZ6TLaA==} - engines: {node: '>=16'} - cpu: [x64] - os: [darwin] - - '@cloudflare/workerd-darwin-arm64@1.20251008.0': - resolution: {integrity: sha512-Yc4lMGSbM4AEtYRpyDpmk77MsHb6X2BSwJgMgGsLVPmckM7ZHivZkJChfcNQjZ/MGR6nkhYc4iF6TcVS+UMEVw==} - engines: {node: '>=16'} - cpu: [arm64] - os: [darwin] - - '@cloudflare/workerd-linux-64@1.20251008.0': - resolution: {integrity: sha512-AjoQnylw4/5G6SmfhZRsli7EuIK7ZMhmbxtU0jkpciTlVV8H01OsFOgS1d8zaTXMfkWamEfMouy8oH/L7B9YcQ==} - engines: {node: '>=16'} - cpu: [x64] - os: [linux] - - '@cloudflare/workerd-linux-arm64@1.20251008.0': - resolution: {integrity: sha512-hRy9yyvzVq1HsqHZUmFkAr0C8JGjAD/PeeVEGCKL3jln3M9sNCKIrbDXiL+efe+EwajJNNlDxpO+s30uVWVaRg==} - engines: {node: '>=16'} - cpu: [arm64] - os: [linux] - - '@cloudflare/workerd-windows-64@1.20251008.0': - resolution: {integrity: sha512-Gm0RR+ehfNMsScn2pUcn3N9PDUpy7FyvV9ecHEyclKttvztyFOcmsF14bxEaSVv7iM4TxWEBn1rclmYHxDM4ow==} - engines: {node: '>=16'} - cpu: [x64] - os: [win32] - '@cloudflare/workers-types@4.20251011.0': resolution: {integrity: sha512-gQpih+pbq3sP4uXltUeCSbPgZxTNp2gQd8639SaIbQMwgA6oJNHLhIART1fWy6DQACngiRzDVULA2x0ohmkGTQ==} - '@cspotcode/source-map-support@0.8.1': - resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} - engines: {node: '>=12'} - '@electric-sql/pglite@0.3.11': resolution: {integrity: sha512-FJtjnEyez8XgmgyE5Ewmx89TGVN+75ZjykFoExApRIbJBMT4dsbsuZkF/YWLuymGDfGFHDACjvENPMEqg4FoWg==} @@ -538,252 +492,126 @@ packages: cpu: [ppc64] os: [aix] - '@esbuild/aix-ppc64@0.25.4': - resolution: {integrity: sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [aix] - '@esbuild/android-arm64@0.25.10': resolution: {integrity: sha512-LSQa7eDahypv/VO6WKohZGPSJDq5OVOo3UoFR1E4t4Gj1W7zEQMUhI+lo81H+DtB+kP+tDgBp+M4oNCwp6kffg==} engines: {node: '>=18'} cpu: [arm64] os: [android] - '@esbuild/android-arm64@0.25.4': - resolution: {integrity: sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A==} - engines: {node: '>=18'} - cpu: [arm64] - os: [android] - '@esbuild/android-arm@0.25.10': resolution: {integrity: sha512-dQAxF1dW1C3zpeCDc5KqIYuZ1tgAdRXNoZP7vkBIRtKZPYe2xVr/d3SkirklCHudW1B45tGiUlz2pUWDfbDD4w==} engines: {node: '>=18'} cpu: [arm] os: [android] - '@esbuild/android-arm@0.25.4': - resolution: {integrity: sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ==} - engines: {node: '>=18'} - cpu: [arm] - os: [android] - '@esbuild/android-x64@0.25.10': resolution: {integrity: sha512-MiC9CWdPrfhibcXwr39p9ha1x0lZJ9KaVfvzA0Wxwz9ETX4v5CHfF09bx935nHlhi+MxhA63dKRRQLiVgSUtEg==} engines: {node: '>=18'} cpu: [x64] os: [android] - '@esbuild/android-x64@0.25.4': - resolution: {integrity: sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [android] - '@esbuild/darwin-arm64@0.25.10': resolution: {integrity: sha512-JC74bdXcQEpW9KkV326WpZZjLguSZ3DfS8wrrvPMHgQOIEIG/sPXEN/V8IssoJhbefLRcRqw6RQH2NnpdprtMA==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] - '@esbuild/darwin-arm64@0.25.4': - resolution: {integrity: sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g==} - engines: {node: '>=18'} - cpu: [arm64] - os: [darwin] - '@esbuild/darwin-x64@0.25.10': resolution: {integrity: sha512-tguWg1olF6DGqzws97pKZ8G2L7Ig1vjDmGTwcTuYHbuU6TTjJe5FXbgs5C1BBzHbJ2bo1m3WkQDbWO2PvamRcg==} engines: {node: '>=18'} cpu: [x64] os: [darwin] - '@esbuild/darwin-x64@0.25.4': - resolution: {integrity: sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A==} - engines: {node: '>=18'} - cpu: [x64] - os: [darwin] - '@esbuild/freebsd-arm64@0.25.10': resolution: {integrity: sha512-3ZioSQSg1HT2N05YxeJWYR+Libe3bREVSdWhEEgExWaDtyFbbXWb49QgPvFH8u03vUPX10JhJPcz7s9t9+boWg==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-arm64@0.25.4': - resolution: {integrity: sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [freebsd] - '@esbuild/freebsd-x64@0.25.10': resolution: {integrity: sha512-LLgJfHJk014Aa4anGDbh8bmI5Lk+QidDmGzuC2D+vP7mv/GeSN+H39zOf7pN5N8p059FcOfs2bVlrRr4SK9WxA==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] - '@esbuild/freebsd-x64@0.25.4': - resolution: {integrity: sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [freebsd] - '@esbuild/linux-arm64@0.25.10': resolution: {integrity: sha512-5luJWN6YKBsawd5f9i4+c+geYiVEw20FVW5x0v1kEMWNq8UctFjDiMATBxLvmmHA4bf7F6hTRaJgtghFr9iziQ==} engines: {node: '>=18'} cpu: [arm64] os: [linux] - '@esbuild/linux-arm64@0.25.4': - resolution: {integrity: sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [linux] - '@esbuild/linux-arm@0.25.10': resolution: {integrity: sha512-oR31GtBTFYCqEBALI9r6WxoU/ZofZl962pouZRTEYECvNF/dtXKku8YXcJkhgK/beU+zedXfIzHijSRapJY3vg==} engines: {node: '>=18'} cpu: [arm] os: [linux] - '@esbuild/linux-arm@0.25.4': - resolution: {integrity: sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ==} - engines: {node: '>=18'} - cpu: [arm] - os: [linux] - '@esbuild/linux-ia32@0.25.10': resolution: {integrity: sha512-NrSCx2Kim3EnnWgS4Txn0QGt0Xipoumb6z6sUtl5bOEZIVKhzfyp/Lyw4C1DIYvzeW/5mWYPBFJU3a/8Yr75DQ==} engines: {node: '>=18'} cpu: [ia32] os: [linux] - '@esbuild/linux-ia32@0.25.4': - resolution: {integrity: sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ==} - engines: {node: '>=18'} - cpu: [ia32] - os: [linux] - '@esbuild/linux-loong64@0.25.10': resolution: {integrity: sha512-xoSphrd4AZda8+rUDDfD9J6FUMjrkTz8itpTITM4/xgerAZZcFW7Dv+sun7333IfKxGG8gAq+3NbfEMJfiY+Eg==} engines: {node: '>=18'} cpu: [loong64] os: [linux] - '@esbuild/linux-loong64@0.25.4': - resolution: {integrity: sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA==} - engines: {node: '>=18'} - cpu: [loong64] - os: [linux] - '@esbuild/linux-mips64el@0.25.10': resolution: {integrity: sha512-ab6eiuCwoMmYDyTnyptoKkVS3k8fy/1Uvq7Dj5czXI6DF2GqD2ToInBI0SHOp5/X1BdZ26RKc5+qjQNGRBelRA==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] - '@esbuild/linux-mips64el@0.25.4': - resolution: {integrity: sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg==} - engines: {node: '>=18'} - cpu: [mips64el] - os: [linux] - '@esbuild/linux-ppc64@0.25.10': resolution: {integrity: sha512-NLinzzOgZQsGpsTkEbdJTCanwA5/wozN9dSgEl12haXJBzMTpssebuXR42bthOF3z7zXFWH1AmvWunUCkBE4EA==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] - '@esbuild/linux-ppc64@0.25.4': - resolution: {integrity: sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [linux] - '@esbuild/linux-riscv64@0.25.10': resolution: {integrity: sha512-FE557XdZDrtX8NMIeA8LBJX3dC2M8VGXwfrQWU7LB5SLOajfJIxmSdyL/gU1m64Zs9CBKvm4UAuBp5aJ8OgnrA==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] - '@esbuild/linux-riscv64@0.25.4': - resolution: {integrity: sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA==} - engines: {node: '>=18'} - cpu: [riscv64] - os: [linux] - '@esbuild/linux-s390x@0.25.10': resolution: {integrity: sha512-3BBSbgzuB9ajLoVZk0mGu+EHlBwkusRmeNYdqmznmMc9zGASFjSsxgkNsqmXugpPk00gJ0JNKh/97nxmjctdew==} engines: {node: '>=18'} cpu: [s390x] os: [linux] - '@esbuild/linux-s390x@0.25.4': - resolution: {integrity: sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g==} - engines: {node: '>=18'} - cpu: [s390x] - os: [linux] - '@esbuild/linux-x64@0.25.10': resolution: {integrity: sha512-QSX81KhFoZGwenVyPoberggdW1nrQZSvfVDAIUXr3WqLRZGZqWk/P4T8p2SP+de2Sr5HPcvjhcJzEiulKgnxtA==} engines: {node: '>=18'} cpu: [x64] os: [linux] - '@esbuild/linux-x64@0.25.4': - resolution: {integrity: sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA==} - engines: {node: '>=18'} - cpu: [x64] - os: [linux] - '@esbuild/netbsd-arm64@0.25.10': resolution: {integrity: sha512-AKQM3gfYfSW8XRk8DdMCzaLUFB15dTrZfnX8WXQoOUpUBQ+NaAFCP1kPS/ykbbGYz7rxn0WS48/81l9hFl3u4A==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] - '@esbuild/netbsd-arm64@0.25.4': - resolution: {integrity: sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [netbsd] - '@esbuild/netbsd-x64@0.25.10': resolution: {integrity: sha512-7RTytDPGU6fek/hWuN9qQpeGPBZFfB4zZgcz2VK2Z5VpdUxEI8JKYsg3JfO0n/Z1E/6l05n0unDCNc4HnhQGig==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] - '@esbuild/netbsd-x64@0.25.4': - resolution: {integrity: sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw==} - engines: {node: '>=18'} - cpu: [x64] - os: [netbsd] - '@esbuild/openbsd-arm64@0.25.10': resolution: {integrity: sha512-5Se0VM9Wtq797YFn+dLimf2Zx6McttsH2olUBsDml+lm0GOCRVebRWUvDtkY4BWYv/3NgzS8b/UM3jQNh5hYyw==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-arm64@0.25.4': - resolution: {integrity: sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openbsd] - '@esbuild/openbsd-x64@0.25.10': resolution: {integrity: sha512-XkA4frq1TLj4bEMB+2HnI0+4RnjbuGZfet2gs/LNs5Hc7D89ZQBHQ0gL2ND6Lzu1+QVkjp3x1gIcPKzRNP8bXw==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] - '@esbuild/openbsd-x64@0.25.4': - resolution: {integrity: sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw==} - engines: {node: '>=18'} - cpu: [x64] - os: [openbsd] - '@esbuild/openharmony-arm64@0.25.10': resolution: {integrity: sha512-AVTSBhTX8Y/Fz6OmIVBip9tJzZEUcY8WLh7I59+upa5/GPhh2/aM6bvOMQySspnCCHvFi79kMtdJS1w0DXAeag==} engines: {node: '>=18'} @@ -796,48 +624,24 @@ packages: cpu: [x64] os: [sunos] - '@esbuild/sunos-x64@0.25.4': - resolution: {integrity: sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q==} - engines: {node: '>=18'} - cpu: [x64] - os: [sunos] - '@esbuild/win32-arm64@0.25.10': resolution: {integrity: sha512-ah+9b59KDTSfpaCg6VdJoOQvKjI33nTaQr4UluQwW7aEwZQsbMCfTmfEO4VyewOxx4RaDT/xCy9ra2GPWmO7Kw==} engines: {node: '>=18'} cpu: [arm64] os: [win32] - '@esbuild/win32-arm64@0.25.4': - resolution: {integrity: sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [win32] - '@esbuild/win32-ia32@0.25.10': resolution: {integrity: sha512-QHPDbKkrGO8/cz9LKVnJU22HOi4pxZnZhhA2HYHez5Pz4JeffhDjf85E57Oyco163GnzNCVkZK0b/n4Y0UHcSw==} engines: {node: '>=18'} cpu: [ia32] os: [win32] - '@esbuild/win32-ia32@0.25.4': - resolution: {integrity: sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg==} - engines: {node: '>=18'} - cpu: [ia32] - os: [win32] - '@esbuild/win32-x64@0.25.10': resolution: {integrity: sha512-9KpxSVFCu0iK1owoez6aC/s/EdUQLDN3adTxGCqxMVhrPDj6bt5dbrHDXUuq+Bs2vATFBBrQS5vdQ/Ed2P+nbw==} engines: {node: '>=18'} cpu: [x64] os: [win32] - '@esbuild/win32-x64@0.25.4': - resolution: {integrity: sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [win32] - '@eslint-community/eslint-utils@4.8.0': resolution: {integrity: sha512-MJQFqrZgcW0UNYLGOuQpey/oTN59vyWwplvCGZztn1cKz9agZPPYpJB7h2OMmuu7VLqkvEjN8feFZJmxNF9D+Q==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -977,111 +781,6 @@ packages: peerDependencies: vue: '>=3' - '@img/sharp-darwin-arm64@0.33.5': - resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [darwin] - - '@img/sharp-darwin-x64@0.33.5': - resolution: {integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [darwin] - - '@img/sharp-libvips-darwin-arm64@1.0.4': - resolution: {integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==} - cpu: [arm64] - os: [darwin] - - '@img/sharp-libvips-darwin-x64@1.0.4': - resolution: {integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==} - cpu: [x64] - os: [darwin] - - '@img/sharp-libvips-linux-arm64@1.0.4': - resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==} - cpu: [arm64] - os: [linux] - - '@img/sharp-libvips-linux-arm@1.0.5': - resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==} - cpu: [arm] - os: [linux] - - '@img/sharp-libvips-linux-s390x@1.0.4': - resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==} - cpu: [s390x] - os: [linux] - - '@img/sharp-libvips-linux-x64@1.0.4': - resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==} - cpu: [x64] - os: [linux] - - '@img/sharp-libvips-linuxmusl-arm64@1.0.4': - resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==} - cpu: [arm64] - os: [linux] - - '@img/sharp-libvips-linuxmusl-x64@1.0.4': - resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==} - cpu: [x64] - os: [linux] - - '@img/sharp-linux-arm64@0.33.5': - resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [linux] - - '@img/sharp-linux-arm@0.33.5': - resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm] - os: [linux] - - '@img/sharp-linux-s390x@0.33.5': - resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [s390x] - os: [linux] - - '@img/sharp-linux-x64@0.33.5': - resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [linux] - - '@img/sharp-linuxmusl-arm64@0.33.5': - resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [linux] - - '@img/sharp-linuxmusl-x64@0.33.5': - resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [linux] - - '@img/sharp-wasm32@0.33.5': - resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [wasm32] - - '@img/sharp-win32-ia32@0.33.5': - resolution: {integrity: sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [ia32] - os: [win32] - - '@img/sharp-win32-x64@0.33.5': - resolution: {integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [win32] - '@internationalized/date@3.10.0': resolution: {integrity: sha512-oxDR/NTEJ1k+UFVQElaNIk65E/Z83HK1z1WI3lQyhTtnNg4R5oVXaPzK3jcpKG8UHKDVuDQHzn+wsxSz8RP3aw==} @@ -1129,9 +828,6 @@ packages: '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} - '@jridgewell/trace-mapping@0.3.9': - resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} - '@jsdevtools/ono@7.1.3': resolution: {integrity: sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==} @@ -3351,15 +3047,6 @@ packages: peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - acorn-walk@8.3.2: - resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==} - engines: {node: '>=0.4.0'} - - acorn@8.14.0: - resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==} - engines: {node: '>=0.4.0'} - hasBin: true - acorn@8.15.0: resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} engines: {node: '>=0.4.0'} @@ -3545,9 +3232,6 @@ packages: bl@4.1.0: resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} - blake3-wasm@2.1.5: - resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==} - blob-to-buffer@1.2.9: resolution: {integrity: sha512-BF033y5fN6OCofD3vgHmNtwZWRcq9NLyyxyILx9hfMy1sXYy4ojFl765hJ2lP0YaN2fuxPaLO2Vzzoxy0FLFFA==} @@ -4285,11 +3969,6 @@ packages: engines: {node: '>=18'} hasBin: true - esbuild@0.25.4: - resolution: {integrity: sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q==} - engines: {node: '>=18'} - hasBin: true - escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} @@ -4464,10 +4143,6 @@ packages: resolution: {integrity: sha512-jpWzZ1ZhwUmeWRhS7Qv3mhpOhLfwI+uAX4e5fOcXqwMR7EcJ0pj2kV1CVzHVMX/LphnKWD3LObjZCoJ71lKpHw==} engines: {node: ^18.19.0 || >=20.5.0} - exit-hook@2.2.1: - resolution: {integrity: sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==} - engines: {node: '>=6'} - expand-template@2.0.3: resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} engines: {node: '>=6'} @@ -4670,9 +4345,6 @@ packages: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} - glob-to-regexp@0.4.1: - resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} - glob@10.4.5: resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} hasBin: true @@ -5421,11 +5093,6 @@ packages: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} engines: {node: '>=4'} - miniflare@4.20251008.0: - resolution: {integrity: sha512-sKCNYNzXG6l8qg0Oo7y8WcDKcpbgw0qwZsxNpdZilFTR4EavRow2TlcwuPSVN99jqAjhz0M4VXvTdSGdtJ2VfQ==} - engines: {node: '>=18.0.0'} - hasBin: true - minimark@0.2.0: resolution: {integrity: sha512-AmtWU9pO0C2/3AM2pikaVhJ//8E5rOpJ7+ioFQfjIq+wCsBeuZoxPd97hBFZ9qrI7DMHZudwGH3r8A7BMnsIew==} @@ -5841,9 +5508,6 @@ packages: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} - path-to-regexp@6.3.0: - resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} - path-type@6.0.0: resolution: {integrity: sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==} engines: {node: '>=18'} @@ -6473,10 +6137,6 @@ packages: resolution: {integrity: sha512-KyLTWwgcR9Oe4d9HwCwNM2l7+J0dUQwn/yf7S0EnTtb0eVS4RxO0eUSvxPtzT4F3SY+C4K6fqdv/DO27sJ/v/w==} engines: {node: '>=14.15.0'} - sharp@0.33.5: - resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -6607,10 +6267,6 @@ packages: std-env@3.9.0: resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==} - stoppable@1.1.0: - resolution: {integrity: sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==} - engines: {node: '>=4', npm: '>=6'} - streamx@2.23.0: resolution: {integrity: sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg==} @@ -6903,10 +6559,6 @@ packages: resolution: {integrity: sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==} engines: {node: '>=14.0'} - undici@7.14.0: - resolution: {integrity: sha512-Vqs8HTzjpQXZeXdpsfChQTlafcMQaaIwnGwLam1wudSSjlJeQ3bw1j+TLPePgrCnCpUXx7Ba5Pdpf5OBih62NQ==} - engines: {node: '>=20.18.1'} - undici@7.16.0: resolution: {integrity: sha512-QEg3HPMll0o3t2ourKwOeUAZ159Kn9mx5pnzHRQO8+Wixmh88YdZRiIwat0iNzNNXn0yoEtXJqFpyW7eM8BV7g==} engines: {node: '>=20.18.1'} @@ -7413,24 +7065,9 @@ packages: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} - workerd@1.20251008.0: - resolution: {integrity: sha512-HwaJmXO3M1r4S8x2ea2vy8Rw/y/38HRQuK/gNDRQ7w9cJXn6xSl1sIIqKCffULSUjul3wV3I3Nd/GfbmsRReEA==} - engines: {node: '>=16'} - hasBin: true - workers-ai-provider@2.0.0: resolution: {integrity: sha512-AoGGy8aOR3lzCzRouSxA6mgrCKuZfrnzxvOHHy9kOzwz4Mm4Hb55a/9G8zz+v0I/mn8bYLs/4I6JABSl/zXJ7w==} - wrangler@4.43.0: - resolution: {integrity: sha512-IBNqXlYHSUSCNNWj/tQN4hFiQy94l7fTxEnJWETXyW69+cjUyjQ7MfeoId3vIV9KBgY8y5M5uf2XulU95OikJg==} - engines: {node: '>=18.0.0'} - hasBin: true - peerDependencies: - '@cloudflare/workers-types': ^4.20251008.0 - peerDependenciesMeta: - '@cloudflare/workers-types': - optional: true - wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} @@ -7454,18 +7091,6 @@ packages: utf-8-validate: optional: true - ws@8.18.0: - resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: '>=5.0.2' - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - ws@8.18.3: resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} engines: {node: '>=10.0.0'} @@ -7541,9 +7166,6 @@ packages: youch-core@0.3.3: resolution: {integrity: sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA==} - youch@4.1.0-beta.10: - resolution: {integrity: sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ==} - youch@4.1.0-beta.11: resolution: {integrity: sha512-sQi6PERyO/mT8w564ojOVeAlYTtVQmC2GaktQAf+IdI75/GKIggosBuvyVXvEV+FATAT6RbLdIjFoiIId4ozoQ==} @@ -7556,9 +7178,6 @@ packages: peerDependencies: zod: ^3.24.1 - zod@3.22.3: - resolution: {integrity: sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug==} - zod@3.25.76: resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} @@ -7855,33 +7474,8 @@ snapshots: dependencies: mime: 3.0.0 - '@cloudflare/unenv-preset@2.7.7(unenv@2.0.0-rc.21)(workerd@1.20251008.0)': - dependencies: - unenv: 2.0.0-rc.21 - optionalDependencies: - workerd: 1.20251008.0 - - '@cloudflare/workerd-darwin-64@1.20251008.0': - optional: true - - '@cloudflare/workerd-darwin-arm64@1.20251008.0': - optional: true - - '@cloudflare/workerd-linux-64@1.20251008.0': - optional: true - - '@cloudflare/workerd-linux-arm64@1.20251008.0': - optional: true - - '@cloudflare/workerd-windows-64@1.20251008.0': - optional: true - '@cloudflare/workers-types@4.20251011.0': {} - '@cspotcode/source-map-support@0.8.1': - dependencies: - '@jridgewell/trace-mapping': 0.3.9 - '@electric-sql/pglite@0.3.11': {} '@emnapi/core@1.5.0': @@ -7911,156 +7505,81 @@ snapshots: '@esbuild/aix-ppc64@0.25.10': optional: true - '@esbuild/aix-ppc64@0.25.4': - optional: true - '@esbuild/android-arm64@0.25.10': optional: true - '@esbuild/android-arm64@0.25.4': - optional: true - '@esbuild/android-arm@0.25.10': optional: true - '@esbuild/android-arm@0.25.4': - optional: true - '@esbuild/android-x64@0.25.10': optional: true - '@esbuild/android-x64@0.25.4': - optional: true - '@esbuild/darwin-arm64@0.25.10': optional: true - '@esbuild/darwin-arm64@0.25.4': - optional: true - '@esbuild/darwin-x64@0.25.10': optional: true - '@esbuild/darwin-x64@0.25.4': - optional: true - '@esbuild/freebsd-arm64@0.25.10': optional: true - '@esbuild/freebsd-arm64@0.25.4': - optional: true - '@esbuild/freebsd-x64@0.25.10': optional: true - '@esbuild/freebsd-x64@0.25.4': - optional: true - '@esbuild/linux-arm64@0.25.10': optional: true - '@esbuild/linux-arm64@0.25.4': - optional: true - '@esbuild/linux-arm@0.25.10': optional: true - '@esbuild/linux-arm@0.25.4': - optional: true - '@esbuild/linux-ia32@0.25.10': optional: true - '@esbuild/linux-ia32@0.25.4': - optional: true - '@esbuild/linux-loong64@0.25.10': optional: true - '@esbuild/linux-loong64@0.25.4': - optional: true - '@esbuild/linux-mips64el@0.25.10': optional: true - '@esbuild/linux-mips64el@0.25.4': - optional: true - '@esbuild/linux-ppc64@0.25.10': optional: true - '@esbuild/linux-ppc64@0.25.4': - optional: true - '@esbuild/linux-riscv64@0.25.10': optional: true - '@esbuild/linux-riscv64@0.25.4': - optional: true - '@esbuild/linux-s390x@0.25.10': optional: true - '@esbuild/linux-s390x@0.25.4': - optional: true - '@esbuild/linux-x64@0.25.10': optional: true - '@esbuild/linux-x64@0.25.4': - optional: true - '@esbuild/netbsd-arm64@0.25.10': optional: true - '@esbuild/netbsd-arm64@0.25.4': - optional: true - '@esbuild/netbsd-x64@0.25.10': optional: true - '@esbuild/netbsd-x64@0.25.4': - optional: true - '@esbuild/openbsd-arm64@0.25.10': optional: true - '@esbuild/openbsd-arm64@0.25.4': - optional: true - '@esbuild/openbsd-x64@0.25.10': optional: true - '@esbuild/openbsd-x64@0.25.4': - optional: true - '@esbuild/openharmony-arm64@0.25.10': optional: true '@esbuild/sunos-x64@0.25.10': optional: true - '@esbuild/sunos-x64@0.25.4': - optional: true - '@esbuild/win32-arm64@0.25.10': optional: true - '@esbuild/win32-arm64@0.25.4': - optional: true - '@esbuild/win32-ia32@0.25.10': optional: true - '@esbuild/win32-ia32@0.25.4': - optional: true - '@esbuild/win32-x64@0.25.10': optional: true - '@esbuild/win32-x64@0.25.4': - optional: true - '@eslint-community/eslint-utils@4.8.0(eslint@9.37.0(jiti@2.6.1))': dependencies: eslint: 9.37.0(jiti@2.6.1) @@ -8221,81 +7740,6 @@ snapshots: '@iconify/types': 2.0.0 vue: 3.5.22(typescript@5.9.3) - '@img/sharp-darwin-arm64@0.33.5': - optionalDependencies: - '@img/sharp-libvips-darwin-arm64': 1.0.4 - optional: true - - '@img/sharp-darwin-x64@0.33.5': - optionalDependencies: - '@img/sharp-libvips-darwin-x64': 1.0.4 - optional: true - - '@img/sharp-libvips-darwin-arm64@1.0.4': - optional: true - - '@img/sharp-libvips-darwin-x64@1.0.4': - optional: true - - '@img/sharp-libvips-linux-arm64@1.0.4': - optional: true - - '@img/sharp-libvips-linux-arm@1.0.5': - optional: true - - '@img/sharp-libvips-linux-s390x@1.0.4': - optional: true - - '@img/sharp-libvips-linux-x64@1.0.4': - optional: true - - '@img/sharp-libvips-linuxmusl-arm64@1.0.4': - optional: true - - '@img/sharp-libvips-linuxmusl-x64@1.0.4': - optional: true - - '@img/sharp-linux-arm64@0.33.5': - optionalDependencies: - '@img/sharp-libvips-linux-arm64': 1.0.4 - optional: true - - '@img/sharp-linux-arm@0.33.5': - optionalDependencies: - '@img/sharp-libvips-linux-arm': 1.0.5 - optional: true - - '@img/sharp-linux-s390x@0.33.5': - optionalDependencies: - '@img/sharp-libvips-linux-s390x': 1.0.4 - optional: true - - '@img/sharp-linux-x64@0.33.5': - optionalDependencies: - '@img/sharp-libvips-linux-x64': 1.0.4 - optional: true - - '@img/sharp-linuxmusl-arm64@0.33.5': - optionalDependencies: - '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 - optional: true - - '@img/sharp-linuxmusl-x64@0.33.5': - optionalDependencies: - '@img/sharp-libvips-linuxmusl-x64': 1.0.4 - optional: true - - '@img/sharp-wasm32@0.33.5': - dependencies: - '@emnapi/runtime': 1.5.0 - optional: true - - '@img/sharp-win32-ia32@0.33.5': - optional: true - - '@img/sharp-win32-x64@0.33.5': - optional: true - '@internationalized/date@3.10.0': dependencies: '@swc/helpers': 0.5.17 @@ -8354,11 +7798,6 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 - '@jridgewell/trace-mapping@0.3.9': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.5 - '@jsdevtools/ono@7.1.3': {} '@kgierke/nuxt-basic-auth@1.7.0(magicast@0.3.5)': @@ -11083,10 +10522,6 @@ snapshots: dependencies: acorn: 8.15.0 - acorn-walk@8.3.2: {} - - acorn@8.14.0: {} - acorn@8.15.0: {} agent-base@7.1.4: {} @@ -11275,8 +10710,6 @@ snapshots: readable-stream: 3.6.2 optional: true - blake3-wasm@2.1.5: {} - blob-to-buffer@1.2.9: {} boolbase@1.0.0: {} @@ -11490,11 +10923,13 @@ snapshots: dependencies: color-name: 1.1.4 simple-swizzle: 0.2.2 + optional: true color@4.2.3: dependencies: color-convert: 2.0.1 color-string: 1.9.1 + optional: true colord@2.9.3: {} @@ -11912,34 +11347,6 @@ snapshots: '@esbuild/win32-ia32': 0.25.10 '@esbuild/win32-x64': 0.25.10 - esbuild@0.25.4: - optionalDependencies: - '@esbuild/aix-ppc64': 0.25.4 - '@esbuild/android-arm': 0.25.4 - '@esbuild/android-arm64': 0.25.4 - '@esbuild/android-x64': 0.25.4 - '@esbuild/darwin-arm64': 0.25.4 - '@esbuild/darwin-x64': 0.25.4 - '@esbuild/freebsd-arm64': 0.25.4 - '@esbuild/freebsd-x64': 0.25.4 - '@esbuild/linux-arm': 0.25.4 - '@esbuild/linux-arm64': 0.25.4 - '@esbuild/linux-ia32': 0.25.4 - '@esbuild/linux-loong64': 0.25.4 - '@esbuild/linux-mips64el': 0.25.4 - '@esbuild/linux-ppc64': 0.25.4 - '@esbuild/linux-riscv64': 0.25.4 - '@esbuild/linux-s390x': 0.25.4 - '@esbuild/linux-x64': 0.25.4 - '@esbuild/netbsd-arm64': 0.25.4 - '@esbuild/netbsd-x64': 0.25.4 - '@esbuild/openbsd-arm64': 0.25.4 - '@esbuild/openbsd-x64': 0.25.4 - '@esbuild/sunos-x64': 0.25.4 - '@esbuild/win32-arm64': 0.25.4 - '@esbuild/win32-ia32': 0.25.4 - '@esbuild/win32-x64': 0.25.4 - escalade@3.2.0: {} escape-html@1.0.3: {} @@ -12178,8 +11585,6 @@ snapshots: strip-final-newline: 4.0.0 yoctocolors: 2.1.2 - exit-hook@2.2.1: {} - expand-template@2.0.3: optional: true @@ -12372,8 +11777,6 @@ snapshots: dependencies: is-glob: 4.0.3 - glob-to-regexp@0.4.1: {} - glob@10.4.5: dependencies: foreground-child: 3.3.1 @@ -12705,7 +12108,8 @@ snapshots: is-alphabetical: 2.0.1 is-decimal: 2.0.1 - is-arrayish@0.3.2: {} + is-arrayish@0.3.2: + optional: true is-binary-path@2.1.0: dependencies: @@ -13375,24 +12779,6 @@ snapshots: min-indent@1.0.1: {} - miniflare@4.20251008.0: - dependencies: - '@cspotcode/source-map-support': 0.8.1 - acorn: 8.14.0 - acorn-walk: 8.3.2 - exit-hook: 2.2.1 - glob-to-regexp: 0.4.1 - sharp: 0.33.5 - stoppable: 1.1.0 - undici: 7.14.0 - workerd: 1.20251008.0 - ws: 8.18.0 - youch: 4.1.0-beta.10 - zod: 3.22.3 - transitivePeerDependencies: - - bufferutil - - utf-8-validate - minimark@0.2.0: {} minimatch@10.0.3: @@ -14301,8 +13687,6 @@ snapshots: lru-cache: 10.4.3 minipass: 7.1.2 - path-to-regexp@6.3.0: {} - path-type@6.0.0: {} pathe@1.1.2: {} @@ -15117,32 +14501,6 @@ snapshots: - react-native-b4a optional: true - sharp@0.33.5: - dependencies: - color: 4.2.3 - detect-libc: 2.1.2 - semver: 7.7.3 - optionalDependencies: - '@img/sharp-darwin-arm64': 0.33.5 - '@img/sharp-darwin-x64': 0.33.5 - '@img/sharp-libvips-darwin-arm64': 1.0.4 - '@img/sharp-libvips-darwin-x64': 1.0.4 - '@img/sharp-libvips-linux-arm': 1.0.5 - '@img/sharp-libvips-linux-arm64': 1.0.4 - '@img/sharp-libvips-linux-s390x': 1.0.4 - '@img/sharp-libvips-linux-x64': 1.0.4 - '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 - '@img/sharp-libvips-linuxmusl-x64': 1.0.4 - '@img/sharp-linux-arm': 0.33.5 - '@img/sharp-linux-arm64': 0.33.5 - '@img/sharp-linux-s390x': 0.33.5 - '@img/sharp-linux-x64': 0.33.5 - '@img/sharp-linuxmusl-arm64': 0.33.5 - '@img/sharp-linuxmusl-x64': 0.33.5 - '@img/sharp-wasm32': 0.33.5 - '@img/sharp-win32-ia32': 0.33.5 - '@img/sharp-win32-x64': 0.33.5 - shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 @@ -15187,6 +14545,7 @@ snapshots: simple-swizzle@0.2.2: dependencies: is-arrayish: 0.3.2 + optional: true sirv@3.0.2: dependencies: @@ -15269,8 +14628,6 @@ snapshots: std-env@3.9.0: {} - stoppable@1.1.0: {} - streamx@2.23.0: dependencies: events-universal: 1.0.1 @@ -15591,8 +14948,6 @@ snapshots: dependencies: '@fastify/busboy': 2.1.1 - undici@7.14.0: {} - undici@7.16.0: {} unenv@2.0.0-rc.21: @@ -16139,14 +15494,6 @@ snapshots: word-wrap@1.2.5: {} - workerd@1.20251008.0: - optionalDependencies: - '@cloudflare/workerd-darwin-64': 1.20251008.0 - '@cloudflare/workerd-darwin-arm64': 1.20251008.0 - '@cloudflare/workerd-linux-64': 1.20251008.0 - '@cloudflare/workerd-linux-arm64': 1.20251008.0 - '@cloudflare/workerd-windows-64': 1.20251008.0 - workers-ai-provider@2.0.0(zod@4.1.12): dependencies: '@ai-sdk/provider': 2.0.0 @@ -16154,23 +15501,6 @@ snapshots: transitivePeerDependencies: - zod - wrangler@4.43.0(@cloudflare/workers-types@4.20251011.0): - dependencies: - '@cloudflare/kv-asset-handler': 0.4.0 - '@cloudflare/unenv-preset': 2.7.7(unenv@2.0.0-rc.21)(workerd@1.20251008.0) - blake3-wasm: 2.1.5 - esbuild: 0.25.4 - miniflare: 4.20251008.0 - path-to-regexp: 6.3.0 - unenv: 2.0.0-rc.21 - workerd: 1.20251008.0 - optionalDependencies: - '@cloudflare/workers-types': 4.20251011.0 - fsevents: 2.3.3 - transitivePeerDependencies: - - bufferutil - - utf-8-validate - wrap-ansi@7.0.0: dependencies: ansi-styles: 4.3.0 @@ -16188,8 +15518,6 @@ snapshots: ws@8.17.1: {} - ws@8.18.0: {} - ws@8.18.3: {} wsl-utils@0.1.0: @@ -16243,14 +15571,6 @@ snapshots: '@poppinss/exception': 1.2.2 error-stack-parser-es: 1.0.5 - youch@4.1.0-beta.10: - dependencies: - '@poppinss/colors': 4.1.5 - '@poppinss/dumper': 0.6.4 - '@speed-highlight/core': 1.2.7 - cookie: 1.0.2 - youch-core: 0.3.3 - youch@4.1.0-beta.11: dependencies: '@poppinss/colors': 4.1.5 @@ -16269,8 +15589,6 @@ snapshots: dependencies: zod: 3.25.76 - zod@3.22.3: {} - zod@3.25.76: {} zod@4.1.12: {} diff --git a/src/features/database.ts b/src/features/database.ts index 7ff80a0c..88cb7e27 100644 --- a/src/features/database.ts +++ b/src/features/database.ts @@ -1,18 +1,15 @@ import { mkdir } from 'node:fs/promises' import { join } from 'pathe' -import { addServerImportsDir, addServerScanDir, addTemplate, addTypeTemplate, logger } from '@nuxt/kit' +import { addServerImportsDir, addServerScanDir, addTemplate, addTypeTemplate } from '@nuxt/kit' import { provider } from 'std-env' import { copyDatabaseMigrationsToHubDir, copyDatabaseQueriesToHubDir } from '../runtime/database/server/utils/migrations/helpers' import { logWhenReady } from '../features' import { resolve } from '../module' import type { Nuxt } from '@nuxt/schema' -import type { Nitro } from 'nitropack' import type { HubConfig, ResolvedDatabaseConfig } from '../features' import type { ModuleOptions, DatabaseConfig } from '../types/module' -const log = logger.withTag('nuxt:hub') - /** * Resolve database configuration from string or object format */ @@ -28,15 +25,14 @@ export async function resolveDatabaseConfig(nuxt: Nuxt, hub: HubConfig, hosting: // Auto-detect connection based on environment variables if (dialect === 'sqlite') { - // Tursor Cloud if (process.env.TURSO_DATABASE_URL && process.env.TURSO_AUTH_TOKEN) { + // Tursor Cloud connection = { url: process.env.TURSO_DATABASE_URL, authToken: process.env.TURSO_AUTH_TOKEN } - } - // Cloudflare D1 - else if (hosting.includes('cloudflare')) { + } else if (hosting.includes('cloudflare')) { + // Cloudflare D1 driver = 'd1' nuxt.options.nitro.cloudflare ||= {} nuxt.options.nitro.cloudflare.deployConfig = true @@ -51,26 +47,22 @@ export async function resolveDatabaseConfig(nuxt: Nuxt, hub: HubConfig, hosting: dbBinding.migrations_table ||= '_hub_migrations' dbBinding.migrations_dir ||= 'migrations' - } - // Local SQLite - else { + } else { + // Local SQLite connection = { url: `file:${join(hub.dir!, 'database/sqlite.db')}` } await mkdir(join(hub.dir!, 'database/sqlite'), { recursive: true }) } - } - else if (dialect === 'postgresql') { + } else if (dialect === 'postgresql') { const url = process.env.DATABASE_URL || process.env.POSTGRES_URL || process.env.POSTGRESQL_URL driver = 'node-postgres' if (url) { connection = { connectionString: url } - } - else { + } else { driver = 'pglite' connection = { dataDir: join(hub.dir!, 'database/pglite') } await mkdir(join(hub.dir!, 'database/pglite'), { recursive: true }) } - } - else if (dialect === 'mysql') { + } else if (dialect === 'mysql') { connection = { url: process.env.DATABASE_URL || process.env.MYSQL_URL } if (!connection.url) { throw new Error('MySQL requires DATABASE_URL or MYSQL_URL environment variable') diff --git a/src/module.ts b/src/module.ts index f458ce05..67fd06ce 100644 --- a/src/module.ts +++ b/src/module.ts @@ -5,8 +5,8 @@ import { defu } from 'defu' import { findWorkspaceDir, readPackageJSON } from 'pkg-types' import type { Nuxt } from '@nuxt/schema' import { version } from '../package.json' -import { setupAI, setupCache, setupOpenAPI, setupDatabase, setupKV, setupBase, setupBlob, resolveDatabaseConfig, type HubConfig } from './features' -import type { ModuleOptions, DatabaseConfig } from './types/module' +import { setupAI, setupCache, setupOpenAPI, setupDatabase, setupKV, setupBase, setupBlob, type HubConfig } from './features' +import type { ModuleOptions } from './types/module' import { addBuildHooks } from './utils/build' export * from './types' @@ -70,7 +70,6 @@ export default defineNuxtModule({ runtimeConfig.hub = hub as HubConfig runtimeConfig.public.hub ||= {} - // nuxt prepare, stop here if (nuxt.options._prepare) { return From b0e80445514a2d18010f54dcb4a2f046eea06e33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Chopin?= Date: Tue, 21 Oct 2025 17:09:14 +0200 Subject: [PATCH 06/22] up --- src/features.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/features.ts b/src/features.ts index 9b758495..6ee6e93c 100644 --- a/src/features.ts +++ b/src/features.ts @@ -17,6 +17,8 @@ export function logWhenReady(nuxt: Nuxt, message: string, type: 'info' | 'warn' nuxt.hooks.hookOnce('modules:done', () => { log[type](message) }) + } else { + log[type](message) } } From 862957d0dad8d58bdb0d9cd5d30c53943ad8a830 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Chopin?= Date: Tue, 21 Oct 2025 23:18:19 +0200 Subject: [PATCH 07/22] force: sqlite anyway --- playground/nuxt.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/playground/nuxt.config.ts b/playground/nuxt.config.ts index 0516f35a..ec72cf07 100644 --- a/playground/nuxt.config.ts +++ b/playground/nuxt.config.ts @@ -32,7 +32,7 @@ export default defineNuxtConfig({ hub: { ai: 'cloudflare', - database: process.env.TEST || process.env.NITRO_PRESET?.includes('cloudflare') ? 'sqlite' : 'postgresql', + database: 'sqlite', blob: true, kv: true, cache: true From 8df16171ef30291b59a2d64b72407b60a17655aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Chopin?= Date: Tue, 21 Oct 2025 23:34:29 +0200 Subject: [PATCH 08/22] disable d1 migrations during the build phase --- src/features/database.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/features/database.ts b/src/features/database.ts index 88cb7e27..710ca9c9 100644 --- a/src/features/database.ts +++ b/src/features/database.ts @@ -34,6 +34,7 @@ export async function resolveDatabaseConfig(nuxt: Nuxt, hub: HubConfig, hosting: } else if (hosting.includes('cloudflare')) { // Cloudflare D1 driver = 'd1' + hub.applyDatabaseMigrationsDuringBuild = false nuxt.options.nitro.cloudflare ||= {} nuxt.options.nitro.cloudflare.deployConfig = true nuxt.options.nitro.cloudflare.wrangler ||= {} From 58f3ce20d29f4ed2428a2aeda7007093d5096b3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Chopin?= Date: Tue, 21 Oct 2025 23:38:02 +0200 Subject: [PATCH 09/22] chore: remove extra code for d1 --- src/features/database.ts | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/features/database.ts b/src/features/database.ts index 710ca9c9..612d6ada 100644 --- a/src/features/database.ts +++ b/src/features/database.ts @@ -35,19 +35,6 @@ export async function resolveDatabaseConfig(nuxt: Nuxt, hub: HubConfig, hosting: // Cloudflare D1 driver = 'd1' hub.applyDatabaseMigrationsDuringBuild = false - nuxt.options.nitro.cloudflare ||= {} - nuxt.options.nitro.cloudflare.deployConfig = true - nuxt.options.nitro.cloudflare.wrangler ||= {} - nuxt.options.nitro.cloudflare.wrangler.d1_databases ||= [] - - let dbBinding = nuxt.options.nitro.cloudflare.wrangler.d1_databases!.find(db => db?.binding === 'DB') - if (!dbBinding) { - dbBinding = { binding: 'DB' } - nuxt.options.nitro.cloudflare.wrangler.d1_databases.push(dbBinding as any) - } - - dbBinding.migrations_table ||= '_hub_migrations' - dbBinding.migrations_dir ||= 'migrations' } else { // Local SQLite connection = { url: `file:${join(hub.dir!, 'database/sqlite.db')}` } From 34d0e25583420714946272bc7afff2278a420897 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Chopin?= Date: Wed, 22 Oct 2025 00:03:28 +0200 Subject: [PATCH 10/22] add missing deps --- playground/package.json | 2 + pnpm-lock.yaml | 96 ++++++++++++++++++++++------------------- 2 files changed, 53 insertions(+), 45 deletions(-) diff --git a/playground/package.json b/playground/package.json index f1f7668e..bc454785 100644 --- a/playground/package.json +++ b/playground/package.json @@ -17,10 +17,12 @@ "@nuxt/ui": "^4.0.1", "@nuxthub/core": "workspace:*", "@nuxtjs/mdc": "^0.18.0", + "@vercel/blob": "^2.0.0", "@vueuse/core": "^13.9.0", "@vueuse/nuxt": "^13.9.0", "ai": "^5.0.76", "drizzle-orm": "^0.44.6", + "ioredis": "^5.8.2", "nuxt": "^4.1.3", "nuxt-auth-utils": "^0.5.25", "pg": "^8.16.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f1a08a9c..206efad0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -82,7 +82,7 @@ importers: version: 0.1.3 unstorage: specifier: ^1.17.1 - version: 1.17.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1) + version: 1.17.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.2) zod: specifier: ^4.1.12 version: 4.1.12 @@ -122,7 +122,7 @@ importers: version: 9.37.0(jiti@2.6.1) nuxt: specifier: ^4.1.3 - version: 4.1.3(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@parcel/watcher@2.5.1)(@types/node@24.7.2)(@vercel/blob@2.0.0)(@vue/compiler-sfc@3.5.22)(aws4fetch@1.0.20)(better-sqlite3@12.4.1)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3))(eslint@9.37.0(jiti@2.6.1))(ioredis@5.8.1)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rolldown@1.0.0-beta.9)(rollup@4.50.0)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.1(typescript@5.9.3))(yaml@2.8.1) + version: 4.1.3(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@parcel/watcher@2.5.1)(@types/node@24.7.2)(@vercel/blob@2.0.0)(@vue/compiler-sfc@3.5.22)(aws4fetch@1.0.20)(better-sqlite3@12.4.1)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3))(eslint@9.37.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rolldown@1.0.0-beta.9)(rollup@4.50.0)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.1(typescript@5.9.3))(yaml@2.8.1) typescript: specifier: ~5.9.3 version: 5.9.3 @@ -161,13 +161,13 @@ importers: version: 3.7.1(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3))(magicast@0.3.5)(valibot@1.1.0(typescript@5.9.3)) '@nuxt/image': specifier: ^1.10.0 - version: 1.11.0(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1)(magicast@0.3.5) + version: 1.11.0(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.2)(magicast@0.3.5) '@nuxt/scripts': specifier: ^0.12.1 - version: 0.12.1(@googlemaps/markerclusterer@2.6.2)(@unhead/vue@2.0.19(vue@3.5.22(typescript@5.9.3)))(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1)(magicast@0.3.5)(typescript@5.9.3)(vue@3.5.22(typescript@5.9.3)) + version: 0.12.1(@googlemaps/markerclusterer@2.6.2)(@unhead/vue@2.0.19(vue@3.5.22(typescript@5.9.3)))(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.2)(magicast@0.3.5)(typescript@5.9.3)(vue@3.5.22(typescript@5.9.3)) '@nuxt/ui': specifier: ^4.0.1 - version: 4.0.1(@babel/parser@7.28.4)(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(change-case@5.4.4)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(embla-carousel@8.6.0)(ioredis@5.8.1)(magicast@0.3.5)(react@19.1.1)(typescript@5.9.3)(valibot@1.1.0(typescript@5.9.3))(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-router@4.5.1(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3))(zod@3.25.76) + version: 4.0.1(@babel/parser@7.28.4)(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(change-case@5.4.4)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(embla-carousel@8.6.0)(ioredis@5.8.2)(magicast@0.3.5)(react@19.1.1)(typescript@5.9.3)(valibot@1.1.0(typescript@5.9.3))(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-router@4.5.1(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3))(zod@3.25.76) '@rollup/plugin-yaml': specifier: ^4.1.2 version: 4.1.2(rollup@4.52.4) @@ -182,19 +182,19 @@ importers: version: 13.9.0(vue@3.5.22(typescript@5.9.3)) '@vueuse/nuxt': specifier: ^13.1.0 - version: 13.9.0(magicast@0.3.5)(nuxt@4.1.3(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@parcel/watcher@2.5.1)(@types/node@24.7.2)(@vercel/blob@2.0.0)(@vue/compiler-sfc@3.5.22)(aws4fetch@1.0.20)(better-sqlite3@12.4.1)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3))(eslint@9.37.0(jiti@2.6.1))(ioredis@5.8.1)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rolldown@1.0.0-beta.9)(rollup@4.52.4)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.1(typescript@5.9.3))(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)) + version: 13.9.0(magicast@0.3.5)(nuxt@4.1.3(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@parcel/watcher@2.5.1)(@types/node@24.7.2)(@vercel/blob@2.0.0)(@vue/compiler-sfc@3.5.22)(aws4fetch@1.0.20)(better-sqlite3@12.4.1)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3))(eslint@9.37.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rolldown@1.0.0-beta.9)(rollup@4.52.4)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.1(typescript@5.9.3))(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)) feed: specifier: ^5.1.0 version: 5.1.0 nuxt: specifier: ^4.1.3 - version: 4.1.3(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@parcel/watcher@2.5.1)(@types/node@24.7.2)(@vercel/blob@2.0.0)(@vue/compiler-sfc@3.5.22)(aws4fetch@1.0.20)(better-sqlite3@12.4.1)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3))(eslint@9.37.0(jiti@2.6.1))(ioredis@5.8.1)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rolldown@1.0.0-beta.9)(rollup@4.52.4)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.1(typescript@5.9.3))(yaml@2.8.1) + version: 4.1.3(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@parcel/watcher@2.5.1)(@types/node@24.7.2)(@vercel/blob@2.0.0)(@vue/compiler-sfc@3.5.22)(aws4fetch@1.0.20)(better-sqlite3@12.4.1)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3))(eslint@9.37.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rolldown@1.0.0-beta.9)(rollup@4.52.4)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.1(typescript@5.9.3))(yaml@2.8.1) nuxt-llms: specifier: ^0.1.2 version: 0.1.3(magicast@0.3.5) nuxt-og-image: specifier: ^5.1.11 - version: 5.1.11(@unhead/vue@2.0.19(vue@3.5.22(typescript@5.9.3)))(h3@1.15.4)(magicast@0.3.5)(unstorage@1.17.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1))(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)) + version: 5.1.11(@unhead/vue@2.0.19(vue@3.5.22(typescript@5.9.3)))(h3@1.15.4)(magicast@0.3.5)(unstorage@1.17.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.2))(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)) playground: dependencies: @@ -215,28 +215,34 @@ importers: version: 0.15.15 '@nuxt/ui': specifier: ^4.0.1 - version: 4.0.1(@babel/parser@7.28.4)(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(change-case@5.4.4)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(embla-carousel@8.6.0)(ioredis@5.8.1)(magicast@0.3.5)(react@19.1.1)(typescript@5.9.3)(valibot@1.1.0(typescript@5.9.3))(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-router@4.5.1(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3))(zod@4.1.12) + version: 4.0.1(@babel/parser@7.28.4)(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(change-case@5.4.4)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(embla-carousel@8.6.0)(ioredis@5.8.2)(magicast@0.3.5)(react@19.1.1)(typescript@5.9.3)(valibot@1.1.0(typescript@5.9.3))(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-router@4.5.1(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3))(zod@4.1.12) '@nuxthub/core': specifier: workspace:* version: link:.. '@nuxtjs/mdc': specifier: ^0.18.0 version: 0.18.0(magicast@0.3.5) + '@vercel/blob': + specifier: ^2.0.0 + version: 2.0.0 '@vueuse/core': specifier: ^13.9.0 version: 13.9.0(vue@3.5.22(typescript@5.9.3)) '@vueuse/nuxt': specifier: ^13.9.0 - version: 13.9.0(magicast@0.3.5)(nuxt@4.1.3(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@parcel/watcher@2.5.1)(@types/node@24.7.2)(@vercel/blob@2.0.0)(@vue/compiler-sfc@3.5.22)(aws4fetch@1.0.20)(better-sqlite3@12.4.1)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3))(eslint@9.37.0(jiti@2.6.1))(ioredis@5.8.1)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rolldown@1.0.0-beta.9)(rollup@4.52.4)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.1(typescript@5.9.3))(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)) + version: 13.9.0(magicast@0.3.5)(nuxt@4.1.3(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@parcel/watcher@2.5.1)(@types/node@24.7.2)(@vercel/blob@2.0.0)(@vue/compiler-sfc@3.5.22)(aws4fetch@1.0.20)(better-sqlite3@12.4.1)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3))(eslint@9.37.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rolldown@1.0.0-beta.9)(rollup@4.52.4)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.1(typescript@5.9.3))(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)) ai: specifier: ^5.0.76 version: 5.0.76(zod@4.1.12) drizzle-orm: specifier: ^0.44.6 version: 0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3) + ioredis: + specifier: ^5.8.2 + version: 5.8.2 nuxt: specifier: ^4.1.3 - version: 4.1.3(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@parcel/watcher@2.5.1)(@types/node@24.7.2)(@vercel/blob@2.0.0)(@vue/compiler-sfc@3.5.22)(aws4fetch@1.0.20)(better-sqlite3@12.4.1)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3))(eslint@9.37.0(jiti@2.6.1))(ioredis@5.8.1)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rolldown@1.0.0-beta.9)(rollup@4.52.4)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.1(typescript@5.9.3))(yaml@2.8.1) + version: 4.1.3(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@parcel/watcher@2.5.1)(@types/node@24.7.2)(@vercel/blob@2.0.0)(@vue/compiler-sfc@3.5.22)(aws4fetch@1.0.20)(better-sqlite3@12.4.1)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3))(eslint@9.37.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rolldown@1.0.0-beta.9)(rollup@4.52.4)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.1(typescript@5.9.3))(yaml@2.8.1) nuxt-auth-utils: specifier: ^0.5.25 version: 0.5.25(magicast@0.3.5) @@ -4527,8 +4533,8 @@ packages: resolution: {integrity: sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - ioredis@5.8.1: - resolution: {integrity: sha512-Qho8TgIamqEPdgiMadJwzRMW3TudIg6vpg4YONokGDudy4eqRIJtDbVX72pfLBcWxvbn3qm/40TyGUObdW4tLQ==} + ioredis@5.8.2: + resolution: {integrity: sha512-C6uC+kleiIMmjViJINWk80sOQw5lEzse1ZmvD+S/s8p8CWapftSaC+kocGTx6xrbrJ4WmYQGC08ffHLr6ToR6Q==} engines: {node: '>=12.22.0'} ipx@2.1.1: @@ -8116,7 +8122,7 @@ snapshots: - supports-color - typescript - '@nuxt/fonts@0.11.4(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1)(magicast@0.3.5)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))': + '@nuxt/fonts@0.11.4(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.2)(magicast@0.3.5)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))': dependencies: '@nuxt/devtools-kit': 2.6.5(magicast@0.3.5)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1)) '@nuxt/kit': 3.19.3(magicast@0.3.5) @@ -8137,7 +8143,7 @@ snapshots: ufo: 1.6.1 unifont: 0.4.1 unplugin: 2.3.10 - unstorage: 1.17.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1) + unstorage: 1.17.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.2) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -8184,7 +8190,7 @@ snapshots: - vite - vue - '@nuxt/image@1.11.0(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1)(magicast@0.3.5)': + '@nuxt/image@1.11.0(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.2)(magicast@0.3.5)': dependencies: '@nuxt/kit': 3.19.3(magicast@0.3.5) consola: 3.4.2 @@ -8197,7 +8203,7 @@ snapshots: std-env: 3.9.0 ufo: 1.6.1 optionalDependencies: - ipx: 2.1.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1) + ipx: 2.1.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.2) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -8311,7 +8317,7 @@ snapshots: std-env: 3.9.0 ufo: 1.6.1 - '@nuxt/scripts@0.12.1(@googlemaps/markerclusterer@2.6.2)(@unhead/vue@2.0.19(vue@3.5.22(typescript@5.9.3)))(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1)(magicast@0.3.5)(typescript@5.9.3)(vue@3.5.22(typescript@5.9.3))': + '@nuxt/scripts@0.12.1(@googlemaps/markerclusterer@2.6.2)(@unhead/vue@2.0.19(vue@3.5.22(typescript@5.9.3)))(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.2)(magicast@0.3.5)(typescript@5.9.3)(vue@3.5.22(typescript@5.9.3))': dependencies: '@googlemaps/markerclusterer': 2.6.2 '@nuxt/kit': 4.1.3(magicast@0.3.5) @@ -8329,7 +8335,7 @@ snapshots: std-env: 3.9.0 ufo: 1.6.1 unplugin: 2.3.10 - unstorage: 1.17.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1) + unstorage: 1.17.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.2) valibot: 1.1.0(typescript@5.9.3) transitivePeerDependencies: - '@azure/app-configuration' @@ -8405,13 +8411,13 @@ snapshots: - magicast - typescript - '@nuxt/ui@4.0.1(@babel/parser@7.28.4)(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(change-case@5.4.4)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(embla-carousel@8.6.0)(ioredis@5.8.1)(magicast@0.3.5)(react@19.1.1)(typescript@5.9.3)(valibot@1.1.0(typescript@5.9.3))(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-router@4.5.1(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3))(zod@3.25.76)': + '@nuxt/ui@4.0.1(@babel/parser@7.28.4)(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(change-case@5.4.4)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(embla-carousel@8.6.0)(ioredis@5.8.2)(magicast@0.3.5)(react@19.1.1)(typescript@5.9.3)(valibot@1.1.0(typescript@5.9.3))(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-router@4.5.1(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3))(zod@3.25.76)': dependencies: '@ai-sdk/vue': 2.0.76(vue@3.5.22(typescript@5.9.3))(zod@3.25.76) '@iconify/vue': 5.0.0(vue@3.5.22(typescript@5.9.3)) '@internationalized/date': 3.10.0 '@internationalized/number': 3.6.5 - '@nuxt/fonts': 0.11.4(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1)(magicast@0.3.5)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1)) + '@nuxt/fonts': 0.11.4(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.2)(magicast@0.3.5)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1)) '@nuxt/icon': 2.0.0(magicast@0.3.5)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)) '@nuxt/kit': 4.1.3(magicast@0.3.5) '@nuxt/schema': 4.1.3 @@ -8499,13 +8505,13 @@ snapshots: - vite - vue - '@nuxt/ui@4.0.1(@babel/parser@7.28.4)(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(change-case@5.4.4)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(embla-carousel@8.6.0)(ioredis@5.8.1)(magicast@0.3.5)(react@19.1.1)(typescript@5.9.3)(valibot@1.1.0(typescript@5.9.3))(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-router@4.5.1(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3))(zod@4.1.12)': + '@nuxt/ui@4.0.1(@babel/parser@7.28.4)(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(change-case@5.4.4)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(embla-carousel@8.6.0)(ioredis@5.8.2)(magicast@0.3.5)(react@19.1.1)(typescript@5.9.3)(valibot@1.1.0(typescript@5.9.3))(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-router@4.5.1(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3))(zod@4.1.12)': dependencies: '@ai-sdk/vue': 2.0.76(vue@3.5.22(typescript@5.9.3))(zod@4.1.12) '@iconify/vue': 5.0.0(vue@3.5.22(typescript@5.9.3)) '@internationalized/date': 3.10.0 '@internationalized/number': 3.6.5 - '@nuxt/fonts': 0.11.4(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1)(magicast@0.3.5)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1)) + '@nuxt/fonts': 0.11.4(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.2)(magicast@0.3.5)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1)) '@nuxt/icon': 2.0.0(magicast@0.3.5)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)) '@nuxt/kit': 4.1.3(magicast@0.3.5) '@nuxt/schema': 4.1.3 @@ -9985,7 +9991,7 @@ snapshots: '@typescript-eslint/types': 8.42.0 '@typescript-eslint/typescript-estree': 8.42.0(typescript@5.9.3) '@typescript-eslint/visitor-keys': 8.42.0 - debug: 4.4.1 + debug: 4.4.3 eslint: 9.37.0(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: @@ -9995,7 +10001,7 @@ snapshots: dependencies: '@typescript-eslint/tsconfig-utils': 8.42.0(typescript@5.9.3) '@typescript-eslint/types': 8.42.0 - debug: 4.4.1 + debug: 4.4.3 typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -10029,7 +10035,7 @@ snapshots: '@typescript-eslint/tsconfig-utils': 8.42.0(typescript@5.9.3) '@typescript-eslint/types': 8.42.0 '@typescript-eslint/visitor-keys': 8.42.0 - debug: 4.4.1 + debug: 4.4.3 fast-glob: 3.3.3 is-glob: 4.0.3 minimatch: 9.0.5 @@ -10478,13 +10484,13 @@ snapshots: '@vueuse/metadata@13.9.0': {} - '@vueuse/nuxt@13.9.0(magicast@0.3.5)(nuxt@4.1.3(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@parcel/watcher@2.5.1)(@types/node@24.7.2)(@vercel/blob@2.0.0)(@vue/compiler-sfc@3.5.22)(aws4fetch@1.0.20)(better-sqlite3@12.4.1)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3))(eslint@9.37.0(jiti@2.6.1))(ioredis@5.8.1)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rolldown@1.0.0-beta.9)(rollup@4.52.4)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.1(typescript@5.9.3))(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3))': + '@vueuse/nuxt@13.9.0(magicast@0.3.5)(nuxt@4.1.3(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@parcel/watcher@2.5.1)(@types/node@24.7.2)(@vercel/blob@2.0.0)(@vue/compiler-sfc@3.5.22)(aws4fetch@1.0.20)(better-sqlite3@12.4.1)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3))(eslint@9.37.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rolldown@1.0.0-beta.9)(rollup@4.52.4)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.1(typescript@5.9.3))(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3))': dependencies: '@nuxt/kit': 3.19.3(magicast@0.3.5) '@vueuse/core': 13.9.0(vue@3.5.22(typescript@5.9.3)) '@vueuse/metadata': 13.9.0 local-pkg: 1.1.2 - nuxt: 4.1.3(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@parcel/watcher@2.5.1)(@types/node@24.7.2)(@vercel/blob@2.0.0)(@vue/compiler-sfc@3.5.22)(aws4fetch@1.0.20)(better-sqlite3@12.4.1)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3))(eslint@9.37.0(jiti@2.6.1))(ioredis@5.8.1)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rolldown@1.0.0-beta.9)(rollup@4.52.4)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.1(typescript@5.9.3))(yaml@2.8.1) + nuxt: 4.1.3(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@parcel/watcher@2.5.1)(@types/node@24.7.2)(@vercel/blob@2.0.0)(@vue/compiler-sfc@3.5.22)(aws4fetch@1.0.20)(better-sqlite3@12.4.1)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3))(eslint@9.37.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rolldown@1.0.0-beta.9)(rollup@4.52.4)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.1(typescript@5.9.3))(yaml@2.8.1) vue: 3.5.22(typescript@5.9.3) transitivePeerDependencies: - magicast @@ -11389,7 +11395,7 @@ snapshots: dependencies: '@typescript-eslint/types': 8.42.0 comment-parser: 1.4.1 - debug: 4.4.1 + debug: 4.4.3 eslint: 9.37.0(jiti@2.6.1) eslint-import-context: 0.1.9(unrs-resolver@1.11.1) is-glob: 4.0.3 @@ -11407,7 +11413,7 @@ snapshots: '@es-joy/jsdoccomment': 0.53.0 are-docs-informative: 0.0.2 comment-parser: 1.4.1 - debug: 4.4.1 + debug: 4.4.3 escape-string-regexp: 4.0.0 eslint: 9.37.0(jiti@2.6.1) espree: 10.4.0 @@ -12040,7 +12046,7 @@ snapshots: ini@4.1.1: {} - ioredis@5.8.1: + ioredis@5.8.2: dependencies: '@ioredis/commands': 1.4.0 cluster-key-slot: 1.1.2 @@ -12054,7 +12060,7 @@ snapshots: transitivePeerDependencies: - supports-color - ipx@2.1.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1): + ipx@2.1.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.2): dependencies: '@fastify/accept-negotiator': 1.1.0 citty: 0.1.6 @@ -12070,7 +12076,7 @@ snapshots: sharp: 0.32.6 svgo: 3.3.2 ufo: 1.6.1 - unstorage: 1.17.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1) + unstorage: 1.17.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.2) xss: 1.0.15 transitivePeerDependencies: - '@azure/app-configuration' @@ -12919,7 +12925,7 @@ snapshots: h3: 1.15.4 hookable: 5.5.3 httpxy: 0.1.7 - ioredis: 5.8.1 + ioredis: 5.8.2 jiti: 2.6.1 klona: 2.0.6 knitwork: 1.2.0 @@ -12952,7 +12958,7 @@ snapshots: unenv: 2.0.0-rc.21 unimport: 5.4.1 unplugin-utils: 0.3.1 - unstorage: 1.17.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1) + unstorage: 1.17.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.2) untyped: 2.0.0 unwasm: 0.3.11 youch: 4.1.0-beta.11 @@ -13087,7 +13093,7 @@ snapshots: transitivePeerDependencies: - magicast - nuxt-og-image@5.1.11(@unhead/vue@2.0.19(vue@3.5.22(typescript@5.9.3)))(h3@1.15.4)(magicast@0.3.5)(unstorage@1.17.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1))(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)): + nuxt-og-image@5.1.11(@unhead/vue@2.0.19(vue@3.5.22(typescript@5.9.3)))(h3@1.15.4)(magicast@0.3.5)(unstorage@1.17.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.2))(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)): dependencies: '@nuxt/devtools-kit': 2.6.5(magicast@0.3.5)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1)) '@nuxt/kit': 4.1.3(magicast@0.3.5) @@ -13118,7 +13124,7 @@ snapshots: strip-literal: 3.1.0 ufo: 1.6.1 unplugin: 2.3.10 - unstorage: 1.17.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1) + unstorage: 1.17.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.2) unwasm: 0.3.11 yoga-wasm-web: 0.3.3 transitivePeerDependencies: @@ -13153,7 +13159,7 @@ snapshots: - magicast - vue - nuxt@4.1.3(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@parcel/watcher@2.5.1)(@types/node@24.7.2)(@vercel/blob@2.0.0)(@vue/compiler-sfc@3.5.22)(aws4fetch@1.0.20)(better-sqlite3@12.4.1)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3))(eslint@9.37.0(jiti@2.6.1))(ioredis@5.8.1)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rolldown@1.0.0-beta.9)(rollup@4.50.0)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.1(typescript@5.9.3))(yaml@2.8.1): + nuxt@4.1.3(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@parcel/watcher@2.5.1)(@types/node@24.7.2)(@vercel/blob@2.0.0)(@vue/compiler-sfc@3.5.22)(aws4fetch@1.0.20)(better-sqlite3@12.4.1)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3))(eslint@9.37.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rolldown@1.0.0-beta.9)(rollup@4.50.0)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.1(typescript@5.9.3))(yaml@2.8.1): dependencies: '@nuxt/cli': 3.29.3(magicast@0.3.5) '@nuxt/devalue': 2.0.2 @@ -13212,7 +13218,7 @@ snapshots: unimport: 5.4.1 unplugin: 2.3.10 unplugin-vue-router: 0.15.0(@vue/compiler-sfc@3.5.22)(typescript@5.9.3)(vue-router@4.5.1(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3)) - unstorage: 1.17.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1) + unstorage: 1.17.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.2) untyped: 2.0.0 vue: 3.5.22(typescript@5.9.3) vue-bundle-renderer: 2.2.0 @@ -13279,7 +13285,7 @@ snapshots: - xml2js - yaml - nuxt@4.1.3(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@parcel/watcher@2.5.1)(@types/node@24.7.2)(@vercel/blob@2.0.0)(@vue/compiler-sfc@3.5.22)(aws4fetch@1.0.20)(better-sqlite3@12.4.1)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3))(eslint@9.37.0(jiti@2.6.1))(ioredis@5.8.1)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rolldown@1.0.0-beta.9)(rollup@4.52.4)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.1(typescript@5.9.3))(yaml@2.8.1): + nuxt@4.1.3(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@parcel/watcher@2.5.1)(@types/node@24.7.2)(@vercel/blob@2.0.0)(@vue/compiler-sfc@3.5.22)(aws4fetch@1.0.20)(better-sqlite3@12.4.1)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3))(eslint@9.37.0(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.1)(magicast@0.3.5)(optionator@0.9.4)(rolldown@1.0.0-beta.9)(rollup@4.52.4)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.1(typescript@5.9.3))(yaml@2.8.1): dependencies: '@nuxt/cli': 3.29.3(magicast@0.3.5) '@nuxt/devalue': 2.0.2 @@ -13338,7 +13344,7 @@ snapshots: unimport: 5.4.1 unplugin: 2.3.10 unplugin-vue-router: 0.15.0(@vue/compiler-sfc@3.5.22)(typescript@5.9.3)(vue-router@4.5.1(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3)) - unstorage: 1.17.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1) + unstorage: 1.17.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.2) untyped: 2.0.0 vue: 3.5.22(typescript@5.9.3) vue-bundle-renderer: 2.2.0 @@ -15140,7 +15146,7 @@ snapshots: '@unrs/resolver-binding-win32-ia32-msvc': 1.11.1 '@unrs/resolver-binding-win32-x64-msvc': 1.11.1 - unstorage@1.17.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.1): + unstorage@1.17.1(@vercel/blob@2.0.0)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)))(ioredis@5.8.2): dependencies: anymatch: 3.1.3 chokidar: 4.0.3 @@ -15154,7 +15160,7 @@ snapshots: '@vercel/blob': 2.0.0 aws4fetch: 1.0.20 db0: 0.3.4(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251011.0)(@electric-sql/pglite@0.3.11)(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(better-sqlite3@12.4.1)(pg@8.16.3)) - ioredis: 5.8.1 + ioredis: 5.8.2 untun@0.1.3: dependencies: @@ -15239,7 +15245,7 @@ snapshots: vite-node@3.2.4(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1): dependencies: cac: 6.7.14 - debug: 4.4.1 + debug: 4.4.3 es-module-lexer: 1.7.0 pathe: 2.0.3 vite: 7.1.4(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.44.0)(yaml@2.8.1) @@ -15416,7 +15422,7 @@ snapshots: vue-eslint-parser@10.2.0(eslint@9.37.0(jiti@2.6.1)): dependencies: - debug: 4.4.1 + debug: 4.4.3 eslint: 9.37.0(jiti@2.6.1) eslint-scope: 8.4.0 eslint-visitor-keys: 4.2.1 From 56d9ca233ccd66a99da4022e1c02473ae838996e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Chopin?= Date: Wed, 22 Oct 2025 00:26:58 +0200 Subject: [PATCH 11/22] try to fix weird issue on Vercel --- playground/server/utils/drizzle.ts | 8 -------- 1 file changed, 8 deletions(-) diff --git a/playground/server/utils/drizzle.ts b/playground/server/utils/drizzle.ts index a9f1393d..d348736a 100644 --- a/playground/server/utils/drizzle.ts +++ b/playground/server/utils/drizzle.ts @@ -1,5 +1,4 @@ import { sqliteTable, text, integer } from 'drizzle-orm/sqlite-core' -// import { pgTable, text as pgText, boolean as pgBoolean, serial as pgSerial, timestamp as pgTimestamp } from 'drizzle-orm/pg-core' import { drizzle } from 'hub:database' export { sql } from 'drizzle-orm' @@ -11,13 +10,6 @@ const todos = sqliteTable('todos', { createdAt: integer('created_at', { mode: 'timestamp' }).notNull() }) -// const todos = pgTable('todos', { -// id: pgSerial('id').primaryKey(), -// title: pgText('title').notNull(), -// completed: pgBoolean('completed').notNull().default(false), -// createdAt: pgTimestamp('created_at').notNull() -// }) - export const tables = { todos } From 6a3f2d71af82c15609b94b17a9da6ff8f7c01ce2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Chopin?= Date: Wed, 22 Oct 2025 00:36:18 +0200 Subject: [PATCH 12/22] chore: debug --- src/features/kv.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/features/kv.ts b/src/features/kv.ts index 7f88a8bb..332048ae 100644 --- a/src/features/kv.ts +++ b/src/features/kv.ts @@ -28,6 +28,7 @@ export function setupKV(nuxt: Nuxt, hub: HubConfig, _deps: Record) { + console.log('setupProductionKV', nitro.options.preset) const preset = nitro.options.preset if (!preset) return From 10a486ff0e911d5ed41cd9dfeee3dc14d88fc90b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Chopin?= Date: Wed, 22 Oct 2025 00:38:04 +0200 Subject: [PATCH 13/22] chore: add support for Vercel Edge --- src/features/kv.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/features/kv.ts b/src/features/kv.ts index 332048ae..09fc59f5 100644 --- a/src/features/kv.ts +++ b/src/features/kv.ts @@ -43,6 +43,7 @@ export async function setupProductionKV(nitro: Nitro, _hub: HubConfig, deps: Rec switch (preset) { // Does your favourite cloud provider require special configuration? Feel free to open a PR to add zero-config support for other presets + case 'vercel-edge': case 'vercel': { kvConfig = { driver: 'redis', From 82e3e84c6c14009646b4e183be9a7ef3c30b92cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Chopin?= Date: Wed, 22 Oct 2025 00:43:41 +0200 Subject: [PATCH 14/22] chore: dynamic switch between CF or Vercel --- playground/nuxt.config.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/playground/nuxt.config.ts b/playground/nuxt.config.ts index ec72cf07..5935177b 100644 --- a/playground/nuxt.config.ts +++ b/playground/nuxt.config.ts @@ -1,5 +1,6 @@ import { createResolver } from 'nuxt/kit' import module from '../src/module' +import { provider } from 'std-env' const resolver = createResolver(import.meta.url) @@ -31,7 +32,7 @@ export default defineNuxtConfig({ }, hub: { - ai: 'cloudflare', + ai: provider.includes('cloudflare') ? 'cloudflare' : 'vercel', database: 'sqlite', blob: true, kv: true, From 811d3f2f1337cbb3e5293a8ed568fdbfcb94dbb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Chopin?= Date: Wed, 22 Oct 2025 01:14:50 +0200 Subject: [PATCH 15/22] add missing package --- playground/.gitignore | 3 ++- playground/package.json | 1 + pnpm-lock.yaml | 3 +++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/playground/.gitignore b/playground/.gitignore index 97c6a141..2a5eb3e6 100644 --- a/playground/.gitignore +++ b/playground/.gitignore @@ -1,3 +1,4 @@ .vercel -.wrangler \ No newline at end of file +.wrangler +.env*.local diff --git a/playground/package.json b/playground/package.json index bc454785..45a21281 100644 --- a/playground/package.json +++ b/playground/package.json @@ -9,6 +9,7 @@ "preview": "nuxi preview" }, "dependencies": { + "@ai-sdk/gateway": "^1.0.39", "@ai-sdk/vue": "^2.0.76", "@electric-sql/pglite": "^0.3.11", "@iconify-json/simple-icons": "^1.2.55", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 206efad0..3b25fe3f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -198,6 +198,9 @@ importers: playground: dependencies: + '@ai-sdk/gateway': + specifier: ^1.0.39 + version: 1.0.39(zod@4.1.12) '@ai-sdk/vue': specifier: ^2.0.76 version: 2.0.76(vue@3.5.22(typescript@5.9.3))(zod@4.1.12) From 5038f66da843a97a4954cfc90b7918a3295a8189 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Chopin?= Date: Wed, 22 Oct 2025 01:20:33 +0200 Subject: [PATCH 16/22] chore: handle both providers --- playground/server/api/chat.post.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/playground/server/api/chat.post.ts b/playground/server/api/chat.post.ts index 6809b452..66dca330 100644 --- a/playground/server/api/chat.post.ts +++ b/playground/server/api/chat.post.ts @@ -9,9 +9,10 @@ defineRouteMeta({ export default defineEventHandler(async (event) => { const { messages } = await readBody(event) + const aiProvider = useRuntimeConfig().hub.ai return streamText({ - model: hubAI('@cf/meta/llama-3.1-8b-instruct'), + model: hubAI(aiProvider === 'cloudflare' ? '@cf/meta/llama-3.1-8b-instruct' : 'openai/gpt-5-nano'), messages: convertToModelMessages(messages), onError(res) { console.error(res.error) From d1cefa12ea5734be89173eabe8371fb551788f61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Chopin?= Date: Wed, 22 Oct 2025 01:42:47 +0200 Subject: [PATCH 17/22] fix: use binding and not bindingName --- src/features/blob.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/features/blob.ts b/src/features/blob.ts index 45b88d3e..e7eab310 100644 --- a/src/features/blob.ts +++ b/src/features/blob.ts @@ -63,7 +63,7 @@ export async function setupProductionBlob(nitro: Nitro, _hub: HubConfig, deps: R case 'cloudflare-pages': { blobConfig = { driver: 'cloudflare-r2-binding', - bindingName: 'BLOB' + binding: 'BLOB' } log.info('Ensure a `BLOB` binding is set in your Cloudflare Workers configuration') break From eb20e533728a1c71a50d83562e056a726c2f935f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Chopin?= Date: Wed, 22 Oct 2025 01:43:44 +0200 Subject: [PATCH 18/22] fix: set proper KV binding name --- src/features/kv.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/features/kv.ts b/src/features/kv.ts index 09fc59f5..e8896ee3 100644 --- a/src/features/kv.ts +++ b/src/features/kv.ts @@ -60,7 +60,7 @@ export async function setupProductionKV(nitro: Nitro, _hub: HubConfig, deps: Rec case 'cloudflare-pages': { kvConfig = { driver: 'cloudflare-kv-binding', - bindingName: 'KV' + binding: 'KV' } log.info('Ensure a `KV` binding is set in your Cloudflare Workers configuration') break From 80a6b2c4cf9fd6b2fa13383f6d07d4e92af26acd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Chopin?= Date: Wed, 22 Oct 2025 01:51:07 +0200 Subject: [PATCH 19/22] hot fix --- src/features/ai.ts | 8 ++++---- src/features/kv.ts | 1 - 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/features/ai.ts b/src/features/ai.ts index 5d52bf86..85fe48d3 100644 --- a/src/features/ai.ts +++ b/src/features/ai.ts @@ -31,18 +31,18 @@ export async function setupAI(nuxt: Nuxt, hub: HubConfig, deps: Record) { - console.log('setupProductionKV', nitro.options.preset) const preset = nitro.options.preset if (!preset) return From 1de3f5152e65efb02b31d9003a6f88f78d92e428 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Chopin?= Date: Wed, 22 Oct 2025 19:06:15 +0200 Subject: [PATCH 20/22] fix: set dynamic import + fix build --- src/utils/database.ts | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/src/utils/database.ts b/src/utils/database.ts index 3041d2f9..99a4abf8 100644 --- a/src/utils/database.ts +++ b/src/utils/database.ts @@ -15,27 +15,21 @@ async function createDrizzleClient(config: any) { const { driver, connection } = config if (driver === 'libsql') { - const { drizzle } = await import('drizzle-orm/libsql') - const { createClient } = await import('@libsql/client') - const client = createClient(connection) - return drizzle(client) + const pkg = 'drizzle-orm/libsql' + const { drizzle } = await import(pkg) + return drizzle({ connection }) } else if (driver === 'node-postgres') { - const { drizzle } = await import('drizzle-orm/node-postgres') - // @ts-expect-error - pg is an optional dependency - const pg = await import('pg') - const pool = new pg.Pool(connection) - return drizzle(pool) + const pkg = 'drizzle-orm/node-postgres' + const { drizzle } = await import(pkg) + return drizzle({ connection }) } else if (driver === 'mysql2') { - const { drizzle } = await import('drizzle-orm/mysql2') - // @ts-expect-error - mysql2 is an optional dependency - const mysql = await import('mysql2/promise') - const pool = mysql.createPool(connection) - return drizzle(pool) + const pkg = 'drizzle-orm/mysql2' + const { drizzle } = await import(pkg) + return drizzle({ connection }) } else if (driver === 'pglite') { - const { drizzle } = await import('drizzle-orm/pglite') - const { PGlite } = await import('@electric-sql/pglite') - const client = new PGlite(connection.dataDir) - return drizzle(client) + const pkg = 'drizzle-orm/pglite' + const { drizzle } = await import(pkg) + return drizzle({ connection }) } throw new Error(`Unsupported driver: ${driver}`) From 8c798a344d525d840ae33fb6a34e91fa1706c5b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Chopin?= Date: Wed, 22 Oct 2025 19:26:51 +0200 Subject: [PATCH 21/22] chore: test CF debug --- playground/server/api/chat.post.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/playground/server/api/chat.post.ts b/playground/server/api/chat.post.ts index 66dca330..ea7464d3 100644 --- a/playground/server/api/chat.post.ts +++ b/playground/server/api/chat.post.ts @@ -17,5 +17,13 @@ export default defineEventHandler(async (event) => { onError(res) { console.error(res.error) } - }).toUIMessageStreamResponse() + }) + .toUIMessageStreamResponse({ + headers: { + 'Content-Type': 'text/x-unknown', + 'content-encoding': 'identity', + 'transfer-encoding': 'chunked', + }, + }) + }) From b1cfc245f2d46feaafd4dbe849c0dd4af51b62f7 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Wed, 22 Oct 2025 17:28:03 +0000 Subject: [PATCH 22/22] [autofix.ci] apply automated fixes --- playground/server/api/chat.post.ts | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/playground/server/api/chat.post.ts b/playground/server/api/chat.post.ts index ea7464d3..2e81a28b 100644 --- a/playground/server/api/chat.post.ts +++ b/playground/server/api/chat.post.ts @@ -18,12 +18,11 @@ export default defineEventHandler(async (event) => { console.error(res.error) } }) - .toUIMessageStreamResponse({ - headers: { - 'Content-Type': 'text/x-unknown', - 'content-encoding': 'identity', - 'transfer-encoding': 'chunked', - }, - }) - + .toUIMessageStreamResponse({ + headers: { + 'Content-Type': 'text/x-unknown', + 'content-encoding': 'identity', + 'transfer-encoding': 'chunked' + } + }) })