diff --git a/changelogs/drizzle-orm/0.35.2.md b/changelogs/drizzle-orm/0.35.2.md new file mode 100644 index 000000000..1df586618 --- /dev/null +++ b/changelogs/drizzle-orm/0.35.2.md @@ -0,0 +1,6 @@ +- Fix issues with importing in several environments after updating the Drizzle driver implementation + +We've added approximately 240 tests to check the ESM and CJS builds for all the drivers we have. You can check them [here](https://github.com/drizzle-team/drizzle-orm/tree/main/integration-tests/js-tests/driver-init) + +- Fixed [[BUG]: Type Error in PgTransaction Missing $client Property After Upgrading to drizzle-orm@0.35.1](https://github.com/drizzle-team/drizzle-orm/issues/3140) +- Fixed [[BUG]: New critical Build error drizzle 0.35.0 deploying on Cloudflare ](https://github.com/drizzle-team/drizzle-orm/issues/3137) \ No newline at end of file diff --git a/drizzle-kit/package.json b/drizzle-kit/package.json index 5b9ac0934..7499a7ec1 100644 --- a/drizzle-kit/package.json +++ b/drizzle-kit/package.json @@ -51,7 +51,7 @@ "@arethetypeswrong/cli": "^0.15.3", "@aws-sdk/client-rds-data": "^3.556.0", "@cloudflare/workers-types": "^4.20230518.0", - "@electric-sql/pglite": "^0.1.5", + "@electric-sql/pglite": "^0.2.12", "@hono/node-server": "^1.9.0", "@hono/zod-validator": "^0.2.1", "@libsql/client": "^0.10.0", diff --git a/drizzle-orm/package.json b/drizzle-orm/package.json index 32af69b83..ceceab709 100644 --- a/drizzle-orm/package.json +++ b/drizzle-orm/package.json @@ -1,6 +1,6 @@ { "name": "drizzle-orm", - "version": "0.35.1", + "version": "0.35.2", "description": "Drizzle ORM package for SQL databases", "type": "module", "scripts": { @@ -160,7 +160,7 @@ "devDependencies": { "@aws-sdk/client-rds-data": "^3.549.0", "@cloudflare/workers-types": "^4.20230904.0", - "@electric-sql/pglite": "^0.1.1", + "@electric-sql/pglite": "^0.2.12", "@libsql/client": "^0.10.0", "@miniflare/d1": "^2.14.4", "@neondatabase/serverless": "^0.9.0", diff --git a/drizzle-orm/src/better-sqlite3/driver.ts b/drizzle-orm/src/better-sqlite3/driver.ts index 14e6644bc..0fe7364bd 100644 --- a/drizzle-orm/src/better-sqlite3/driver.ts +++ b/drizzle-orm/src/better-sqlite3/driver.ts @@ -9,7 +9,7 @@ import { } from '~/relations.ts'; import { BaseSQLiteDatabase } from '~/sqlite-core/db.ts'; import { SQLiteSyncDialect } from '~/sqlite-core/dialect.ts'; -import type { DrizzleConfig, IfNotImported, ImportTypeError } from '~/utils.ts'; +import { type DrizzleConfig, type IfNotImported, type ImportTypeError, isConfig } from '~/utils.ts'; import { BetterSQLiteSession } from './session.ts'; export type DrizzleBetterSQLite3DatabaseConfig = @@ -89,12 +89,13 @@ export function drizzle< ): BetterSQLite3Database & { $client: Database; } { - // eslint-disable-next-line no-instanceof/no-instanceof - if (params[0] instanceof Client) { - return construct(params[0] as Database, params[1] as DrizzleConfig | undefined) as any; + if (params[0] === undefined || typeof params[0] === 'string') { + const instance = params[0] === undefined ? new Client() : new Client(params[0]); + + return construct(instance, params[1]) as any; } - if (typeof params[0] === 'object') { + if (isConfig(params[0])) { const { connection, client, ...drizzleConfig } = params[0] as & { connection?: DrizzleBetterSQLite3DatabaseConfig; @@ -117,9 +118,7 @@ export function drizzle< return construct(instance, drizzleConfig) as any; } - const instance = new Client(params[0]); - - return construct(instance, params[1]) as any; + return construct(params[0] as Database, params[1] as DrizzleConfig | undefined) as any; } export namespace drizzle { diff --git a/drizzle-orm/src/bun-sqlite/driver.ts b/drizzle-orm/src/bun-sqlite/driver.ts index 91a2e370b..7510fe58e 100644 --- a/drizzle-orm/src/bun-sqlite/driver.ts +++ b/drizzle-orm/src/bun-sqlite/driver.ts @@ -11,7 +11,7 @@ import { } from '~/relations.ts'; import { BaseSQLiteDatabase } from '~/sqlite-core/db.ts'; import { SQLiteSyncDialect } from '~/sqlite-core/dialect.ts'; -import type { DrizzleConfig, IfNotImported, ImportTypeError } from '~/utils.ts'; +import { type DrizzleConfig, type IfNotImported, type ImportTypeError, isConfig } from '~/utils.ts'; import { SQLiteBunSession } from './session.ts'; export class BunSQLiteDatabase< @@ -111,12 +111,13 @@ export function drizzle< ): BunSQLiteDatabase & { $client: TClient; } { - // eslint-disable-next-line no-instanceof/no-instanceof - if (params[0] instanceof Database) { - return construct(params[0] as TClient, params[1] as DrizzleConfig | undefined) as any; + if (params[0] === undefined || typeof params[0] === 'string') { + const instance = params[0] === undefined ? new Database() : new Database(params[0]); + + return construct(instance, params[1]) as any; } - if (typeof params[0] === 'object') { + if (isConfig(params[0])) { const { connection, client, ...drizzleConfig } = params[0] as & ({ connection?: DrizzleBunSqliteDatabaseConfig | string; @@ -141,9 +142,7 @@ export function drizzle< return construct(instance, drizzleConfig) as any; } - const instance = new Database(params[0]); - - return construct(instance, params[1]) as any; + return construct(params[0] as Database, params[1] as DrizzleConfig | undefined) as any; } export namespace drizzle { diff --git a/drizzle-orm/src/libsql/driver.ts b/drizzle-orm/src/libsql/driver.ts index c5e3957d2..378ae15d2 100644 --- a/drizzle-orm/src/libsql/driver.ts +++ b/drizzle-orm/src/libsql/driver.ts @@ -1,7 +1,4 @@ import { type Client, type Config, createClient, type ResultSet } from '@libsql/client'; -import { HttpClient } from '@libsql/client/http'; -import { Sqlite3Client } from '@libsql/client/sqlite3'; -import { WsClient } from '@libsql/client/ws'; import type { BatchItem, BatchResponse } from '~/batch.ts'; import { entityKind } from '~/entity.ts'; import { DefaultLogger } from '~/logger.ts'; @@ -14,7 +11,7 @@ import { } from '~/relations.ts'; import { BaseSQLiteDatabase } from '~/sqlite-core/db.ts'; import { SQLiteAsyncDialect } from '~/sqlite-core/dialect.ts'; -import type { DrizzleConfig, IfNotImported, ImportTypeError } from '~/utils.ts'; +import { type DrizzleConfig, type IfNotImported, type ImportTypeError, isConfig } from '~/utils.ts'; import { LibSQLSession } from './session.ts'; export class LibSQLDatabase< @@ -91,11 +88,6 @@ export function drizzle< ): LibSQLDatabase & { $client: TClient; } { - // eslint-disable-next-line no-instanceof/no-instanceof - if (params[0] instanceof WsClient || params[0] instanceof HttpClient || params[0] instanceof Sqlite3Client) { - return construct(params[0] as TClient, params[1] as DrizzleConfig | undefined) as any; - } - if (typeof params[0] === 'string') { const instance = createClient({ url: params[0], @@ -104,15 +96,19 @@ export function drizzle< return construct(instance, params[1]) as any; } - const { connection, client, ...drizzleConfig } = params[0] as - & { connection?: Config; client?: TClient } - & DrizzleConfig; + if (isConfig(params[0])) { + const { connection, client, ...drizzleConfig } = params[0] as + & { connection?: Config; client?: TClient } + & DrizzleConfig; - if (client) return construct(client, drizzleConfig) as any; + if (client) return construct(client, drizzleConfig) as any; - const instance = typeof connection === 'string' ? createClient({ url: connection }) : createClient(connection!); + const instance = typeof connection === 'string' ? createClient({ url: connection }) : createClient(connection!); + + return construct(instance, drizzleConfig) as any; + } - return construct(instance, drizzleConfig) as any; + return construct(params[0] as TClient, params[1] as DrizzleConfig | undefined) as any; } export namespace drizzle { diff --git a/drizzle-orm/src/mysql2/driver.ts b/drizzle-orm/src/mysql2/driver.ts index ef34604e3..ec791e571 100644 --- a/drizzle-orm/src/mysql2/driver.ts +++ b/drizzle-orm/src/mysql2/driver.ts @@ -1,4 +1,3 @@ -import { EventEmitter } from 'events'; import { type Connection as CallbackConnection, createPool, type Pool as CallbackPool, type PoolOptions } from 'mysql2'; import type { Connection, Pool } from 'mysql2/promise'; import { entityKind } from '~/entity.ts'; @@ -13,7 +12,7 @@ import { type RelationalSchemaConfig, type TablesRelationalConfig, } from '~/relations.ts'; -import type { DrizzleConfig, IfNotImported, ImportTypeError } from '~/utils.ts'; +import { type DrizzleConfig, type IfNotImported, type ImportTypeError, isConfig } from '~/utils.ts'; import { DrizzleError } from '../errors.ts'; import type { MySql2Client, MySql2PreparedQueryHKT, MySql2QueryResultHKT } from './session.ts'; import { MySql2Session } from './session.ts'; @@ -137,12 +136,16 @@ export function drizzle< ): MySql2Database & { $client: TClient; } { - // eslint-disable-next-line no-instanceof/no-instanceof - if (params[0] instanceof EventEmitter) { - return construct(params[0] as TClient, params[1] as MySql2DrizzleConfig | undefined) as any; + if (typeof params[0] === 'string') { + const connectionString = params[0]!; + const instance = createPool({ + uri: connectionString, + }); + + return construct(instance, params[1]) as any; } - if (typeof params[0] === 'object') { + if (isConfig(params[0])) { const { connection, client, ...drizzleConfig } = params[0] as & { connection?: PoolOptions | string; client?: TClient } & MySql2DrizzleConfig; @@ -159,12 +162,7 @@ export function drizzle< return db as any; } - const connectionString = params[0]!; - const instance = createPool({ - uri: connectionString, - }); - - return construct(instance, params[1]) as any; + return construct(params[0] as TClient, params[1] as MySql2DrizzleConfig | undefined) as any; } export namespace drizzle { diff --git a/drizzle-orm/src/neon-http/driver.ts b/drizzle-orm/src/neon-http/driver.ts index f79fd9de3..4ef1dc36a 100644 --- a/drizzle-orm/src/neon-http/driver.ts +++ b/drizzle-orm/src/neon-http/driver.ts @@ -8,7 +8,7 @@ import { PgDatabase } from '~/pg-core/db.ts'; import { PgDialect } from '~/pg-core/dialect.ts'; import { createTableRelationsHelpers, extractTablesRelationalConfig } from '~/relations.ts'; import type { ExtractTablesWithRelations, RelationalSchemaConfig, TablesRelationalConfig } from '~/relations.ts'; -import type { DrizzleConfig, IfNotImported, ImportTypeError } from '~/utils.ts'; +import { type DrizzleConfig, type IfNotImported, type ImportTypeError, isConfig } from '~/utils.ts'; import { type NeonHttpClient, type NeonHttpQueryResultHKT, NeonHttpSession } from './session.ts'; export interface NeonDriverOptions { @@ -124,12 +124,12 @@ export function drizzle< ): NeonHttpDatabase & { $client: TClient; } { - // eslint-disable-next-line no-instanceof/no-instanceof - if (typeof params[0] === 'function') { - return construct(params[0] as TClient, params[1] as DrizzleConfig | undefined) as any; + if (typeof params[0] === 'string') { + const instance = neon(params[0] as string); + return construct(instance, params[1]) as any; } - if (typeof params[0] === 'object') { + if (isConfig(params[0])) { const { connection, client, ...drizzleConfig } = params[0] as & { connection?: @@ -156,8 +156,7 @@ export function drizzle< return construct(instance, drizzleConfig) as any; } - const instance = neon(params[0] as string); - return construct(instance, params[1]) as any; + return construct(params[0] as TClient, params[1] as DrizzleConfig | undefined) as any; } export namespace drizzle { diff --git a/drizzle-orm/src/neon-serverless/driver.ts b/drizzle-orm/src/neon-serverless/driver.ts index c0f962e96..a1975c78b 100644 --- a/drizzle-orm/src/neon-serverless/driver.ts +++ b/drizzle-orm/src/neon-serverless/driver.ts @@ -10,7 +10,7 @@ import { type RelationalSchemaConfig, type TablesRelationalConfig, } from '~/relations.ts'; -import type { DrizzleConfig, IfNotImported, ImportTypeError } from '~/utils.ts'; +import { type DrizzleConfig, type IfNotImported, type ImportTypeError, isConfig } from '~/utils.ts'; import type { NeonClient, NeonQueryResultHKT } from './session.ts'; import { NeonSession } from './session.ts'; @@ -108,12 +108,15 @@ export function drizzle< ): NeonDatabase & { $client: TClient; } { - // eslint-disable-next-line no-instanceof/no-instanceof - if (params[0] instanceof Pool) { - return construct(params[0] as TClient, params[1] as DrizzleConfig | undefined) as any; + if (typeof params[0] === 'string') { + const instance = new Pool({ + connectionString: params[0], + }); + + return construct(instance, params[1]) as any; } - if (typeof params[0] === 'object') { + if (isConfig(params[0])) { const { connection, client, ws, ...drizzleConfig } = params[0] as { connection?: PoolConfig | string; ws?: any; @@ -135,11 +138,7 @@ export function drizzle< return construct(instance, drizzleConfig) as any; } - const instance = new Pool({ - connectionString: params[0], - }); - - return construct(instance, params[1]) as any; + return construct(params[0] as TClient, params[1] as DrizzleConfig | undefined) as any; } export namespace drizzle { diff --git a/drizzle-orm/src/node-postgres/driver.ts b/drizzle-orm/src/node-postgres/driver.ts index b9bb063d8..4b5b5eaab 100644 --- a/drizzle-orm/src/node-postgres/driver.ts +++ b/drizzle-orm/src/node-postgres/driver.ts @@ -1,4 +1,3 @@ -import { EventEmitter } from 'events'; import pg, { type Pool, type PoolConfig } from 'pg'; import { entityKind } from '~/entity.ts'; import type { Logger } from '~/logger.ts'; @@ -11,7 +10,7 @@ import { type RelationalSchemaConfig, type TablesRelationalConfig, } from '~/relations.ts'; -import type { DrizzleConfig, IfNotImported, ImportTypeError } from '~/utils.ts'; +import { type DrizzleConfig, type IfNotImported, type ImportTypeError, isConfig } from '~/utils.ts'; import type { NodePgClient, NodePgQueryResultHKT } from './session.ts'; import { NodePgSession } from './session.ts'; @@ -86,7 +85,7 @@ export function drizzle< >( ...params: IfNotImported< Pool, - [ImportTypeError<'pg'>], + [ImportTypeError<'@types/pg` `pg'>], | [ TClient | string, ] @@ -108,12 +107,15 @@ export function drizzle< ): NodePgDatabase & { $client: TClient; } { - // eslint-disable-next-line no-instanceof/no-instanceof - if (params[0] instanceof EventEmitter) { - return construct(params[0] as TClient, params[1] as DrizzleConfig | undefined) as any; + if (typeof params[0] === 'string') { + const instance = new pg.Pool({ + connectionString: params[0], + }); + + return construct(instance, params[1] as DrizzleConfig | undefined) as any; } - if (typeof params[0] === 'object') { + if (isConfig(params[0])) { const { connection, client, ...drizzleConfig } = params[0] as ( & ({ connection?: PoolConfig | string; client?: TClient }) & DrizzleConfig @@ -130,11 +132,7 @@ export function drizzle< return construct(instance, drizzleConfig) as any; } - const instance = new pg.Pool({ - connectionString: params[0], - }); - - return construct(instance, params[1] as DrizzleConfig | undefined) as any; + return construct(params[0] as TClient, params[1] as DrizzleConfig | undefined) as any; } export namespace drizzle { diff --git a/drizzle-orm/src/pglite/driver.ts b/drizzle-orm/src/pglite/driver.ts index 89d37d1f9..ee6aaa252 100644 --- a/drizzle-orm/src/pglite/driver.ts +++ b/drizzle-orm/src/pglite/driver.ts @@ -10,7 +10,7 @@ import { type RelationalSchemaConfig, type TablesRelationalConfig, } from '~/relations.ts'; -import type { DrizzleConfig, IfNotImported, ImportTypeError } from '~/utils.ts'; +import { type DrizzleConfig, type IfNotImported, type ImportTypeError, isConfig } from '~/utils.ts'; import type { PgliteClient, PgliteQueryResultHKT } from './session.ts'; import { PgliteSession } from './session.ts'; @@ -105,12 +105,12 @@ export function drizzle< ): PgliteDatabase & { $client: TClient; } { - // eslint-disable-next-line no-instanceof/no-instanceof - if (params[0] instanceof PGlite) { - return construct(params[0] as TClient, params[1] as DrizzleConfig | undefined) as any; + if (params[0] === undefined || typeof params[0] === 'string') { + const instance = new PGlite(params[0]); + return construct(instance, params[1]) as any; } - if (typeof params[0] === 'object') { + if (isConfig(params[0])) { const { connection, client, ...drizzleConfig } = params[0] as { connection?: PGliteOptions & { dataDir: string }; client?: TClient; @@ -131,8 +131,7 @@ export function drizzle< return construct(instance, drizzleConfig) as any; } - const instance = new PGlite(params[0]); - return construct(instance, params[1]) as any; + return construct(params[0] as TClient, params[1] as DrizzleConfig | undefined) as any; } export namespace drizzle { diff --git a/drizzle-orm/src/planetscale-serverless/driver.ts b/drizzle-orm/src/planetscale-serverless/driver.ts index 1865673bf..47988e5f3 100644 --- a/drizzle-orm/src/planetscale-serverless/driver.ts +++ b/drizzle-orm/src/planetscale-serverless/driver.ts @@ -11,7 +11,7 @@ import { type RelationalSchemaConfig, type TablesRelationalConfig, } from '~/relations.ts'; -import type { DrizzleConfig, IfNotImported, ImportTypeError } from '~/utils.ts'; +import { type DrizzleConfig, type IfNotImported, type ImportTypeError, isConfig } from '~/utils.ts'; import type { PlanetScalePreparedQueryHKT, PlanetscaleQueryResultHKT } from './session.ts'; import { PlanetscaleSession } from './session.ts'; @@ -122,12 +122,15 @@ export function drizzle< ): PlanetScaleDatabase & { $client: TClient; } { - // eslint-disable-next-line no-instanceof/no-instanceof - if (params[0] instanceof Client) { - return construct(params[0] as TClient, params[1] as DrizzleConfig | undefined) as any; + if (typeof params[0] === 'string') { + const instance = new Client({ + url: params[0], + }); + + return construct(instance, params[1]) as any; } - if (typeof params[0] === 'object') { + if (isConfig(params[0])) { const { connection, client, ...drizzleConfig } = params[0] as & { connection?: Config | string; client?: TClient } & DrizzleConfig; @@ -145,11 +148,7 @@ export function drizzle< return construct(instance, drizzleConfig) as any; } - const instance = new Client({ - url: params[0], - }); - - return construct(instance, params[1]) as any; + return construct(params[0] as TClient, params[1] as DrizzleConfig | undefined) as any; } export namespace drizzle { diff --git a/drizzle-orm/src/postgres-js/driver.ts b/drizzle-orm/src/postgres-js/driver.ts index 5c2979c84..5d1ff6755 100644 --- a/drizzle-orm/src/postgres-js/driver.ts +++ b/drizzle-orm/src/postgres-js/driver.ts @@ -9,7 +9,7 @@ import { type RelationalSchemaConfig, type TablesRelationalConfig, } from '~/relations.ts'; -import type { DrizzleConfig, IfNotImported, ImportTypeError } from '~/utils.ts'; +import { type DrizzleConfig, type IfNotImported, type ImportTypeError, isConfig } from '~/utils.ts'; import type { PostgresJsQueryResultHKT } from './session.ts'; import { PostgresJsSession } from './session.ts'; @@ -89,11 +89,13 @@ export function drizzle< ): PostgresJsDatabase & { $client: TClient; } { - if (typeof params[0] === 'function') { - return construct(params[0] as TClient, params[1] as DrizzleConfig | undefined) as any; + if (typeof params[0] === 'string') { + const instance = pgClient(params[0] as string); + + return construct(instance, params[1]) as any; } - if (typeof params[0] === 'object') { + if (isConfig(params[0])) { const { connection, client, ...drizzleConfig } = params[0] as { connection?: { url?: string } & Options>; client?: TClient; @@ -112,9 +114,7 @@ export function drizzle< return construct(instance, drizzleConfig) as any; } - const instance = pgClient(params[0] as string); - - return construct(instance, params[1]) as any; + return construct(params[0] as TClient, params[1] as DrizzleConfig | undefined) as any; } export namespace drizzle { diff --git a/drizzle-orm/src/tidb-serverless/driver.ts b/drizzle-orm/src/tidb-serverless/driver.ts index 01f54af6e..62fbfb9ab 100644 --- a/drizzle-orm/src/tidb-serverless/driver.ts +++ b/drizzle-orm/src/tidb-serverless/driver.ts @@ -1,4 +1,4 @@ -import { type Config, connect, Connection } from '@tidbcloud/serverless'; +import { type Config, connect, type Connection } from '@tidbcloud/serverless'; import { entityKind } from '~/entity.ts'; import type { Logger } from '~/logger.ts'; import { DefaultLogger } from '~/logger.ts'; @@ -10,7 +10,7 @@ import { type RelationalSchemaConfig, type TablesRelationalConfig, } from '~/relations.ts'; -import type { DrizzleConfig, IfNotImported, ImportTypeError } from '~/utils.ts'; +import { type DrizzleConfig, type IfNotImported, type ImportTypeError, isConfig } from '~/utils.ts'; import type { TiDBServerlessPreparedQueryHKT, TiDBServerlessQueryResultHKT } from './session.ts'; import { TiDBServerlessSession } from './session.ts'; @@ -82,11 +82,6 @@ export function drizzle< ): TiDBServerlessDatabase & { $client: TClient; } { - // eslint-disable-next-line no-instanceof/no-instanceof - if (params[0] instanceof Connection) { - return construct(params[0] as TClient, params[1] as DrizzleConfig | undefined) as any; - } - if (typeof params[0] === 'string') { const instance = connect({ url: params[0], @@ -95,19 +90,23 @@ export function drizzle< return construct(instance, params[1]) as any; } - const { connection, client, ...drizzleConfig } = params[0] as - & { connection?: Config | string; client?: TClient } - & DrizzleConfig; + if (isConfig(params[0])) { + const { connection, client, ...drizzleConfig } = params[0] as + & { connection?: Config | string; client?: TClient } + & DrizzleConfig; - if (client) return construct(client, drizzleConfig) as any; + if (client) return construct(client, drizzleConfig) as any; - const instance = typeof connection === 'string' - ? connect({ - url: connection, - }) - : connect(connection!); + const instance = typeof connection === 'string' + ? connect({ + url: connection, + }) + : connect(connection!); + + return construct(instance, drizzleConfig) as any; + } - return construct(instance, drizzleConfig) as any; + return construct(params[0] as TClient, params[1] as DrizzleConfig | undefined) as any; } export namespace drizzle { diff --git a/drizzle-orm/src/utils.ts b/drizzle-orm/src/utils.ts index 20abd0a5a..8d563d0da 100644 --- a/drizzle-orm/src/utils.ts +++ b/drizzle-orm/src/utils.ts @@ -240,8 +240,74 @@ export function getColumnNameAndConfig< export type IfNotImported = unknown extends T ? Y : N; export type ImportTypeError = - `Please install \`${TPackageName}\`to allow Drizzle ORM to connect to the database`; + `Please install \`${TPackageName}\` to allow Drizzle ORM to connect to the database`; export type RequireAtLeastOne = Keys extends any ? Required> & Partial> : never; + +type ExpectedConfigShape = { + logger?: boolean | { + logQuery(query: string, params: unknown[]): void; + }; + schema?: Record; + casing?: 'snake_case' | 'camelCase'; +}; + +// If this errors, you must update config shape checker function with new config specs +const _: DrizzleConfig = {} as ExpectedConfigShape; +const __: ExpectedConfigShape = {} as DrizzleConfig; + +export function isConfig(data: any): boolean { + if (typeof data !== 'object' || data === null) return false; + + if (data.constructor.name !== 'Object') return false; + + if ('logger' in data) { + const type = typeof data['logger']; + if ( + type !== 'boolean' && (type !== 'object' || typeof data['logger']['logQuery'] !== 'function') + && type !== 'undefined' + ) return false; + + return true; + } + + if ('schema' in data) { + const type = typeof data['logger']; + if (type !== 'object' && type !== 'undefined') return false; + + return true; + } + + if ('casing' in data) { + const type = typeof data['logger']; + if (type !== 'string' && type !== 'undefined') return false; + + return true; + } + + if ('mode' in data) { + if (data['mode'] !== 'default' || data['mode'] !== 'planetscale' || data['mode'] !== undefined) return false; + + return true; + } + + if ('connection' in data) { + const type = typeof data['connection']; + if (type !== 'string' && type !== 'object' && type !== 'undefined') return false; + + return true; + } + + if ('client' in data) { + const type = typeof data['client']; + if (type !== 'object' && type !== 'undefined') return false; + + return true; + } + + if (Object.keys(data).length === 0) return true; + + return false; +} diff --git a/drizzle-orm/src/vercel-postgres/driver.ts b/drizzle-orm/src/vercel-postgres/driver.ts index 5e6c44c27..44606a079 100644 --- a/drizzle-orm/src/vercel-postgres/driver.ts +++ b/drizzle-orm/src/vercel-postgres/driver.ts @@ -1,4 +1,4 @@ -import { type QueryResult, type QueryResultRow, sql, type VercelPool } from '@vercel/postgres'; +import { sql, type VercelPool } from '@vercel/postgres'; import { entityKind } from '~/entity.ts'; import type { Logger } from '~/logger.ts'; import { DefaultLogger } from '~/logger.ts'; @@ -10,7 +10,7 @@ import { type RelationalSchemaConfig, type TablesRelationalConfig, } from '~/relations.ts'; -import type { DrizzleConfig, IfNotImported, ImportTypeError } from '~/utils.ts'; +import { type DrizzleConfig, type IfNotImported, type ImportTypeError, isConfig } from '~/utils.ts'; import { type VercelPgClient, type VercelPgQueryResultHKT, VercelPgSession } from './session.ts'; export interface VercelPgDriverOptions { @@ -75,13 +75,9 @@ function construct = Record = Record, - TClient extends VercelPgClient = - & VercelPool - & ((strings: TemplateStringsArray, ...values: Primitive[]) => Promise>), + TClient extends VercelPgClient = typeof sql, >( ...params: IfNotImported< VercelPool, @@ -103,17 +99,12 @@ export function drizzle< ): VercelPgDatabase & { $client: TClient; } { - // eslint-disable-next-line no-instanceof/no-instanceof - if (typeof params[0] === 'function') { - return construct(params[0] as TClient, params[1] as DrizzleConfig | undefined) as any; - } - - if (!params[0] || !(params[0] as { client?: TClient }).client) { - return construct(sql, params[0] as DrizzleConfig | undefined) as any; + if (isConfig(params[0])) { + const { client, ...drizzleConfig } = params[0] as ({ client?: TClient } & DrizzleConfig); + return construct(client ?? sql, drizzleConfig) as any; } - const { client, ...drizzleConfig } = params[0] as ({ client?: TClient } & DrizzleConfig); - return construct(client ?? sql, drizzleConfig) as any; + return construct((params[0] ?? sql) as TClient, params[1] as DrizzleConfig | undefined) as any; } export namespace drizzle { diff --git a/integration-tests/.env.example b/integration-tests/.env.example index 50b3c95f2..c2e01d4f6 100644 --- a/integration-tests/.env.example +++ b/integration-tests/.env.example @@ -9,3 +9,4 @@ AWS_DATA_API_DB= AWS_DATA_API_SECRET_ARN= AWS_DATA_API_RESOURCE_ARN= AWS_TEST_PROFILE= +VERCEL_CONNECTION_STRING= # For driver-init, utils/is-config tests. Must not be local DB - breaks with Vercel drivers \ No newline at end of file diff --git a/integration-tests/js-tests/driver-init/commonjs/better-sqlite3.test.cjs b/integration-tests/js-tests/driver-init/commonjs/better-sqlite3.test.cjs new file mode 100644 index 000000000..1a9941e30 --- /dev/null +++ b/integration-tests/js-tests/driver-init/commonjs/better-sqlite3.test.cjs @@ -0,0 +1,124 @@ +require('dotenv/config'); +const Database = require('better-sqlite3'); +const { drizzle } = require('drizzle-orm/better-sqlite3'); +const { sqlite: schema } = require('./schema.cjs'); +import { describe, expect } from 'vitest'; + +describe('better-sqlite3', async (it) => { + it('drizzle()', async () => { + const db = drizzle(); + + await db.$client.exec('SELECT 1;'); + + await db.$client.close(); + }); + + it('drizzle(string)', async () => { + const db = drizzle(':memory:'); + + await db.$client.exec('SELECT 1;'); + + await db.$client.close(); + }); + + it('drizzle(string, config)', async () => { + const db = drizzle(':memory:', { + schema, + }); + + await db.$client.exec('SELECT 1;'); + + await db.$client.close(); + + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({connection: string, ...config})', async () => { + const db = drizzle({ + connection: ':memory:', + schema, + }); + + await db.$client.exec('SELECT 1;'); + + await db.$client.close(); + + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({connection: params, ...config})', async () => { + const db = drizzle({ + connection: { + source: ':memory:', + }, + schema, + }); + + await db.$client.exec('SELECT 1;'); + + await db.$client.close(); + + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({connection: {}, ...config})', async () => { + const db = drizzle({ + connection: {}, + schema, + }); + + await db.$client.exec('SELECT 1;'); + + await db.$client.close(); + + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({...config})', async () => { + const db = drizzle({ + schema, + }); + + await db.$client.exec('SELECT 1;'); + + await db.$client.close(); + + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle(client)', async () => { + const client = new Database(':memory:'); + const db = drizzle(client); + + await db.$client.exec('SELECT 1;'); + + await db.$client.close(); + }); + + it('drizzle(client, config)', async () => { + const client = new Database(':memory:'); + const db = drizzle(client, { + schema, + }); + + await db.$client.exec('SELECT 1;'); + + await db.$client.close(); + + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({client, ...config})', async () => { + const client = new Database(':memory:'); + const db = drizzle({ + client, + schema, + }); + + await db.$client.exec('SELECT 1;'); + + await db.$client.close(); + + expect(db.query.User).not.toStrictEqual(undefined); + }); +}); diff --git a/integration-tests/js-tests/driver-init/commonjs/libsql.test.cjs b/integration-tests/js-tests/driver-init/commonjs/libsql.test.cjs new file mode 100644 index 000000000..e070af1bc --- /dev/null +++ b/integration-tests/js-tests/driver-init/commonjs/libsql.test.cjs @@ -0,0 +1,97 @@ +require('dotenv/config'); +const { createClient } = require('@libsql/client'); +const { drizzle } = require('drizzle-orm/libsql'); +const { sqlite: schema } = require('./schema.cjs'); +import { describe, expect } from 'vitest'; + +describe('libsql', async (it) => { + it('drizzle(string)', async () => { + const db = drizzle(':memory:'); + + await db.$client.execute('SELECT 1;'); + + await db.$client.close(); + }); + + it('drizzle(string, config)', async () => { + const db = drizzle(':memory:', { + schema, + }); + + await db.$client.execute('SELECT 1;'); + + await db.$client.close(); + + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({connection: string, ...config})', async () => { + const db = drizzle({ + connection: ':memory:', + schema, + }); + + await db.$client.execute('SELECT 1;'); + + await db.$client.close(); + + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({connection: params, ...config})', async () => { + const db = drizzle({ + connection: { + url: ':memory:', + }, + schema, + }); + + await db.$client.execute('SELECT 1;'); + + await db.$client.close(); + + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle(client)', async () => { + const client = createClient({ + url: ':memory:', + }); + const db = drizzle(client); + + await db.$client.execute('SELECT 1;'); + + await db.$client.close(); + }); + + it('drizzle(client, config)', async () => { + const client = createClient({ + url: ':memory:', + }); + const db = drizzle(client, { + schema, + }); + + await db.$client.execute('SELECT 1;'); + + await db.$client.close(); + + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({client, ...config})', async () => { + const client = createClient({ + url: ':memory:', + }); + const db = drizzle({ + client, + schema, + }); + + await db.$client.execute('SELECT 1;'); + + await db.$client.close(); + + expect(db.query.User).not.toStrictEqual(undefined); + }); +}); diff --git a/integration-tests/js-tests/driver-init/commonjs/mysql2.test.cjs b/integration-tests/js-tests/driver-init/commonjs/mysql2.test.cjs new file mode 100644 index 000000000..44a0987d1 --- /dev/null +++ b/integration-tests/js-tests/driver-init/commonjs/mysql2.test.cjs @@ -0,0 +1,153 @@ +require('dotenv/config'); +const { drizzle } = require('drizzle-orm/mysql2'); +const { createPool, createConnection, Connection } = require('mysql2'); +const { mysql: schema } = require('./schema.cjs'); +import { describe, expect } from 'vitest'; + +if (!process.env['MYSQL_CONNECTION_STRING']) { + throw new Error('MYSQL_CONNECTION_STRING is not defined'); +} + +describe('mysql2', async (it) => { + it('drizzle(string)', async () => { + const db = drizzle( + process.env['MYSQL_CONNECTION_STRING'], + ); + + await db.$client.execute(`SELECT 1`); + + expect(db.$client.getConnection).not.toStrictEqual(undefined); + }); + + it('drizzle(string, config)', async () => { + const db = drizzle( + process.env['MYSQL_CONNECTION_STRING'], + { + schema, + mode: 'default', + }, + ); + await db.$client.execute('SELECT 1;'); + + expect(db.query.User).not.toStrictEqual(undefined); + expect(db.$client.getConnection).not.toStrictEqual(undefined); + }); + + it('drizzle({connection: string, ...config})', async () => { + const db = drizzle({ + connection: process.env['MYSQL_CONNECTION_STRING'], + schema, + mode: 'default', + }); + + await db.$client.execute('SELECT 1;'); + + expect(db.query.User).not.toStrictEqual(undefined); + expect(db.$client.getConnection).not.toStrictEqual(undefined); + }); + + it('drizzle({connection: params, ...config})', async () => { + const db = drizzle({ + connection: { + uri: process.env['MYSQL_CONNECTION_STRING'], + }, + schema, + mode: 'default', + }); + + await db.$client.execute('SELECT 1;'); + + expect(db.query.User).not.toStrictEqual(undefined); + expect(db.$client.getConnection).not.toStrictEqual(undefined); + }); + + it('drizzle(client)', async () => { + const client = createPool({ + uri: process.env['MYSQL_CONNECTION_STRING'], + }); + + const db = drizzle(client); + + await db.$client.execute('SELECT 1;'); + + expect(db.$client.getConnection).not.toStrictEqual(undefined); + }); + + it('drizzle(client, config)', async () => { + const client = createPool({ + uri: process.env['MYSQL_CONNECTION_STRING'], + }); + const db = drizzle(client, { + schema, + mode: 'default', + }); + + await db.$client.execute('SELECT 1;'); + + expect(db.query.User).not.toStrictEqual(undefined); + expect(db.$client.getConnection).not.toStrictEqual(undefined); + }); + + it('drizzle({client, ...config})', async () => { + const client = createPool({ + uri: process.env['MYSQL_CONNECTION_STRING'], + }); + + const db = drizzle({ + client, + schema, + mode: 'default', + }); + + await db.$client.execute('SELECT 1;'); + + expect(db.query.User).not.toStrictEqual(undefined); + expect(db.$client.getConnection).not.toStrictEqual(undefined); + }); +}); + +describe('mysql2:connection', async (it) => { + it('drizzle(client)', async () => { + const client = createConnection({ + uri: process.env['MYSQL_CONNECTION_STRING'], + }); + + const db = drizzle(client); + + await db.$client.execute('SELECT 1;'); + + expect(db.$client.getConnection).toStrictEqual(undefined); + }); + + it('drizzle(client, config)', async () => { + const client = createConnection({ + uri: process.env['MYSQL_CONNECTION_STRING'], + }); + const db = drizzle(client, { + schema, + mode: 'default', + }); + + await db.$client.execute('SELECT 1;'); + + expect(db.query.User).not.toStrictEqual(undefined); + expect(db.$client.getConnection).toStrictEqual(undefined); + }); + + it('drizzle({client, ...config})', async () => { + const client = createConnection({ + uri: process.env['MYSQL_CONNECTION_STRING'], + }); + + const db = drizzle({ + client, + schema, + mode: 'default', + }); + + await db.$client.execute('SELECT 1;'); + + expect(db.query.User).not.toStrictEqual(undefined); + expect(db.$client.getConnection).toStrictEqual(undefined); + }); +}); diff --git a/integration-tests/js-tests/driver-init/commonjs/neon-http.test.cjs b/integration-tests/js-tests/driver-init/commonjs/neon-http.test.cjs new file mode 100644 index 000000000..ad68b96a3 --- /dev/null +++ b/integration-tests/js-tests/driver-init/commonjs/neon-http.test.cjs @@ -0,0 +1,92 @@ +require('dotenv/config'); +const { neon: pg } = require('@neondatabase/serverless'); +const { drizzle } = require('drizzle-orm/neon-http'); +const { pg: schema } = require('./schema.cjs'); +import { describe, expect } from 'vitest'; + +if (!process.env['NEON_CONNECTION_STRING']) { + throw new Error('NEON_CONNECTION_STRING is not defined'); +} + +describe('neon-http', async (it) => { + it('drizzle(string)', async () => { + const db = drizzle( + process.env['NEON_CONNECTION_STRING'], + ); + + await db.$client('SELECT 1;'); + }); + + it('drizzle(string, config)', async () => { + const db = drizzle( + process.env['NEON_CONNECTION_STRING'], + { + schema, + }, + ); + + await db.$client('SELECT 1;'); + + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({connection: string, ...config})', async () => { + const db = drizzle({ + connection: process.env['NEON_CONNECTION_STRING'], + schema, + }); + + await db.$client('SELECT 1;'); + + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({connection: params, ...config})', async () => { + const db = drizzle({ + connection: { + connectionString: process.env['NEON_CONNECTION_STRING'], + }, + schema, + }); + + await db.$client('SELECT 1;'); + + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle(client)', async () => { + const client = pg( + process.env['NEON_CONNECTION_STRING'], + ); + const db = drizzle(client); + + await db.$client('SELECT 1;'); + }); + + it('drizzle(client, config)', async () => { + const client = pg( + process.env['NEON_CONNECTION_STRING'], + ); + const db = drizzle(client, { + schema, + }); + + await db.$client('SELECT 1;'); + + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({client, ...config})', async () => { + const client = pg( + process.env['NEON_CONNECTION_STRING'], + ); + const db = drizzle({ + client, + schema, + }); + + await db.$client('SELECT 1;'); + + expect(db.query.User).not.toStrictEqual(undefined); + }); +}); diff --git a/integration-tests/js-tests/driver-init/commonjs/neon-ws.test.cjs b/integration-tests/js-tests/driver-init/commonjs/neon-ws.test.cjs new file mode 100644 index 000000000..28b5026c6 --- /dev/null +++ b/integration-tests/js-tests/driver-init/commonjs/neon-ws.test.cjs @@ -0,0 +1,211 @@ +require('dotenv/config'); +const { neonConfig, Pool, Client } = require('@neondatabase/serverless'); +const { drizzle } = require('drizzle-orm/neon-serverless'); +const { pg: schema } = require('./schema.cjs'); +const ws = require('ws'); +import { describe, expect } from 'vitest'; + +neonConfig.webSocketConstructor = ws; + +if (!process.env['NEON_CONNECTION_STRING']) { + throw new Error('NEON_CONNECTION_STRING is not defined'); +} + +describe('neon-ws', async (it) => { + it('drizzle(string)', async () => { + const db = drizzle( + process.env['NEON_CONNECTION_STRING'], + ); + + await db.$client.query('SELECT 1;'); + }); + + it('drizzle(string, config)', async () => { + const db = drizzle( + process.env['NEON_CONNECTION_STRING'], + { + schema, + }, + ); + + await db.$client.query('SELECT 1;'); + + expect(db.query.User).not.toStrictEqual(undefined); + expect(db.$client).toBeInstanceOf(Pool); + }); + + it('drizzle({connection: string, ...config})', async () => { + const db = drizzle({ + connection: process.env['NEON_CONNECTION_STRING'], + schema, + }); + + await db.$client.query('SELECT 1;'); + + expect(db.query.User).not.toStrictEqual(undefined); + expect(db.$client).toBeInstanceOf(Pool); + }); + + it('drizzle({connection: params, ...config})', async () => { + const db = drizzle({ + connection: { + connectionString: process.env['NEON_CONNECTION_STRING'], + }, + schema, + }); + + await db.$client.query('SELECT 1;'); + + expect(db.query.User).not.toStrictEqual(undefined); + expect(db.$client).toBeInstanceOf(Pool); + }); + + it('drizzle(client)', async () => { + const client = new Pool({ + connectionString: process.env['NEON_CONNECTION_STRING'], + }); + const db = drizzle(client); + + await db.$client.query('SELECT 1;'); + + expect(db.$client).toBeInstanceOf(Pool); + }); + + it('drizzle(client, config)', async () => { + const client = new Pool({ + connectionString: process.env['NEON_CONNECTION_STRING'], + }); + const db = drizzle(client, { + schema, + }); + + await db.$client.query('SELECT 1;'); + + expect(db.query.User).not.toStrictEqual(undefined); + expect(db.$client).toBeInstanceOf(Pool); + }); + + it('drizzle({client, ...config})', async () => { + const client = new Pool({ + connectionString: process.env['NEON_CONNECTION_STRING'], + }); + const db = drizzle({ + client, + schema, + }); + + await db.$client.query('SELECT 1;'); + + expect(db.query.User).not.toStrictEqual(undefined); + expect(db.$client).toBeInstanceOf(Pool); + }); +}); + +describe('neon-ws:Client', async (it) => { + it('drizzle(client)', async () => { + const client = new Client({ + connectionString: process.env['NEON_CONNECTION_STRING'], + }); + + await client.connect(); + + const db = drizzle(client); + + await db.$client.query('SELECT 1;'); + + expect(db.$client).toBeInstanceOf(Client); + expect(db.$client).not.toBeInstanceOf(Pool); + }); + + it('drizzle(client, config)', async () => { + const client = new Client({ + connectionString: process.env['NEON_CONNECTION_STRING'], + }); + const db = drizzle(client, { + schema, + }); + + await client.connect(); + + await db.$client.query('SELECT 1;'); + + expect(db.query.User).not.toStrictEqual(undefined); + expect(db.$client).toBeInstanceOf(Client); + expect(db.$client).not.toBeInstanceOf(Pool); + }); + + it('drizzle({client, ...config})', async () => { + const client = new Client({ + connectionString: process.env['NEON_CONNECTION_STRING'], + }); + const db = drizzle({ + client, + schema, + }); + + await client.connect(); + + await db.$client.query('SELECT 1;'); + + expect(db.query.User).not.toStrictEqual(undefined); + expect(db.$client).toBeInstanceOf(Client); + expect(db.$client).not.toBeInstanceOf(Pool); + }); +}); + +describe('neon-ws:PoolClient', async (it) => { + it('drizzle(client)', async () => { + const pool = new Pool({ + connectionString: process.env['NEON_CONNECTION_STRING'], + }); + const client = await pool.connect(); + + const db = drizzle(client); + + await db.$client.query('SELECT 1;'); + + client.release(); + + expect(db.$client).toBeInstanceOf(Client); + expect(db.$client).not.toBeInstanceOf(Pool); + }); + + it('drizzle(client, config)', async () => { + const pool = new Pool({ + connectionString: process.env['NEON_CONNECTION_STRING'], + }); + const client = await pool.connect(); + + const db = drizzle(client, { + schema, + }); + + await db.$client.query('SELECT 1;'); + + client.release(); + + expect(db.query.User).not.toStrictEqual(undefined); + expect(db.$client).toBeInstanceOf(Client); + expect(db.$client).not.toBeInstanceOf(Pool); + }); + + it('drizzle({client, ...config})', async () => { + const pool = new Pool({ + connectionString: process.env['NEON_CONNECTION_STRING'], + }); + const client = await pool.connect(); + + const db = drizzle({ + client, + schema, + }); + + await db.$client.query('SELECT 1;'); + + client.release(); + + expect(db.query.User).not.toStrictEqual(undefined); + expect(db.$client).toBeInstanceOf(Client); + expect(db.$client).not.toBeInstanceOf(Pool); + }); +}); diff --git a/integration-tests/js-tests/driver-init/commonjs/node-pg.test.cjs b/integration-tests/js-tests/driver-init/commonjs/node-pg.test.cjs new file mode 100644 index 000000000..53338d061 --- /dev/null +++ b/integration-tests/js-tests/driver-init/commonjs/node-pg.test.cjs @@ -0,0 +1,201 @@ +require('dotenv/config'); +const { drizzle } = require('drizzle-orm/node-postgres'); +const pg = require('pg'); +const { pg: schema } = require('./schema.cjs'); +import { describe, expect } from 'vitest'; + +const Pool = pg.Pool; +const Client = pg.Client; + +if (!process.env['PG_CONNECTION_STRING']) { + throw new Error('PG_CONNECTION_STRING is not defined'); +} + +describe('node-pg', async (it) => { + it('drizzle(string)', async () => { + const db = drizzle(process.env['PG_CONNECTION_STRING']); + + await db.$client.query('SELECT 1;'); + + expect(db.$client).toBeInstanceOf(Pool); + }); + + it('drizzle(string, config)', async () => { + const db = drizzle(process.env['PG_CONNECTION_STRING'], { + schema, + }); + + await db.$client.query('SELECT 1;'); + + expect(db.$client).toBeInstanceOf(Pool); + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({connection: string, ...config})', async () => { + const db = drizzle({ + connection: process.env['PG_CONNECTION_STRING'], + schema, + }); + + await db.$client.query('SELECT 1;'); + + expect(db.$client).toBeInstanceOf(Pool); + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({connection: params, ...config})', async () => { + const db = drizzle({ + connection: { + connectionString: process.env['PG_CONNECTION_STRING'], + }, + schema, + }); + + await db.$client.query('SELECT 1;'); + + expect(db.$client).toBeInstanceOf(Pool); + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle(client)', async () => { + const client = new Pool({ + connectionString: process.env['PG_CONNECTION_STRING'], + }); + const db = drizzle(client); + + await db.$client.query('SELECT 1;'); + + expect(db.$client).toBeInstanceOf(Pool); + }); + + it('drizzle(client, config)', async () => { + const client = new Pool({ + connectionString: process.env['PG_CONNECTION_STRING'], + }); + const db = drizzle(client, { + schema, + }); + + await db.$client.query('SELECT 1;'); + + expect(db.$client).toBeInstanceOf(Pool); + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({client, ...config})', async () => { + const client = new Pool({ + connectionString: process.env['PG_CONNECTION_STRING'], + }); + const db = drizzle({ + client, + schema, + }); + + await db.$client.query('SELECT 1;'); + + expect(db.$client).toBeInstanceOf(Pool); + expect(db.query.User).not.toStrictEqual(undefined); + }); +}); + +describe('node-pg:Client', async (it) => { + it('drizzle(client)', async () => { + const client = new Client({ + connectionString: process.env['PG_CONNECTION_STRING'], + }); + const db = drizzle(client); + + await client.connect(); + + await db.$client.query('SELECT 1;'); + + expect(db.$client).not.toBeInstanceOf(Pool); + expect(db.$client).toBeInstanceOf(Client); + }); + + it('drizzle(client, config)', async () => { + const client = new Client({ + connectionString: process.env['PG_CONNECTION_STRING'], + }); + const db = drizzle(client, { + schema, + }); + + await client.connect(); + + await db.$client.query('SELECT 1;'); + + expect(db.$client).not.toBeInstanceOf(Pool); + expect(db.$client).toBeInstanceOf(Client); + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({client, ...config})', async () => { + const client = new Client({ + connectionString: process.env['PG_CONNECTION_STRING'], + }); + const db = drizzle({ + client, + schema, + }); + + await client.connect(); + + await db.$client.query('SELECT 1;'); + + expect(db.$client).not.toBeInstanceOf(Pool); + expect(db.$client).toBeInstanceOf(Client); + expect(db.query.User).not.toStrictEqual(undefined); + }); +}); + +describe('node-pg:PoolClient', async (it) => { + it('drizzle(client)', async () => { + const pool = new Pool({ + connectionString: process.env['PG_CONNECTION_STRING'], + }); + const client = await pool.connect(); + const db = drizzle(client); + + await db.$client.query('SELECT 1;'); + client.release(); + + expect(db.$client).not.toBeInstanceOf(Pool); + expect(db.$client).toBeInstanceOf(Client); + }); + + it('drizzle(client, config)', async () => { + const pool = new Pool({ + connectionString: process.env['PG_CONNECTION_STRING'], + }); + const client = await pool.connect(); + const db = drizzle(client, { + schema, + }); + + await db.$client.query('SELECT 1;'); + client.release(); + + expect(db.$client).not.toBeInstanceOf(Pool); + expect(db.$client).toBeInstanceOf(Client); + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({client, ...config})', async () => { + const pool = new Pool({ + connectionString: process.env['PG_CONNECTION_STRING'], + }); + const client = await pool.connect(); + const db = drizzle({ + client, + schema, + }); + + await db.$client.query('SELECT 1;'); + client.release(); + + expect(db.$client).not.toBeInstanceOf(Pool); + expect(db.$client).toBeInstanceOf(Client); + expect(db.query.User).not.toStrictEqual(undefined); + }); +}); diff --git a/integration-tests/js-tests/driver-init/commonjs/pglite.test.cjs b/integration-tests/js-tests/driver-init/commonjs/pglite.test.cjs new file mode 100644 index 000000000..a00afb041 --- /dev/null +++ b/integration-tests/js-tests/driver-init/commonjs/pglite.test.cjs @@ -0,0 +1,88 @@ +require('dotenv/config'); +const { drizzle } = require('drizzle-orm/pglite'); +const { pg: schema } = require('./schema.cjs'); +const { PGlite: Database } = require('@electric-sql/pglite'); +import { describe, expect } from 'vitest'; + +describe('pglite', async (it) => { + it('drizzle()', async () => { + const db = drizzle(); + + await db.$client.exec('SELECT 1;'); + await db.$client.close(); + }); + + it('drizzle(string)', async () => { + const db = drizzle('memory://'); + + await db.$client.exec('SELECT 1;'); + await db.$client.close(); + }); + + it('drizzle(string, config)', async () => { + const db = drizzle('memory://', { + schema, + }); + + await db.$client.exec('SELECT 1;'); + await db.$client.close(); + + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({connection: {}, ...config})', async () => { + const db = drizzle({ + connection: {}, + schema, + }); + + await db.$client.exec('SELECT 1;'); + await db.$client.close(); + + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({...config})', async () => { + const db = drizzle({ + schema, + }); + + await db.$client.exec('SELECT 1;'); + await db.$client.close(); + + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle(client)', async () => { + const client = new Database('memory://'); + const db = drizzle(client); + + await db.$client.exec('SELECT 1;'); + await db.$client.close(); + }); + + it('drizzle(client, config)', async () => { + const client = new Database('memory://'); + const db = drizzle(client, { + schema, + }); + + await db.$client.exec('SELECT 1;'); + await db.$client.close(); + + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({client, ...config})', async () => { + const client = new Database('memory://'); + const db = drizzle({ + client, + schema, + }); + + await db.$client.exec('SELECT 1;'); + await db.$client.close(); + + expect(db.query.User).not.toStrictEqual(undefined); + }); +}); diff --git a/integration-tests/js-tests/driver-init/commonjs/planetscale.test.cjs b/integration-tests/js-tests/driver-init/commonjs/planetscale.test.cjs new file mode 100644 index 000000000..2a7bffec1 --- /dev/null +++ b/integration-tests/js-tests/driver-init/commonjs/planetscale.test.cjs @@ -0,0 +1,146 @@ +require('dotenv/config'); +const { Client, Connection } = require('@planetscale/database'); +const { drizzle } = require('drizzle-orm/planetscale-serverless'); +const { mysql: schema } = require('./schema.cjs'); +import { describe, expect } from 'vitest'; + +if (!process.env['PLANETSCALE_CONNECTION_STRING']) { + throw new Error('PLANETSCALE_CONNECTION_STRING is not defined'); +} + +describe('planetscale', async (it) => { + it('drizzle(string)', async () => { + const db = drizzle( + process.env['PLANETSCALE_CONNECTION_STRING'], + ); + + await db.$client.execute('SELECT 1;'); + + expect(db.$client).toBeInstanceOf(Client); + }); + + it('drizzle(string, config)', async () => { + const db = drizzle( + process.env['PLANETSCALE_CONNECTION_STRING'], + { + schema, + }, + ); + + await db.$client.execute('SELECT 1;'); + + expect(db.$client).toBeInstanceOf(Client); + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({connection: string, ...config})', async () => { + const db = drizzle({ + connection: process.env['PLANETSCALE_CONNECTION_STRING'], + schema, + }); + + await db.$client.execute('SELECT 1;'); + + expect(db.$client).toBeInstanceOf(Client); + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({connection: params, ...config})', async () => { + const db = drizzle({ + connection: { + url: process.env['PLANETSCALE_CONNECTION_STRING'], + }, + schema, + }); + + await db.$client.execute('SELECT 1;'); + + expect(db.$client).toBeInstanceOf(Client); + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle(client)', async () => { + const client = new Client({ + url: process.env['PLANETSCALE_CONNECTION_STRING'], + }); + const db = drizzle(client); + + await db.$client.execute('SELECT 1;'); + + expect(db.$client).toBeInstanceOf(Client); + }); + + it('drizzle(client, config)', async () => { + const client = new Client({ + url: process.env['PLANETSCALE_CONNECTION_STRING'], + }); + const db = drizzle(client, { + schema, + }); + + await db.$client.execute('SELECT 1;'); + + expect(db.$client).toBeInstanceOf(Client); + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({client, ...config})', async () => { + const client = new Client({ + url: process.env['PLANETSCALE_CONNECTION_STRING'], + }); + const db = drizzle({ + client, + schema, + }); + + await db.$client.execute('SELECT 1;'); + + expect(db.$client).toBeInstanceOf(Client); + expect(db.query.User).not.toStrictEqual(undefined); + }); +}); + +describe('planetscale:Connection', async (it) => { + it('drizzle(client)', async () => { + const client = new Connection({ + url: process.env['PLANETSCALE_CONNECTION_STRING'], + }); + const db = drizzle(client); + + await db.$client.execute('SELECT 1;'); + + expect(db.$client).not.toBeInstanceOf(Client); + expect(db.$client).toBeInstanceOf(Connection); + }); + + it('drizzle(client, config)', async () => { + const client = new Connection({ + url: process.env['PLANETSCALE_CONNECTION_STRING'], + }); + const db = drizzle(client, { + schema, + }); + + await db.$client.execute('SELECT 1;'); + + expect(db.$client).not.toBeInstanceOf(Client); + expect(db.$client).toBeInstanceOf(Connection); + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({client, ...config})', async () => { + const client = new Connection({ + url: process.env['PLANETSCALE_CONNECTION_STRING'], + }); + const db = drizzle({ + client, + schema, + }); + + await db.$client.execute('SELECT 1;'); + + expect(db.$client).not.toBeInstanceOf(Client); + expect(db.$client).toBeInstanceOf(Connection); + expect(db.query.User).not.toStrictEqual(undefined); + }); +}); diff --git a/integration-tests/js-tests/driver-init/commonjs/postgres-js.test.cjs b/integration-tests/js-tests/driver-init/commonjs/postgres-js.test.cjs new file mode 100644 index 000000000..da79953f3 --- /dev/null +++ b/integration-tests/js-tests/driver-init/commonjs/postgres-js.test.cjs @@ -0,0 +1,81 @@ +require('dotenv/config'); +const { drizzle } = require('drizzle-orm/postgres-js'); +const pg = require('postgres'); +const { pg: schema } = require('./schema.cjs'); +import { describe, expect } from 'vitest'; + +if (!process.env['PG_CONNECTION_STRING']) { + throw new Error('PG_CONNECTION_STRING is not defined'); +} + +describe('postgres-js', async (it) => { + it('drizzle(string)', async () => { + const db = drizzle(process.env['PG_CONNECTION_STRING']); + + await db.$client.unsafe('SELECT 1;'); + }); + + it('drizzle(string, config)', async () => { + const db = drizzle(process.env['PG_CONNECTION_STRING'], { + schema, + }); + + await db.$client.unsafe('SELECT 1;'); + + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({connection: string, ...config})', async () => { + const db = drizzle({ + connection: process.env['PG_CONNECTION_STRING'], + schema, + }); + + await db.$client.unsafe('SELECT 1;'); + + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({connection: params, ...config})', async () => { + const db = drizzle({ + connection: { + url: process.env['PG_CONNECTION_STRING'], + }, + schema, + }); + + await db.$client.unsafe('SELECT 1;'); + + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle(client)', async () => { + const client = pg(process.env['PG_CONNECTION_STRING']); + const db = drizzle(client); + + await db.$client.unsafe('SELECT 1;'); + }); + + it('drizzle(client, config)', async () => { + const client = pg(process.env['PG_CONNECTION_STRING']); + const db = drizzle(client, { + schema, + }); + + await db.$client.unsafe('SELECT 1;'); + + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({client, ...config})', async () => { + const client = pg(process.env['PG_CONNECTION_STRING']); + const db = drizzle({ + client, + schema, + }); + + await db.$client.unsafe('SELECT 1;'); + + expect(db.query.User).not.toStrictEqual(undefined); + }); +}); diff --git a/integration-tests/js-tests/driver-init/commonjs/schema.cjs b/integration-tests/js-tests/driver-init/commonjs/schema.cjs new file mode 100644 index 000000000..7015a068d --- /dev/null +++ b/integration-tests/js-tests/driver-init/commonjs/schema.cjs @@ -0,0 +1,21 @@ +const { int: mysqlInt, mysqlTable } = require('drizzle-orm/mysql-core'); +const { integer: pgInt, pgTable } = require('drizzle-orm/pg-core'); +const { integer: sqliteInt, sqliteTable } = require('drizzle-orm/sqlite-core'); + +module.exports.sqlite = { + User: sqliteTable('test', { + id: sqliteInt('id').primaryKey().notNull(), + }), +}; + +module.exports.pg = { + User: pgTable('test', { + id: pgInt('id').primaryKey().notNull(), + }), +}; + +module.exports.mysql = { + User: mysqlTable('test', { + id: mysqlInt('id').primaryKey().notNull(), + }), +}; diff --git a/integration-tests/js-tests/driver-init/commonjs/tidb.test.cjs b/integration-tests/js-tests/driver-init/commonjs/tidb.test.cjs new file mode 100644 index 000000000..a64588b8a --- /dev/null +++ b/integration-tests/js-tests/driver-init/commonjs/tidb.test.cjs @@ -0,0 +1,88 @@ +require('dotenv/config'); +const { connect } = require('@tidbcloud/serverless'); +const { drizzle } = require('drizzle-orm/tidb-serverless'); +const { mysql: schema } = require('./schema.cjs'); +import { describe, expect } from 'vitest'; + +if (!process.env['TIDB_CONNECTION_STRING']) { + throw new Error('TIDB_CONNECTION_STRING is not defined'); +} + +describe('tidb', async (it) => { + it('drizzle(string)', async () => { + const db = drizzle( + process.env['TIDB_CONNECTION_STRING'], + ); + + await db.$client.execute(`SELECT 1`); + }); + + it('drizzle(string, config)', async () => { + const db = drizzle( + process.env['TIDB_CONNECTION_STRING'], + { + schema, + }, + ); + + await db.$client.execute('SELECT 1;'); + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({connection: string, ...config})', async () => { + const db = drizzle({ + connection: process.env['TIDB_CONNECTION_STRING'], + schema, + }); + + await db.$client.execute('SELECT 1;'); + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({connection: params, ...config})', async () => { + const db = drizzle({ + connection: { + url: process.env['TIDB_CONNECTION_STRING'], + }, + schema, + }); + + await db.$client.execute('SELECT 1;'); + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle(client)', async () => { + const client = connect({ + url: process.env['TIDB_CONNECTION_STRING'], + }); + + const db = drizzle(client); + + await db.$client.execute('SELECT 1;'); + }); + + it('drizzle(client, config)', async () => { + const client = connect({ + url: process.env['TIDB_CONNECTION_STRING'], + }); + const db = drizzle(client, { + schema, + }); + + await db.$client.execute('SELECT 1;'); + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({client, ...config})', async () => { + const client = connect({ + url: process.env['TIDB_CONNECTION_STRING'], + }); + const db = drizzle({ + client, + schema, + }); + + await db.$client.execute('SELECT 1;'); + expect(db.query.User).not.toStrictEqual(undefined); + }); +}); diff --git a/integration-tests/js-tests/driver-init/commonjs/vercel.test.cjs b/integration-tests/js-tests/driver-init/commonjs/vercel.test.cjs new file mode 100644 index 000000000..ad418a26e --- /dev/null +++ b/integration-tests/js-tests/driver-init/commonjs/vercel.test.cjs @@ -0,0 +1,229 @@ +require('dotenv/config'); +const vc = require('@vercel/postgres'); +const { drizzle } = require('drizzle-orm/vercel-postgres'); +const { pg: schema } = require('./schema.cjs'); +import { describe, expect } from 'vitest'; +const { sql, createClient, createPool } = vc; + +const Pool = vc.VercelPool; +const Client = vc.VercelClient; + +if (!process.env['VERCEL_CONNECTION_STRING']) { + throw new Error('VERCEL_CONNECTION_STRING is not defined'); +} + +// Used for non-pooled connection +if (!process.env['NEON_CONNECTION_STRING']) { + throw new Error('NEON_CONNECTION_STRING is not defined'); +} +process.env['POSTGRES_URL'] = process.env['VERCEL_CONNECTION_STRING']; + +describe('vercel:sql', async (it) => { + it('drizzle()', async () => { + const db = drizzle(); + + await sql.connect(); + + await db.$client.query('SELECT 1;'); + + expect(db.$client).toBeTypeOf('function'); + }); + + it('drizzle(client)', async () => { + const db = drizzle(sql); + + await db.$client.query('SELECT 1;'); + + expect(db.$client).toBeTypeOf('function'); + }); + + it('drizzle(client, config)', async () => { + const db = drizzle(sql, { + schema, + }); + + await db.$client.query('SELECT 1;'); + + expect(db.$client).toBeTypeOf('function'); + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({client, ...config})', async () => { + const db = drizzle({ + client: sql, + schema, + }); + + await db.$client.query('SELECT 1;'); + + expect(db.$client).toBeTypeOf('function'); + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({...config})', async () => { + const db = drizzle({ + schema, + }); + + await db.$client.query('SELECT 1;'); + + expect(db.$client).toBeTypeOf('function'); + expect(db.query.User).not.toStrictEqual(undefined); + }); +}); + +describe('vercel:Pool', async (it) => { + it('drizzle(client)', async () => { + const client = createPool({ + connectionString: process.env['VERCEL_CONNECTION_STRING'], + }); + const db = drizzle(client); + + await db.$client.query('SELECT 1;'); + + expect(db.$client).not.toBeTypeOf('function'); + expect(db.$client).toBeInstanceOf(Pool); + }); + + it('drizzle(client, config)', async () => { + const client = createPool({ + connectionString: process.env['VERCEL_CONNECTION_STRING'], + }); + const db = drizzle(client, { + schema, + }); + + await db.$client.query('SELECT 1;'); + + expect(db.$client).not.toBeTypeOf('function'); + expect(db.$client).toBeInstanceOf(Pool); + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({client, ...config})', async () => { + const client = createPool({ + connectionString: process.env['VERCEL_CONNECTION_STRING'], + }); + const db = drizzle({ + client: client, + schema, + }); + + await db.$client.query('SELECT 1;'); + + expect(db.$client).not.toBeTypeOf('function'); + expect(db.$client).toBeInstanceOf(Pool); + expect(db.query.User).not.toStrictEqual(undefined); + }); +}); + +describe('vercel:Client', async (it) => { + it('drizzle(client)', async () => { + const client = createClient({ + connectionString: process.env['NEON_CONNECTION_STRING'], + }); + const db = drizzle(client); + + await client.connect(); + + await db.$client.query('SELECT 1;'); + + expect(db.$client).not.toBeTypeOf('function'); + expect(db.$client).not.toBeInstanceOf(Pool); + expect(db.$client).toBeInstanceOf(Client); + }); + + it('drizzle(client, config)', async () => { + const client = createClient({ + connectionString: process.env['NEON_CONNECTION_STRING'], + }); + const db = drizzle(client, { + schema, + }); + + await client.connect(); + + await db.$client.query('SELECT 1;'); + + expect(db.$client).not.toBeTypeOf('function'); + expect(db.$client).not.toBeInstanceOf(Pool); + expect(db.$client).toBeInstanceOf(Client); + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({client, ...config})', async () => { + const client = createClient({ + connectionString: process.env['NEON_CONNECTION_STRING'], + }); + const db = drizzle({ + client: client, + schema, + }); + + await client.connect(); + + await db.$client.query('SELECT 1;'); + + expect(db.$client).not.toBeTypeOf('function'); + expect(db.$client).not.toBeInstanceOf(Pool); + expect(db.$client).toBeInstanceOf(Client); + expect(db.query.User).not.toStrictEqual(undefined); + }); +}); + +describe('vercel:PoolClient', async (it) => { + it('drizzle(client)', async () => { + const pool = createPool({ + connectionString: process.env['VERCEL_CONNECTION_STRING'], + }); + const client = await pool.connect(); + + const db = drizzle(client); + + await db.$client.query('SELECT 1;'); + client.release(); + + expect(db.$client).not.toBeTypeOf('function'); + expect(db.$client).not.toBeInstanceOf(Pool); + expect(db.$client).toBeInstanceOf(Client); + }); + + it('drizzle(client, config)', async () => { + const pool = createPool({ + connectionString: process.env['VERCEL_CONNECTION_STRING'], + }); + const client = await pool.connect(); + + const db = drizzle(client, { + schema, + }); + + await db.$client.query('SELECT 1;'); + client.release(); + + expect(db.$client).not.toBeTypeOf('function'); + expect(db.$client).not.toBeInstanceOf(Pool); + expect(db.$client).toBeInstanceOf(Client); + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({client, ...config})', async () => { + const pool = createPool({ + connectionString: process.env['VERCEL_CONNECTION_STRING'], + }); + const client = await pool.connect(); + + const db = drizzle({ + client: client, + schema, + }); + + await db.$client.query('SELECT 1;'); + client.release(); + + expect(db.$client).not.toBeTypeOf('function'); + expect(db.$client).not.toBeInstanceOf(Pool); + expect(db.$client).toBeInstanceOf(Client); + expect(db.query.User).not.toStrictEqual(undefined); + }); +}); diff --git a/integration-tests/js-tests/driver-init/module/better-sqlite3.test.mjs b/integration-tests/js-tests/driver-init/module/better-sqlite3.test.mjs new file mode 100644 index 000000000..063eb958f --- /dev/null +++ b/integration-tests/js-tests/driver-init/module/better-sqlite3.test.mjs @@ -0,0 +1,124 @@ +import 'dotenv/config'; +import Database from 'better-sqlite3'; +import { drizzle } from 'drizzle-orm/better-sqlite3'; +import { describe, expect } from 'vitest'; +import { sqlite as schema } from './schema.mjs'; + +describe('better-sqlite3', async (it) => { + it('drizzle()', async () => { + const db = drizzle(); + + await db.$client.exec('SELECT 1;'); + + await db.$client.close(); + }); + + it('drizzle(string)', async () => { + const db = drizzle(':memory:'); + + await db.$client.exec('SELECT 1;'); + + await db.$client.close(); + }); + + it('drizzle(string, config)', async () => { + const db = drizzle(':memory:', { + schema, + }); + + await db.$client.exec('SELECT 1;'); + + await db.$client.close(); + + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({connection: string, ...config})', async () => { + const db = drizzle({ + connection: ':memory:', + schema, + }); + + await db.$client.exec('SELECT 1;'); + + await db.$client.close(); + + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({connection: params, ...config})', async () => { + const db = drizzle({ + connection: { + source: ':memory:', + }, + schema, + }); + + await db.$client.exec('SELECT 1;'); + + await db.$client.close(); + + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({connection: {}, ...config})', async () => { + const db = drizzle({ + connection: {}, + schema, + }); + + await db.$client.exec('SELECT 1;'); + + await db.$client.close(); + + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({...config})', async () => { + const db = drizzle({ + schema, + }); + + await db.$client.exec('SELECT 1;'); + + await db.$client.close(); + + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle(client)', async () => { + const client = new Database(':memory:'); + const db = drizzle(client); + + await db.$client.exec('SELECT 1;'); + + await db.$client.close(); + }); + + it('drizzle(client, config)', async () => { + const client = new Database(':memory:'); + const db = drizzle(client, { + schema, + }); + + await db.$client.exec('SELECT 1;'); + + await db.$client.close(); + + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({client, ...config})', async () => { + const client = new Database(':memory:'); + const db = drizzle({ + client, + schema, + }); + + await db.$client.exec('SELECT 1;'); + + await db.$client.close(); + + expect(db.query.User).not.toStrictEqual(undefined); + }); +}); diff --git a/integration-tests/js-tests/driver-init/module/libsql.test.mjs b/integration-tests/js-tests/driver-init/module/libsql.test.mjs new file mode 100644 index 000000000..816d0eb0e --- /dev/null +++ b/integration-tests/js-tests/driver-init/module/libsql.test.mjs @@ -0,0 +1,97 @@ +import 'dotenv/config'; +import { createClient } from '@libsql/client'; +import { drizzle } from 'drizzle-orm/libsql'; +import { describe, expect } from 'vitest'; +import { sqlite as schema } from './schema.mjs'; + +describe('libsql', async (it) => { + it('drizzle(string)', async () => { + const db = drizzle(':memory:'); + + await db.$client.execute('SELECT 1;'); + + await db.$client.close(); + }); + + it('drizzle(string, config)', async () => { + const db = drizzle(':memory:', { + schema, + }); + + await db.$client.execute('SELECT 1;'); + + await db.$client.close(); + + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({connection: string, ...config})', async () => { + const db = drizzle({ + connection: ':memory:', + schema, + }); + + await db.$client.execute('SELECT 1;'); + + await db.$client.close(); + + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({connection: params, ...config})', async () => { + const db = drizzle({ + connection: { + url: ':memory:', + }, + schema, + }); + + await db.$client.execute('SELECT 1;'); + + await db.$client.close(); + + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle(client)', async () => { + const client = createClient({ + url: ':memory:', + }); + const db = drizzle(client); + + await db.$client.execute('SELECT 1;'); + + await db.$client.close(); + }); + + it('drizzle(client, config)', async () => { + const client = createClient({ + url: ':memory:', + }); + const db = drizzle(client, { + schema, + }); + + await db.$client.execute('SELECT 1;'); + + await db.$client.close(); + + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({client, ...config})', async () => { + const client = createClient({ + url: ':memory:', + }); + const db = drizzle({ + client, + schema, + }); + + await db.$client.execute('SELECT 1;'); + + await db.$client.close(); + + expect(db.query.User).not.toStrictEqual(undefined); + }); +}); diff --git a/integration-tests/js-tests/driver-init/module/mysql2.test.mjs b/integration-tests/js-tests/driver-init/module/mysql2.test.mjs new file mode 100644 index 000000000..1a1565c67 --- /dev/null +++ b/integration-tests/js-tests/driver-init/module/mysql2.test.mjs @@ -0,0 +1,153 @@ +import 'dotenv/config'; +import { drizzle } from 'drizzle-orm/mysql2'; +import { Connection, createConnection, createPool } from 'mysql2'; +import { describe, expect } from 'vitest'; +import { mysql as schema } from './schema.mjs'; + +if (!process.env['MYSQL_CONNECTION_STRING']) { + throw new Error('MYSQL_CONNECTION_STRING is not defined'); +} + +describe('mysql2', async (it) => { + it('drizzle(string)', async () => { + const db = drizzle( + process.env['MYSQL_CONNECTION_STRING'], + ); + + await db.$client.execute(`SELECT 1`); + + expect(db.$client.getConnection).not.toStrictEqual(undefined); + }); + + it('drizzle(string, config)', async () => { + const db = drizzle( + process.env['MYSQL_CONNECTION_STRING'], + { + schema, + mode: 'default', + }, + ); + await db.$client.execute('SELECT 1;'); + + expect(db.query.User).not.toStrictEqual(undefined); + expect(db.$client.getConnection).not.toStrictEqual(undefined); + }); + + it('drizzle({connection: string, ...config})', async () => { + const db = drizzle({ + connection: process.env['MYSQL_CONNECTION_STRING'], + schema, + mode: 'default', + }); + + await db.$client.execute('SELECT 1;'); + + expect(db.query.User).not.toStrictEqual(undefined); + expect(db.$client.getConnection).not.toStrictEqual(undefined); + }); + + it('drizzle({connection: params, ...config})', async () => { + const db = drizzle({ + connection: { + uri: process.env['MYSQL_CONNECTION_STRING'], + }, + schema, + mode: 'default', + }); + + await db.$client.execute('SELECT 1;'); + + expect(db.query.User).not.toStrictEqual(undefined); + expect(db.$client.getConnection).not.toStrictEqual(undefined); + }); + + it('drizzle(client)', async () => { + const client = createPool({ + uri: process.env['MYSQL_CONNECTION_STRING'], + }); + + const db = drizzle(client); + + await db.$client.execute('SELECT 1;'); + + expect(db.$client.getConnection).not.toStrictEqual(undefined); + }); + + it('drizzle(client, config)', async () => { + const client = createPool({ + uri: process.env['MYSQL_CONNECTION_STRING'], + }); + const db = drizzle(client, { + schema, + mode: 'default', + }); + + await db.$client.execute('SELECT 1;'); + + expect(db.query.User).not.toStrictEqual(undefined); + expect(db.$client.getConnection).not.toStrictEqual(undefined); + }); + + it('drizzle({client, ...config})', async () => { + const client = createPool({ + uri: process.env['MYSQL_CONNECTION_STRING'], + }); + + const db = drizzle({ + client, + schema, + mode: 'default', + }); + + await db.$client.execute('SELECT 1;'); + + expect(db.query.User).not.toStrictEqual(undefined); + expect(db.$client.getConnection).not.toStrictEqual(undefined); + }); +}); + +describe('mysql2:connection', async (it) => { + it('drizzle(client)', async () => { + const client = createConnection({ + uri: process.env['MYSQL_CONNECTION_STRING'], + }); + + const db = drizzle(client); + + await db.$client.execute('SELECT 1;'); + + expect(db.$client.getConnection).toStrictEqual(undefined); + }); + + it('drizzle(client, config)', async () => { + const client = createConnection({ + uri: process.env['MYSQL_CONNECTION_STRING'], + }); + const db = drizzle(client, { + schema, + mode: 'default', + }); + + await db.$client.execute('SELECT 1;'); + + expect(db.query.User).not.toStrictEqual(undefined); + expect(db.$client.getConnection).toStrictEqual(undefined); + }); + + it('drizzle({client, ...config})', async () => { + const client = createConnection({ + uri: process.env['MYSQL_CONNECTION_STRING'], + }); + + const db = drizzle({ + client, + schema, + mode: 'default', + }); + + await db.$client.execute('SELECT 1;'); + + expect(db.query.User).not.toStrictEqual(undefined); + expect(db.$client.getConnection).toStrictEqual(undefined); + }); +}); diff --git a/integration-tests/js-tests/driver-init/module/neon-http.test.mjs b/integration-tests/js-tests/driver-init/module/neon-http.test.mjs new file mode 100644 index 000000000..b9c07f4d9 --- /dev/null +++ b/integration-tests/js-tests/driver-init/module/neon-http.test.mjs @@ -0,0 +1,92 @@ +import 'dotenv/config'; +import { neon as pg } from '@neondatabase/serverless'; +import { drizzle } from 'drizzle-orm/neon-http'; +import { describe, expect } from 'vitest'; +import { pg as schema } from './schema.mjs'; + +if (!process.env['NEON_CONNECTION_STRING']) { + throw new Error('NEON_CONNECTION_STRING is not defined'); +} + +describe('neon-http', async (it) => { + it('drizzle(string)', async () => { + const db = drizzle( + process.env['NEON_CONNECTION_STRING'], + ); + + await db.$client('SELECT 1;'); + }); + + it('drizzle(string, config)', async () => { + const db = drizzle( + process.env['NEON_CONNECTION_STRING'], + { + schema, + }, + ); + + await db.$client('SELECT 1;'); + + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({connection: string, ...config})', async () => { + const db = drizzle({ + connection: process.env['NEON_CONNECTION_STRING'], + schema, + }); + + await db.$client('SELECT 1;'); + + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({connection: params, ...config})', async () => { + const db = drizzle({ + connection: { + connectionString: process.env['NEON_CONNECTION_STRING'], + }, + schema, + }); + + await db.$client('SELECT 1;'); + + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle(client)', async () => { + const client = pg( + process.env['NEON_CONNECTION_STRING'], + ); + const db = drizzle(client); + + await db.$client('SELECT 1;'); + }); + + it('drizzle(client, config)', async () => { + const client = pg( + process.env['NEON_CONNECTION_STRING'], + ); + const db = drizzle(client, { + schema, + }); + + await db.$client('SELECT 1;'); + + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({client, ...config})', async () => { + const client = pg( + process.env['NEON_CONNECTION_STRING'], + ); + const db = drizzle({ + client, + schema, + }); + + await db.$client('SELECT 1;'); + + expect(db.query.User).not.toStrictEqual(undefined); + }); +}); diff --git a/integration-tests/js-tests/driver-init/module/neon-ws.test.mjs b/integration-tests/js-tests/driver-init/module/neon-ws.test.mjs new file mode 100644 index 000000000..5a045b76a --- /dev/null +++ b/integration-tests/js-tests/driver-init/module/neon-ws.test.mjs @@ -0,0 +1,211 @@ +import 'dotenv/config'; +import { Client, neonConfig, Pool } from '@neondatabase/serverless'; +import { drizzle } from 'drizzle-orm/neon-serverless'; +import { describe, expect } from 'vitest'; +import ws from 'ws'; +import { pg as schema } from './schema.mjs'; + +neonConfig.webSocketConstructor = ws; + +if (!process.env['NEON_CONNECTION_STRING']) { + throw new Error('NEON_CONNECTION_STRING is not defined'); +} + +describe('neon-ws', async (it) => { + it('drizzle(string)', async () => { + const db = drizzle( + process.env['NEON_CONNECTION_STRING'], + ); + + await db.$client.query('SELECT 1;'); + }); + + it('drizzle(string, config)', async () => { + const db = drizzle( + process.env['NEON_CONNECTION_STRING'], + { + schema, + }, + ); + + await db.$client.query('SELECT 1;'); + + expect(db.query.User).not.toStrictEqual(undefined); + expect(db.$client).toBeInstanceOf(Pool); + }); + + it('drizzle({connection: string, ...config})', async () => { + const db = drizzle({ + connection: process.env['NEON_CONNECTION_STRING'], + schema, + }); + + await db.$client.query('SELECT 1;'); + + expect(db.query.User).not.toStrictEqual(undefined); + expect(db.$client).toBeInstanceOf(Pool); + }); + + it('drizzle({connection: params, ...config})', async () => { + const db = drizzle({ + connection: { + connectionString: process.env['NEON_CONNECTION_STRING'], + }, + schema, + }); + + await db.$client.query('SELECT 1;'); + + expect(db.query.User).not.toStrictEqual(undefined); + expect(db.$client).toBeInstanceOf(Pool); + }); + + it('drizzle(client)', async () => { + const client = new Pool({ + connectionString: process.env['NEON_CONNECTION_STRING'], + }); + const db = drizzle(client); + + await db.$client.query('SELECT 1;'); + + expect(db.$client).toBeInstanceOf(Pool); + }); + + it('drizzle(client, config)', async () => { + const client = new Pool({ + connectionString: process.env['NEON_CONNECTION_STRING'], + }); + const db = drizzle(client, { + schema, + }); + + await db.$client.query('SELECT 1;'); + + expect(db.query.User).not.toStrictEqual(undefined); + expect(db.$client).toBeInstanceOf(Pool); + }); + + it('drizzle({client, ...config})', async () => { + const client = new Pool({ + connectionString: process.env['NEON_CONNECTION_STRING'], + }); + const db = drizzle({ + client, + schema, + }); + + await db.$client.query('SELECT 1;'); + + expect(db.query.User).not.toStrictEqual(undefined); + expect(db.$client).toBeInstanceOf(Pool); + }); +}); + +describe('neon-ws:Client', async (it) => { + it('drizzle(client)', async () => { + const client = new Client({ + connectionString: process.env['NEON_CONNECTION_STRING'], + }); + + await client.connect(); + + const db = drizzle(client); + + await db.$client.query('SELECT 1;'); + + expect(db.$client).toBeInstanceOf(Client); + expect(db.$client).not.toBeInstanceOf(Pool); + }); + + it('drizzle(client, config)', async () => { + const client = new Client({ + connectionString: process.env['NEON_CONNECTION_STRING'], + }); + const db = drizzle(client, { + schema, + }); + + await client.connect(); + + await db.$client.query('SELECT 1;'); + + expect(db.query.User).not.toStrictEqual(undefined); + expect(db.$client).toBeInstanceOf(Client); + expect(db.$client).not.toBeInstanceOf(Pool); + }); + + it('drizzle({client, ...config})', async () => { + const client = new Client({ + connectionString: process.env['NEON_CONNECTION_STRING'], + }); + const db = drizzle({ + client, + schema, + }); + + await client.connect(); + + await db.$client.query('SELECT 1;'); + + expect(db.query.User).not.toStrictEqual(undefined); + expect(db.$client).toBeInstanceOf(Client); + expect(db.$client).not.toBeInstanceOf(Pool); + }); +}); + +describe('neon-ws:PoolClient', async (it) => { + it('drizzle(client)', async () => { + const pool = new Pool({ + connectionString: process.env['NEON_CONNECTION_STRING'], + }); + const client = await pool.connect(); + + const db = drizzle(client); + + await db.$client.query('SELECT 1;'); + + client.release(); + + expect(db.$client).toBeInstanceOf(Client); + expect(db.$client).not.toBeInstanceOf(Pool); + }); + + it('drizzle(client, config)', async () => { + const pool = new Pool({ + connectionString: process.env['NEON_CONNECTION_STRING'], + }); + const client = await pool.connect(); + + const db = drizzle(client, { + schema, + }); + + await db.$client.query('SELECT 1;'); + + client.release(); + + expect(db.query.User).not.toStrictEqual(undefined); + expect(db.$client).toBeInstanceOf(Client); + expect(db.$client).not.toBeInstanceOf(Pool); + }); + + it('drizzle({client, ...config})', async () => { + const pool = new Pool({ + connectionString: process.env['NEON_CONNECTION_STRING'], + }); + const client = await pool.connect(); + + const db = drizzle({ + client, + schema, + }); + + await db.$client.query('SELECT 1;'); + + client.release(); + + expect(db.query.User).not.toStrictEqual(undefined); + expect(db.$client).toBeInstanceOf(Client); + expect(db.$client).not.toBeInstanceOf(Pool); + }); +}); diff --git a/integration-tests/js-tests/driver-init/module/node-pg.test.mjs b/integration-tests/js-tests/driver-init/module/node-pg.test.mjs new file mode 100644 index 000000000..75dd391f1 --- /dev/null +++ b/integration-tests/js-tests/driver-init/module/node-pg.test.mjs @@ -0,0 +1,201 @@ +import 'dotenv/config'; +import { drizzle } from 'drizzle-orm/node-postgres'; +import pg from 'pg'; +import { describe, expect } from 'vitest'; +import { pg as schema } from './schema.mjs'; + +const Pool = pg.Pool; +const Client = pg.Client; + +if (!process.env['PG_CONNECTION_STRING']) { + throw new Error('PG_CONNECTION_STRING is not defined'); +} + +describe('node-pg', async (it) => { + it('drizzle(string)', async () => { + const db = drizzle(process.env['PG_CONNECTION_STRING']); + + await db.$client.query('SELECT 1;'); + + expect(db.$client).toBeInstanceOf(Pool); + }); + + it('drizzle(string, config)', async () => { + const db = drizzle(process.env['PG_CONNECTION_STRING'], { + schema, + }); + + await db.$client.query('SELECT 1;'); + + expect(db.$client).toBeInstanceOf(Pool); + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({connection: string, ...config})', async () => { + const db = drizzle({ + connection: process.env['PG_CONNECTION_STRING'], + schema, + }); + + await db.$client.query('SELECT 1;'); + + expect(db.$client).toBeInstanceOf(Pool); + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({connection: params, ...config})', async () => { + const db = drizzle({ + connection: { + connectionString: process.env['PG_CONNECTION_STRING'], + }, + schema, + }); + + await db.$client.query('SELECT 1;'); + + expect(db.$client).toBeInstanceOf(Pool); + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle(client)', async () => { + const client = new Pool({ + connectionString: process.env['PG_CONNECTION_STRING'], + }); + const db = drizzle(client); + + await db.$client.query('SELECT 1;'); + + expect(db.$client).toBeInstanceOf(Pool); + }); + + it('drizzle(client, config)', async () => { + const client = new Pool({ + connectionString: process.env['PG_CONNECTION_STRING'], + }); + const db = drizzle(client, { + schema, + }); + + await db.$client.query('SELECT 1;'); + + expect(db.$client).toBeInstanceOf(Pool); + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({client, ...config})', async () => { + const client = new Pool({ + connectionString: process.env['PG_CONNECTION_STRING'], + }); + const db = drizzle({ + client, + schema, + }); + + await db.$client.query('SELECT 1;'); + + expect(db.$client).toBeInstanceOf(Pool); + expect(db.query.User).not.toStrictEqual(undefined); + }); +}); + +describe('node-pg:Client', async (it) => { + it('drizzle(client)', async () => { + const client = new Client({ + connectionString: process.env['PG_CONNECTION_STRING'], + }); + const db = drizzle(client); + + await client.connect(); + + await db.$client.query('SELECT 1;'); + + expect(db.$client).not.toBeInstanceOf(Pool); + expect(db.$client).toBeInstanceOf(Client); + }); + + it('drizzle(client, config)', async () => { + const client = new Client({ + connectionString: process.env['PG_CONNECTION_STRING'], + }); + const db = drizzle(client, { + schema, + }); + + await client.connect(); + + await db.$client.query('SELECT 1;'); + + expect(db.$client).not.toBeInstanceOf(Pool); + expect(db.$client).toBeInstanceOf(Client); + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({client, ...config})', async () => { + const client = new Client({ + connectionString: process.env['PG_CONNECTION_STRING'], + }); + const db = drizzle({ + client, + schema, + }); + + await client.connect(); + + await db.$client.query('SELECT 1;'); + + expect(db.$client).not.toBeInstanceOf(Pool); + expect(db.$client).toBeInstanceOf(Client); + expect(db.query.User).not.toStrictEqual(undefined); + }); +}); + +describe('node-pg:PoolClient', async (it) => { + it('drizzle(client)', async () => { + const pool = new Pool({ + connectionString: process.env['PG_CONNECTION_STRING'], + }); + const client = await pool.connect(); + const db = drizzle(client); + + await db.$client.query('SELECT 1;'); + client.release(); + + expect(db.$client).not.toBeInstanceOf(Pool); + expect(db.$client).toBeInstanceOf(Client); + }); + + it('drizzle(client, config)', async () => { + const pool = new Pool({ + connectionString: process.env['PG_CONNECTION_STRING'], + }); + const client = await pool.connect(); + const db = drizzle(client, { + schema, + }); + + await db.$client.query('SELECT 1;'); + client.release(); + + expect(db.$client).not.toBeInstanceOf(Pool); + expect(db.$client).toBeInstanceOf(Client); + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({client, ...config})', async () => { + const pool = new Pool({ + connectionString: process.env['PG_CONNECTION_STRING'], + }); + const client = await pool.connect(); + const db = drizzle({ + client, + schema, + }); + + await db.$client.query('SELECT 1;'); + client.release(); + + expect(db.$client).not.toBeInstanceOf(Pool); + expect(db.$client).toBeInstanceOf(Client); + expect(db.query.User).not.toStrictEqual(undefined); + }); +}); diff --git a/integration-tests/js-tests/driver-init/module/pglite.test.mjs b/integration-tests/js-tests/driver-init/module/pglite.test.mjs new file mode 100644 index 000000000..bb67f383b --- /dev/null +++ b/integration-tests/js-tests/driver-init/module/pglite.test.mjs @@ -0,0 +1,88 @@ +import 'dotenv/config'; +import { PGlite as Database } from '@electric-sql/pglite'; +import { drizzle } from 'drizzle-orm/pglite'; +import { describe, expect } from 'vitest'; +import { pg as schema } from './schema.mjs'; + +describe('pglite', async (it) => { + it('drizzle()', async () => { + const db = drizzle(); + + await db.$client.exec('SELECT 1;'); + await db.$client.close(); + }); + + it('drizzle(string)', async () => { + const db = drizzle('memory://'); + + await db.$client.exec('SELECT 1;'); + await db.$client.close(); + }); + + it('drizzle(string, config)', async () => { + const db = drizzle('memory://', { + schema, + }); + + await db.$client.exec('SELECT 1;'); + await db.$client.close(); + + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({connection: {}, ...config})', async () => { + const db = drizzle({ + connection: {}, + schema, + }); + + await db.$client.exec('SELECT 1;'); + await db.$client.close(); + + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({...config})', async () => { + const db = drizzle({ + schema, + }); + + await db.$client.exec('SELECT 1;'); + await db.$client.close(); + + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle(client)', async () => { + const client = new Database('memory://'); + const db = drizzle(client); + + await db.$client.exec('SELECT 1;'); + await db.$client.close(); + }); + + it('drizzle(client, config)', async () => { + const client = new Database('memory://'); + const db = drizzle(client, { + schema, + }); + + await db.$client.exec('SELECT 1;'); + await db.$client.close(); + + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({client, ...config})', async () => { + const client = new Database('memory://'); + const db = drizzle({ + client, + schema, + }); + + await db.$client.exec('SELECT 1;'); + await db.$client.close(); + + expect(db.query.User).not.toStrictEqual(undefined); + }); +}); diff --git a/integration-tests/js-tests/driver-init/module/planetscale.test.mjs b/integration-tests/js-tests/driver-init/module/planetscale.test.mjs new file mode 100644 index 000000000..c56537b06 --- /dev/null +++ b/integration-tests/js-tests/driver-init/module/planetscale.test.mjs @@ -0,0 +1,146 @@ +import 'dotenv/config'; +import { Client, Connection } from '@planetscale/database'; +import { drizzle } from 'drizzle-orm/planetscale-serverless'; +import { describe, expect } from 'vitest'; +import { mysql as schema } from './schema.mjs'; + +if (!process.env['PLANETSCALE_CONNECTION_STRING']) { + throw new Error('PLANETSCALE_CONNECTION_STRING is not defined'); +} + +describe('planetscale', async (it) => { + it('drizzle(string)', async () => { + const db = drizzle( + process.env['PLANETSCALE_CONNECTION_STRING'], + ); + + await db.$client.execute('SELECT 1;'); + + expect(db.$client).toBeInstanceOf(Client); + }); + + it('drizzle(string, config)', async () => { + const db = drizzle( + process.env['PLANETSCALE_CONNECTION_STRING'], + { + schema, + }, + ); + + await db.$client.execute('SELECT 1;'); + + expect(db.$client).toBeInstanceOf(Client); + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({connection: string, ...config})', async () => { + const db = drizzle({ + connection: process.env['PLANETSCALE_CONNECTION_STRING'], + schema, + }); + + await db.$client.execute('SELECT 1;'); + + expect(db.$client).toBeInstanceOf(Client); + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({connection: params, ...config})', async () => { + const db = drizzle({ + connection: { + url: process.env['PLANETSCALE_CONNECTION_STRING'], + }, + schema, + }); + + await db.$client.execute('SELECT 1;'); + + expect(db.$client).toBeInstanceOf(Client); + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle(client)', async () => { + const client = new Client({ + url: process.env['PLANETSCALE_CONNECTION_STRING'], + }); + const db = drizzle(client); + + await db.$client.execute('SELECT 1;'); + + expect(db.$client).toBeInstanceOf(Client); + }); + + it('drizzle(client, config)', async () => { + const client = new Client({ + url: process.env['PLANETSCALE_CONNECTION_STRING'], + }); + const db = drizzle(client, { + schema, + }); + + await db.$client.execute('SELECT 1;'); + + expect(db.$client).toBeInstanceOf(Client); + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({client, ...config})', async () => { + const client = new Client({ + url: process.env['PLANETSCALE_CONNECTION_STRING'], + }); + const db = drizzle({ + client, + schema, + }); + + await db.$client.execute('SELECT 1;'); + + expect(db.$client).toBeInstanceOf(Client); + expect(db.query.User).not.toStrictEqual(undefined); + }); +}); + +describe('planetscale:Connection', async (it) => { + it('drizzle(client)', async () => { + const client = new Connection({ + url: process.env['PLANETSCALE_CONNECTION_STRING'], + }); + const db = drizzle(client); + + await db.$client.execute('SELECT 1;'); + + expect(db.$client).not.toBeInstanceOf(Client); + expect(db.$client).toBeInstanceOf(Connection); + }); + + it('drizzle(client, config)', async () => { + const client = new Connection({ + url: process.env['PLANETSCALE_CONNECTION_STRING'], + }); + const db = drizzle(client, { + schema, + }); + + await db.$client.execute('SELECT 1;'); + + expect(db.$client).not.toBeInstanceOf(Client); + expect(db.$client).toBeInstanceOf(Connection); + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({client, ...config})', async () => { + const client = new Connection({ + url: process.env['PLANETSCALE_CONNECTION_STRING'], + }); + const db = drizzle({ + client, + schema, + }); + + await db.$client.execute('SELECT 1;'); + + expect(db.$client).not.toBeInstanceOf(Client); + expect(db.$client).toBeInstanceOf(Connection); + expect(db.query.User).not.toStrictEqual(undefined); + }); +}); diff --git a/integration-tests/js-tests/driver-init/module/postgres-js.test.mjs b/integration-tests/js-tests/driver-init/module/postgres-js.test.mjs new file mode 100644 index 000000000..40925aceb --- /dev/null +++ b/integration-tests/js-tests/driver-init/module/postgres-js.test.mjs @@ -0,0 +1,81 @@ +import 'dotenv/config'; +import { drizzle } from 'drizzle-orm/postgres-js'; +import pg from 'postgres'; +import { describe, expect } from 'vitest'; +import { pg as schema } from './schema.mjs'; + +if (!process.env['PG_CONNECTION_STRING']) { + throw new Error('PG_CONNECTION_STRING is not defined'); +} + +describe('postgres-js', async (it) => { + it('drizzle(string)', async () => { + const db = drizzle(process.env['PG_CONNECTION_STRING']); + + await db.$client.unsafe('SELECT 1;'); + }); + + it('drizzle(string, config)', async () => { + const db = drizzle(process.env['PG_CONNECTION_STRING'], { + schema, + }); + + await db.$client.unsafe('SELECT 1;'); + + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({connection: string, ...config})', async () => { + const db = drizzle({ + connection: process.env['PG_CONNECTION_STRING'], + schema, + }); + + await db.$client.unsafe('SELECT 1;'); + + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({connection: params, ...config})', async () => { + const db = drizzle({ + connection: { + url: process.env['PG_CONNECTION_STRING'], + }, + schema, + }); + + await db.$client.unsafe('SELECT 1;'); + + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle(client)', async () => { + const client = pg(process.env['PG_CONNECTION_STRING']); + const db = drizzle(client); + + await db.$client.unsafe('SELECT 1;'); + }); + + it('drizzle(client, config)', async () => { + const client = pg(process.env['PG_CONNECTION_STRING']); + const db = drizzle(client, { + schema, + }); + + await db.$client.unsafe('SELECT 1;'); + + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({client, ...config})', async () => { + const client = pg(process.env['PG_CONNECTION_STRING']); + const db = drizzle({ + client, + schema, + }); + + await db.$client.unsafe('SELECT 1;'); + + expect(db.query.User).not.toStrictEqual(undefined); + }); +}); diff --git a/integration-tests/js-tests/driver-init/module/schema.mjs b/integration-tests/js-tests/driver-init/module/schema.mjs new file mode 100644 index 000000000..9c0d4d689 --- /dev/null +++ b/integration-tests/js-tests/driver-init/module/schema.mjs @@ -0,0 +1,21 @@ +import { int as mysqlInt, mysqlTable } from 'drizzle-orm/mysql-core'; +import { integer as pgInt, pgTable } from 'drizzle-orm/pg-core'; +import { integer as sqliteInt, sqliteTable } from 'drizzle-orm/sqlite-core'; + +export const sqlite = { + User: sqliteTable('test', { + id: sqliteInt('id').primaryKey().notNull(), + }), +}; + +export const pg = { + User: pgTable('test', { + id: pgInt('id').primaryKey().notNull(), + }), +}; + +export const mysql = { + User: mysqlTable('test', { + id: mysqlInt('id').primaryKey().notNull(), + }), +}; diff --git a/integration-tests/js-tests/driver-init/module/tidb.test.mjs b/integration-tests/js-tests/driver-init/module/tidb.test.mjs new file mode 100644 index 000000000..0cd62f00a --- /dev/null +++ b/integration-tests/js-tests/driver-init/module/tidb.test.mjs @@ -0,0 +1,88 @@ +import 'dotenv/config'; +import { connect } from '@tidbcloud/serverless'; +import { drizzle } from 'drizzle-orm/tidb-serverless'; +import { describe, expect } from 'vitest'; +import { mysql as schema } from './schema.mjs'; + +if (!process.env['TIDB_CONNECTION_STRING']) { + throw new Error('TIDB_CONNECTION_STRING is not defined'); +} + +describe('tidb', async (it) => { + it('drizzle(string)', async () => { + const db = drizzle( + process.env['TIDB_CONNECTION_STRING'], + ); + + await db.$client.execute(`SELECT 1`); + }); + + it('drizzle(string, config)', async () => { + const db = drizzle( + process.env['TIDB_CONNECTION_STRING'], + { + schema, + }, + ); + + await db.$client.execute('SELECT 1;'); + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({connection: string, ...config})', async () => { + const db = drizzle({ + connection: process.env['TIDB_CONNECTION_STRING'], + schema, + }); + + await db.$client.execute('SELECT 1;'); + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({connection: params, ...config})', async () => { + const db = drizzle({ + connection: { + url: process.env['TIDB_CONNECTION_STRING'], + }, + schema, + }); + + await db.$client.execute('SELECT 1;'); + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle(client)', async () => { + const client = connect({ + url: process.env['TIDB_CONNECTION_STRING'], + }); + + const db = drizzle(client); + + await db.$client.execute('SELECT 1;'); + }); + + it('drizzle(client, config)', async () => { + const client = connect({ + url: process.env['TIDB_CONNECTION_STRING'], + }); + const db = drizzle(client, { + schema, + }); + + await db.$client.execute('SELECT 1;'); + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({client, ...config})', async () => { + const client = connect({ + url: process.env['TIDB_CONNECTION_STRING'], + }); + const db = drizzle({ + client, + schema, + }); + + await db.$client.execute('SELECT 1;'); + expect(db.query.User).not.toStrictEqual(undefined); + }); +}); diff --git a/integration-tests/js-tests/driver-init/module/vercel.test.mjs b/integration-tests/js-tests/driver-init/module/vercel.test.mjs new file mode 100644 index 000000000..0ef7c460e --- /dev/null +++ b/integration-tests/js-tests/driver-init/module/vercel.test.mjs @@ -0,0 +1,229 @@ +import 'dotenv/config'; +import { createClient, createPool, sql, VercelClient, VercelPool } from '@vercel/postgres'; +import { drizzle } from 'drizzle-orm/vercel-postgres'; +import { describe, expect } from 'vitest'; +import { pg as schema } from './schema.mjs'; + +const Pool = VercelPool; +const Client = VercelClient; + +if (!process.env['VERCEL_CONNECTION_STRING']) { + throw new Error('VERCEL_CONNECTION_STRING is not defined'); +} + +// Used for non-pooled connection +if (!process.env['NEON_CONNECTION_STRING']) { + throw new Error('NEON_CONNECTION_STRING is not defined'); +} + +process.env['POSTGRES_URL'] = process.env['VERCEL_CONNECTION_STRING']; + +describe('vercel:sql', async (it) => { + it('drizzle()', async () => { + const db = drizzle(); + + await sql.connect(); + + await db.$client.query('SELECT 1;'); + + expect(db.$client).toBeTypeOf('function'); + }); + + it('drizzle(client)', async () => { + const db = drizzle(sql); + + await db.$client.query('SELECT 1;'); + + expect(db.$client).toBeTypeOf('function'); + }); + + it('drizzle(client, config)', async () => { + const db = drizzle(sql, { + schema, + }); + + await db.$client.query('SELECT 1;'); + + expect(db.$client).toBeTypeOf('function'); + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({client, ...config})', async () => { + const db = drizzle({ + client: sql, + schema, + }); + + await db.$client.query('SELECT 1;'); + + expect(db.$client).toBeTypeOf('function'); + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({...config})', async () => { + const db = drizzle({ + schema, + }); + + await db.$client.query('SELECT 1;'); + + expect(db.$client).toBeTypeOf('function'); + expect(db.query.User).not.toStrictEqual(undefined); + }); +}); + +describe('vercel:Pool', async (it) => { + it('drizzle(client)', async () => { + const client = createPool({ + connectionString: process.env['VERCEL_CONNECTION_STRING'], + }); + const db = drizzle(client); + + await db.$client.query('SELECT 1;'); + + expect(db.$client).not.toBeTypeOf('function'); + expect(db.$client).toBeInstanceOf(Pool); + }); + + it('drizzle(client, config)', async () => { + const client = createPool({ + connectionString: process.env['VERCEL_CONNECTION_STRING'], + }); + const db = drizzle(client, { + schema, + }); + + await db.$client.query('SELECT 1;'); + + expect(db.$client).not.toBeTypeOf('function'); + expect(db.$client).toBeInstanceOf(Pool); + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({client, ...config})', async () => { + const client = createPool({ + connectionString: process.env['VERCEL_CONNECTION_STRING'], + }); + const db = drizzle({ + client: client, + schema, + }); + + await db.$client.query('SELECT 1;'); + + expect(db.$client).not.toBeTypeOf('function'); + expect(db.$client).toBeInstanceOf(Pool); + expect(db.query.User).not.toStrictEqual(undefined); + }); +}); + +describe('vercel:Client', async (it) => { + it('drizzle(client)', async () => { + const client = createClient({ + connectionString: process.env['NEON_CONNECTION_STRING'], + }); + const db = drizzle(client); + + await client.connect(); + + await db.$client.query('SELECT 1;'); + + expect(db.$client).not.toBeTypeOf('function'); + expect(db.$client).not.toBeInstanceOf(Pool); + expect(db.$client).toBeInstanceOf(Client); + }); + + it('drizzle(client, config)', async () => { + const client = createClient({ + connectionString: process.env['NEON_CONNECTION_STRING'], + }); + const db = drizzle(client, { + schema, + }); + + await client.connect(); + + await db.$client.query('SELECT 1;'); + + expect(db.$client).not.toBeTypeOf('function'); + expect(db.$client).not.toBeInstanceOf(Pool); + expect(db.$client).toBeInstanceOf(Client); + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({client, ...config})', async () => { + const client = createClient({ + connectionString: process.env['NEON_CONNECTION_STRING'], + }); + const db = drizzle({ + client: client, + schema, + }); + + await client.connect(); + + await db.$client.query('SELECT 1;'); + + expect(db.$client).not.toBeTypeOf('function'); + expect(db.$client).not.toBeInstanceOf(Pool); + expect(db.$client).toBeInstanceOf(Client); + expect(db.query.User).not.toStrictEqual(undefined); + }); +}); + +describe('vercel:PoolClient', async (it) => { + it('drizzle(client)', async () => { + const pool = createPool({ + connectionString: process.env['VERCEL_CONNECTION_STRING'], + }); + const client = await pool.connect(); + + const db = drizzle(client); + + await db.$client.query('SELECT 1;'); + client.release(); + + expect(db.$client).not.toBeTypeOf('function'); + expect(db.$client).not.toBeInstanceOf(Pool); + expect(db.$client).toBeInstanceOf(Client); + }); + + it('drizzle(client, config)', async () => { + const pool = createPool({ + connectionString: process.env['VERCEL_CONNECTION_STRING'], + }); + const client = await pool.connect(); + + const db = drizzle(client, { + schema, + }); + + await db.$client.query('SELECT 1;'); + client.release(); + + expect(db.$client).not.toBeTypeOf('function'); + expect(db.$client).not.toBeInstanceOf(Pool); + expect(db.$client).toBeInstanceOf(Client); + expect(db.query.User).not.toStrictEqual(undefined); + }); + + it('drizzle({client, ...config})', async () => { + const pool = createPool({ + connectionString: process.env['VERCEL_CONNECTION_STRING'], + }); + const client = await pool.connect(); + + const db = drizzle({ + client: client, + schema, + }); + + await db.$client.query('SELECT 1;'); + client.release(); + + expect(db.$client).not.toBeTypeOf('function'); + expect(db.$client).not.toBeInstanceOf(Pool); + expect(db.$client).toBeInstanceOf(Client); + expect(db.query.User).not.toStrictEqual(undefined); + }); +}); diff --git a/integration-tests/package.json b/integration-tests/package.json index 2b26ec374..775103111 100644 --- a/integration-tests/package.json +++ b/integration-tests/package.json @@ -43,7 +43,7 @@ "dependencies": { "@aws-sdk/client-rds-data": "^3.549.0", "@aws-sdk/credential-providers": "^3.549.0", - "@electric-sql/pglite": "^0.1.1", + "@electric-sql/pglite": "^0.2.12", "@miniflare/d1": "^2.14.4", "@miniflare/shared": "^2.14.4", "@planetscale/database": "^1.16.0", diff --git a/integration-tests/tests/utils/is-config.test.ts b/integration-tests/tests/utils/is-config.test.ts new file mode 100644 index 000000000..5e55aaa08 --- /dev/null +++ b/integration-tests/tests/utils/is-config.test.ts @@ -0,0 +1,298 @@ +import 'dotenv/config'; +import { PGlite as pglite } from '@electric-sql/pglite'; +import { createClient as libsql } from '@libsql/client'; +import { Client as neonClient, neon, neonConfig, Pool as neonPool } from '@neondatabase/serverless'; +import { connect as planetscale } from '@planetscale/database'; +import { connect as tidb } from '@tidbcloud/serverless'; +import { createClient as vcClient, createPool as vcPool, sql as vcSql } from '@vercel/postgres'; +import betterSqlite3 from 'better-sqlite3'; +import { type DrizzleConfig, isConfig } from 'drizzle-orm'; +import { createConnection as ms2Connection, createPool as ms2Pool } from 'mysql2'; +import { createConnection as ms2pConnection, createPool as ms2pPool } from 'mysql2/promise'; +import pg from 'pg'; +import postgres from 'postgres'; +import { describe, expect } from 'vitest'; +import ws from 'ws'; + +neonConfig.webSocketConstructor = ws; + +if ( + !process.env['PG_CONNECTION_STRING'] || !process.env['MYSQL_CONNECTION_STRING'] + || !process.env['PLANETSCALE_CONNECTION_STRING'] || !process.env['TIDB_CONNECTION_STRING'] + || !process.env['NEON_CONNECTION_STRING'] || !process.env['VERCEL_CONNECTION_STRING'] +) { + throw new Error('process.env is missing some connection strings!'); +} + +process.env['POSTGRES_URL'] = process.env['VERCEL_CONNECTION_STRING']; + +describe('Objects', (it) => { + it('Passes configs', () => { + expect(isConfig({} as DrizzleConfig)).toEqual(true); + + expect( + isConfig({ + casing: 'camelCase', + } as DrizzleConfig), + ).toEqual(true); + + expect( + isConfig({ + logger: true, + } as DrizzleConfig), + ).toEqual(true); + + expect( + isConfig({ + logger: { + logQuery: () => {}, + }, + } as DrizzleConfig), + ).toEqual(true); + + expect( + isConfig({ + schema: { + any: true, + }, + } as DrizzleConfig), + ).toEqual(true); + + expect( + isConfig({ + casing: 'camelCase', + logger: true, + schema: { + any: true, + }, + } as DrizzleConfig), + ).toEqual(true); + + expect( + isConfig({ + casing: 'camelCase', + trash: true, + } as DrizzleConfig), + ).toEqual(true); + }); + + it('Rejects non-configs', () => { + expect(isConfig('')).toEqual(false); + + expect(isConfig('data')).toEqual(false); + + expect(isConfig(true)).toEqual(false); + + expect(isConfig(false)).toEqual(false); + + expect(isConfig(null)).toEqual(false); + + expect(isConfig(undefined)).toEqual(false); + + expect(isConfig(5)).toEqual(false); + + expect(isConfig(BigInt(5))).toEqual(false); + + expect(isConfig(new Date())).toEqual(false); + + expect( + isConfig({ + trash: true, + } as DrizzleConfig), + ).toEqual(false); + }); +}); + +describe('Rejects drivers', (it) => { + it('libsql', () => { + const cl = libsql({ + url: ':memory:', + }); + + expect(isConfig(cl)).toEqual(false); + }); + + it('better-sqlite3', () => { + const cl = new betterSqlite3(':memory:'); + + expect(isConfig(cl)).toEqual(false); + }); + + it('pglite', () => { + const cl = new pglite('memory://'); + + expect(isConfig(cl)).toEqual(false); + }); + + it('node-postgres:Pool', () => { + const cl = new pg.Pool({ + connectionString: process.env['PG_CONNECTION_STRING'], + }); + + expect(isConfig(cl)).toEqual(false); + }); + + it('node-postgres:Client', async () => { + const cl = new pg.Client({ + connectionString: process.env['PG_CONNECTION_STRING'], + }); + + const res = isConfig(cl); + + await cl.end(); + + expect(res).toEqual(false); + }); + + it('node-postgres:PoolClient', async () => { + const cl = new pg.Pool({ + connectionString: process.env['PG_CONNECTION_STRING'], + }); + + const con = await cl.connect(); + + const res = isConfig(con); + + con.release(); + + expect(res).toEqual(false); + }); + + it('postgres-js', () => { + const cl = postgres(process.env['PG_CONNECTION_STRING']!); + + expect(isConfig(cl)).toEqual(false); + }); + + it('vercel:sql', () => { + expect(isConfig(vcSql)).toEqual(false); + }); + + it('vercel:Pool', () => { + const cl = vcPool({ + connectionString: process.env['VERCEL_CONNECTION_STRING'], + }); + + expect(isConfig(cl)).toEqual(false); + }); + + it('vercel:Client', async () => { + const cl = vcClient({ + connectionString: process.env['NEON_CONNECTION_STRING'], + }); + + const res = isConfig(cl); + + expect(res).toEqual(false); + }); + + it('vercel:PoolClient', async () => { + const cl = vcPool({ + connectionString: process.env['VERCEL_CONNECTION_STRING'], + }); + + const con = await cl.connect(); + + const res = isConfig(con); + + con.release(); + + expect(res).toEqual(false); + }); + + it('neon-serverless:Pool', async () => { + const cl = new neonPool({ + connectionString: process.env['NEON_CONNECTION_STRING']!, + }); + + expect(isConfig(cl)).toEqual(false); + }); + + it('neon-serverless:Client', async () => { + const cl = new neonClient({ + connectionString: process.env['NEON_CONNECTION_STRING']!, + }); + + const res = isConfig(cl); + + await cl.end(); + + expect(res).toEqual(false); + }); + + it('neon-serverless:PoolClient', async () => { + const cl = new neonPool({ + connectionString: process.env['NEON_CONNECTION_STRING']!, + }); + + const con = await cl.connect(); + + const res = isConfig(con); + + con.release(); + + expect(res).toEqual(false); + }); + + it('neon-http', async () => { + const cl = neon(process.env['NEON_CONNECTION_STRING']!); + + expect(isConfig(cl)).toEqual(false); + }); + + it('planetscale', async () => { + const cl = planetscale({ + url: process.env['PLANETSCALE_CONNECTION_STRING'], + }); + + expect(isConfig(cl)).toEqual(false); + }); + + it('mysql2:Pool', async () => { + const cl = ms2Pool({ + uri: process.env['MYSQL_CONNECTION_STRING'], + }); + + expect(isConfig(cl)).toEqual(false); + }); + + it('mysql2:Connection', async () => { + const cl = ms2Connection({ + uri: process.env['MYSQL_CONNECTION_STRING'], + }); + + expect(isConfig(cl)).toEqual(false); + }); + + it('mysql2/promise:Pool', async () => { + const cl = await ms2pPool({ + uri: process.env['MYSQL_CONNECTION_STRING'], + }); + + const res = isConfig(cl); + + await cl.end(); + + expect(res).toEqual(false); + }); + + it('mysql2/promise:Connection', async () => { + const cl = await ms2pConnection({ + uri: process.env['MYSQL_CONNECTION_STRING'], + }); + + const res = isConfig(cl); + + await cl.end(); + + expect(res).toEqual(false); + }); + + it('tidb', async () => { + const cl = tidb({ + url: process.env['TIDB_CONNECTION_STRING'], + }); + + expect(isConfig(cl)).toEqual(false); + }); +}); diff --git a/integration-tests/vitest.config.ts b/integration-tests/vitest.config.ts index 3952eca49..1b07615b5 100644 --- a/integration-tests/vitest.config.ts +++ b/integration-tests/vitest.config.ts @@ -15,6 +15,9 @@ export default defineConfig({ 'tests/extensions/vectors/**/*', 'tests/version.test.ts', 'tests/pg/node-postgres.test.ts', + 'tests/utils/is-config.test.ts', + 'js-tests/driver-init/commonjs/*.test.cjs', + 'js-tests/driver-init/module/*.test.mjs', ], exclude: [ ...(process.env.SKIP_EXTERNAL_DB_TESTS @@ -28,6 +31,17 @@ export default defineConfig({ 'tests/sqlite/libsql-batch.test.ts', 'tests/pg/neon-http.test.ts', 'tests/pg/neon-http-batch.test.ts', + 'tests/utils/is-config.test.ts', // Uses external DBs in some cases + 'tests/driver-init/commonjs/neon-http.test.cjs', + 'tests/driver-init/commonjs/neon-ws.test.cjs', + 'tests/driver-init/commonjs/planetscale.test.cjs', + 'tests/driver-init/commonjs/tidb.test.cjs', + 'tests/driver-init/commonjs/vercel.test.cjs', + 'tests/driver-init/module/neon-http.test.mjs', + 'tests/driver-init/module/neon-ws.test.mjs', + 'tests/driver-init/module/planetscale.test.mjs', + 'tests/driver-init/module/tidb.test.mjs', + 'tests/driver-init/module/vercel.test.mjs', ] : []), 'tests/pg/awsdatapi.test.ts', @@ -37,6 +51,9 @@ export default defineConfig({ // Have a strange "invalid SQL: ERROR: must be owner of schema public" error. Will need to check with xata team 'tests/pg/xata-http.test.ts', 'tests/pg/neon-http-batch.ts', + // todo: remove + 'tests/driver-init/module/vercel.test.mjs', + 'tests/driver-init/commonjs/vercel.test.cjs', ], typecheck: { tsconfig: 'tsconfig.json', diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d2400e16d..39e4d5c44 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -109,8 +109,8 @@ importers: specifier: ^4.20230518.0 version: 4.20240524.0 '@electric-sql/pglite': - specifier: ^0.1.5 - version: 0.1.5 + specifier: ^0.2.12 + version: 0.2.12 '@hono/node-server': specifier: ^1.9.0 version: 1.12.0 @@ -298,8 +298,8 @@ importers: specifier: ^4.20230904.0 version: 4.20240512.0 '@electric-sql/pglite': - specifier: ^0.1.1 - version: 0.1.5 + specifier: ^0.2.12 + version: 0.2.12 '@libsql/client': specifier: ^0.10.0 version: 0.10.0(bufferutil@4.0.8)(utf-8-validate@6.0.3) @@ -548,10 +548,10 @@ importers: version: 3.583.0 '@aws-sdk/credential-providers': specifier: ^3.549.0 - version: 3.569.0(@aws-sdk/client-sso-oidc@3.583.0(@aws-sdk/client-sts@3.583.0)) + version: 3.569.0(@aws-sdk/client-sso-oidc@3.583.0) '@electric-sql/pglite': - specifier: ^0.1.1 - version: 0.1.5 + specifier: ^0.2.12 + version: 0.2.12 '@miniflare/d1': specifier: ^2.14.4 version: 2.14.4 @@ -1993,8 +1993,8 @@ packages: '@drizzle-team/studio@0.0.5': resolution: {integrity: sha512-ps5qF0tMxWRVu+V5gvCRrQNqlY92aTnIKdq27gm9LZMSdaKYZt6AVvSK1dlUMzs6Rt0Jm80b+eWct6xShBKhIw==} - '@electric-sql/pglite@0.1.5': - resolution: {integrity: sha512-eymv4ONNvoPZQTvOQIi5dbpR+J5HzEv0qQH9o/y3gvNheJV/P/NFcrbsfJZYTsDKoq7DKrTiFNexsRkJKy8x9Q==} + '@electric-sql/pglite@0.2.12': + resolution: {integrity: sha512-J/X42ujcoFEbOkgRyoNqZB5qcqrnJRWVlwpH3fKYoJkTz49N91uAK/rDSSG/85WRas9nC9mdV4FnMTxnQWE/rw==} '@esbuild-kit/core-utils@3.1.0': resolution: {integrity: sha512-Uuk8RpCg/7fdHSceR1M6XbSZFSuMrxcePFuGgyvsBn+u339dk5OeL4jv2EojwTN2st/unJGsVm4qHWjWNmJ/tw==} @@ -10911,12 +10911,12 @@ snapshots: - '@aws-sdk/client-sso-oidc' - aws-crt - '@aws-sdk/credential-provider-ini@3.568.0(@aws-sdk/client-sso-oidc@3.583.0(@aws-sdk/client-sts@3.583.0))(@aws-sdk/client-sts@3.569.0(@aws-sdk/client-sso-oidc@3.569.0))': + '@aws-sdk/credential-provider-ini@3.568.0(@aws-sdk/client-sso-oidc@3.583.0)(@aws-sdk/client-sts@3.569.0(@aws-sdk/client-sso-oidc@3.569.0))': dependencies: '@aws-sdk/client-sts': 3.569.0(@aws-sdk/client-sso-oidc@3.569.0) '@aws-sdk/credential-provider-env': 3.568.0 '@aws-sdk/credential-provider-process': 3.568.0 - '@aws-sdk/credential-provider-sso': 3.568.0(@aws-sdk/client-sso-oidc@3.583.0(@aws-sdk/client-sts@3.583.0)) + '@aws-sdk/credential-provider-sso': 3.568.0(@aws-sdk/client-sso-oidc@3.583.0) '@aws-sdk/credential-provider-web-identity': 3.568.0(@aws-sdk/client-sts@3.569.0(@aws-sdk/client-sso-oidc@3.569.0)) '@aws-sdk/types': 3.567.0 '@smithy/credential-provider-imds': 2.3.0 @@ -10999,13 +10999,13 @@ snapshots: - '@aws-sdk/client-sts' - aws-crt - '@aws-sdk/credential-provider-node@3.569.0(@aws-sdk/client-sso-oidc@3.583.0(@aws-sdk/client-sts@3.583.0))(@aws-sdk/client-sts@3.569.0(@aws-sdk/client-sso-oidc@3.569.0))': + '@aws-sdk/credential-provider-node@3.569.0(@aws-sdk/client-sso-oidc@3.583.0)(@aws-sdk/client-sts@3.569.0(@aws-sdk/client-sso-oidc@3.569.0))': dependencies: '@aws-sdk/credential-provider-env': 3.568.0 '@aws-sdk/credential-provider-http': 3.568.0 - '@aws-sdk/credential-provider-ini': 3.568.0(@aws-sdk/client-sso-oidc@3.583.0(@aws-sdk/client-sts@3.583.0))(@aws-sdk/client-sts@3.569.0(@aws-sdk/client-sso-oidc@3.569.0)) + '@aws-sdk/credential-provider-ini': 3.568.0(@aws-sdk/client-sso-oidc@3.583.0)(@aws-sdk/client-sts@3.569.0(@aws-sdk/client-sso-oidc@3.569.0)) '@aws-sdk/credential-provider-process': 3.568.0 - '@aws-sdk/credential-provider-sso': 3.568.0(@aws-sdk/client-sso-oidc@3.583.0(@aws-sdk/client-sts@3.583.0)) + '@aws-sdk/credential-provider-sso': 3.568.0(@aws-sdk/client-sso-oidc@3.583.0) '@aws-sdk/credential-provider-web-identity': 3.568.0(@aws-sdk/client-sts@3.569.0(@aws-sdk/client-sso-oidc@3.569.0)) '@aws-sdk/types': 3.567.0 '@smithy/credential-provider-imds': 2.3.0 @@ -11086,10 +11086,10 @@ snapshots: - '@aws-sdk/client-sso-oidc' - aws-crt - '@aws-sdk/credential-provider-sso@3.568.0(@aws-sdk/client-sso-oidc@3.583.0(@aws-sdk/client-sts@3.583.0))': + '@aws-sdk/credential-provider-sso@3.568.0(@aws-sdk/client-sso-oidc@3.583.0)': dependencies: '@aws-sdk/client-sso': 3.568.0 - '@aws-sdk/token-providers': 3.568.0(@aws-sdk/client-sso-oidc@3.583.0(@aws-sdk/client-sts@3.583.0)) + '@aws-sdk/token-providers': 3.568.0(@aws-sdk/client-sso-oidc@3.583.0) '@aws-sdk/types': 3.567.0 '@smithy/property-provider': 2.2.0 '@smithy/shared-ini-file-loader': 2.4.0 @@ -11143,7 +11143,7 @@ snapshots: '@smithy/types': 3.0.0 tslib: 2.6.2 - '@aws-sdk/credential-providers@3.569.0(@aws-sdk/client-sso-oidc@3.583.0(@aws-sdk/client-sts@3.583.0))': + '@aws-sdk/credential-providers@3.569.0(@aws-sdk/client-sso-oidc@3.583.0)': dependencies: '@aws-sdk/client-cognito-identity': 3.569.0 '@aws-sdk/client-sso': 3.568.0 @@ -11151,10 +11151,10 @@ snapshots: '@aws-sdk/credential-provider-cognito-identity': 3.569.0 '@aws-sdk/credential-provider-env': 3.568.0 '@aws-sdk/credential-provider-http': 3.568.0 - '@aws-sdk/credential-provider-ini': 3.568.0(@aws-sdk/client-sso-oidc@3.583.0(@aws-sdk/client-sts@3.583.0))(@aws-sdk/client-sts@3.569.0(@aws-sdk/client-sso-oidc@3.569.0)) - '@aws-sdk/credential-provider-node': 3.569.0(@aws-sdk/client-sso-oidc@3.583.0(@aws-sdk/client-sts@3.583.0))(@aws-sdk/client-sts@3.569.0(@aws-sdk/client-sso-oidc@3.569.0)) + '@aws-sdk/credential-provider-ini': 3.568.0(@aws-sdk/client-sso-oidc@3.583.0)(@aws-sdk/client-sts@3.569.0(@aws-sdk/client-sso-oidc@3.569.0)) + '@aws-sdk/credential-provider-node': 3.569.0(@aws-sdk/client-sso-oidc@3.583.0)(@aws-sdk/client-sts@3.569.0(@aws-sdk/client-sso-oidc@3.569.0)) '@aws-sdk/credential-provider-process': 3.568.0 - '@aws-sdk/credential-provider-sso': 3.568.0(@aws-sdk/client-sso-oidc@3.583.0(@aws-sdk/client-sts@3.583.0)) + '@aws-sdk/credential-provider-sso': 3.568.0(@aws-sdk/client-sso-oidc@3.583.0) '@aws-sdk/credential-provider-web-identity': 3.568.0(@aws-sdk/client-sts@3.569.0(@aws-sdk/client-sso-oidc@3.569.0)) '@aws-sdk/types': 3.567.0 '@smithy/credential-provider-imds': 2.3.0 @@ -11336,7 +11336,7 @@ snapshots: '@smithy/types': 2.12.0 tslib: 2.6.2 - '@aws-sdk/token-providers@3.568.0(@aws-sdk/client-sso-oidc@3.583.0(@aws-sdk/client-sts@3.583.0))': + '@aws-sdk/token-providers@3.568.0(@aws-sdk/client-sso-oidc@3.583.0)': dependencies: '@aws-sdk/client-sso-oidc': 3.583.0(@aws-sdk/client-sts@3.583.0) '@aws-sdk/types': 3.567.0 @@ -12493,7 +12493,7 @@ snapshots: '@drizzle-team/studio@0.0.5': {} - '@electric-sql/pglite@0.1.5': {} + '@electric-sql/pglite@0.2.12': {} '@esbuild-kit/core-utils@3.1.0': dependencies: