Website Structure

This commit is contained in:
supalerk-ar66 2026-01-13 10:46:40 +07:00
parent 62812f2090
commit 71f0676a62
22365 changed files with 4265753 additions and 791 deletions

21
Frontend-Learner/node_modules/db0/LICENSE generated vendored Normal file
View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) Pooya Parsa <pooya@pi0.io>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

57
Frontend-Learner/node_modules/db0/README.md generated vendored Normal file
View file

@ -0,0 +1,57 @@
# DB0
<!-- automd:badges color=yellow -->
[![npm version](https://img.shields.io/npm/v/db0?color=yellow)](https://npmjs.com/package/db0)
[![npm downloads](https://img.shields.io/npm/dm/db0?color=yellow)](https://npm.chart.dev/db0)
<!-- /automd -->
> [!IMPORTANT]
> DB0 development is in the early stages. Track progress via [GitHub issues](https://github.com/unjs/db0/issues).
DB0 is a lightweight SQL connector:
✅ Works with several SQL [connectors](https://db0.unjs.io/connectors).
✅ Can be [integrated](https://db0.unjs.io/integrations) with ORMs and embedded into frameworks.
✅ Provides a simple but elegant query API out of the box.
👉 Read [📚 Documentation](https://db0.unjs.io)
## Contribution
<details>
<summary>Local development</summary>
- Clone this repository
- Install the latest LTS version of [Node.js](https://nodejs.org/en/)
- Enable [Corepack](https://github.com/nodejs/corepack) using `corepack enable`
- Install dependencies using `pnpm install`
- Run tests using `pnpm dev` or `pnpm test`
</details>
<!-- /automd -->
## License
<!-- automd:contributors license=MIT author="pi0" -->
Published under the [MIT](https://github.com/unjs/db0/blob/main/LICENSE) license.
Made by [@pi0](https://github.com/pi0) and [community](https://github.com/unjs/db0/graphs/contributors) 💛
<br><br>
<a href="https://github.com/unjs/db0/graphs/contributors">
<img src="https://contrib.rocks/image?repo=unjs/db0" />
</a>
<!-- /automd -->
<!-- automd:with-automd -->
---
_🤖 auto updated with [automd](https://automd.unjs.io)_
<!-- /automd -->

View file

@ -0,0 +1,2 @@
import type { Hyperdrive } from "@cloudflare/workers-types";
export declare function getHyperdrive(bindingName: string): Promise<Hyperdrive>;

View file

@ -0,0 +1,11 @@
function getCloudflareEnv() {
return globalThis.__env__ || import("cloudflare:workers").then((mod) => mod.env);
}
export async function getHyperdrive(bindingName) {
const env = await getCloudflareEnv();
const binding = env[bindingName];
if (!binding) {
throw new Error(`[db0] [hyperdrive] binding \`${bindingName}\` not found`);
}
return binding;
}

View file

@ -0,0 +1,11 @@
import type { Primitive, Statement, PreparedStatement } from "db0";
export declare abstract class BoundableStatement<T> implements Statement {
_statement: T;
constructor(rawStmt: T);
bind(...params: Primitive[]): PreparedStatement;
abstract all(...params: Primitive[]): Promise<unknown[]>;
abstract run(...params: Primitive[]): Promise<{
success: boolean;
}>;
abstract get(...params: Primitive[]): Promise<unknown>;
}

View file

@ -0,0 +1,29 @@
export class BoundableStatement {
_statement;
constructor(rawStmt) {
this._statement = rawStmt;
}
bind(...params) {
return new BoundStatement(this, params);
}
}
class BoundStatement {
#statement;
#params;
constructor(statement, params) {
this.#statement = statement;
this.#params = params;
}
bind(...params) {
return new BoundStatement(this.#statement, params);
}
all() {
return this.#statement.all(...this.#params);
}
run() {
return this.#statement.run(...this.#params);
}
get() {
return this.#statement.get(...this.#params);
}
}

View file

@ -0,0 +1,8 @@
import Database from "better-sqlite3";
import type { Connector } from "db0";
export interface ConnectorOptions {
cwd?: string;
path?: string;
name?: string;
}
export default function sqliteConnector(opts: ConnectorOptions): Connector<Database.Database>;

View file

@ -0,0 +1,46 @@
import { resolve, dirname } from "node:path";
import { mkdirSync } from "node:fs";
import Database from "better-sqlite3";
import { BoundableStatement } from "./_internal/statement.mjs";
export default function sqliteConnector(opts) {
let _db;
const getDB = () => {
if (_db) {
return _db;
}
if (opts.name === ":memory:") {
_db = new Database(":memory:");
return _db;
}
const filePath = resolve(opts.cwd || ".", opts.path || `.data/${opts.name || "db"}.sqlite3`);
mkdirSync(dirname(filePath), { recursive: true });
_db = new Database(filePath);
return _db;
};
return {
name: "sqlite",
dialect: "sqlite",
getInstance: () => getDB(),
exec: (sql) => getDB().exec(sql),
prepare: (sql) => new StatementWrapper(() => getDB().prepare(sql)),
dispose: () => {
_db?.close?.();
_db = undefined;
}
};
}
class StatementWrapper extends BoundableStatement {
async all(...params) {
return this._statement().all(...params);
}
async run(...params) {
const res = this._statement().run(...params);
return {
success: res.changes > 0,
...res
};
}
async get(...params) {
return this._statement().get(...params);
}
}

View file

@ -0,0 +1,8 @@
import { Database } from "bun:sqlite";
import type { Connector } from "db0";
export interface ConnectorOptions {
cwd?: string;
path?: string;
name?: string;
}
export default function bunSqliteConnector(opts: ConnectorOptions): Connector<Database>;

View file

@ -0,0 +1,46 @@
import { resolve, dirname } from "node:path";
import { mkdirSync } from "node:fs";
import { Database } from "bun:sqlite";
import { BoundableStatement } from "./_internal/statement.mjs";
export default function bunSqliteConnector(opts) {
let _db;
const getDB = () => {
if (_db) {
return _db;
}
if (opts.name === ":memory:") {
_db = new Database(":memory:");
} else {
const filePath = resolve(opts.cwd || ".", opts.path || `.data/${opts.name || "db"}.bun.sqlite`);
mkdirSync(dirname(filePath), { recursive: true });
_db = new Database(filePath);
}
return _db;
};
return {
name: "sqlite",
dialect: "sqlite",
getInstance: () => getDB(),
exec: (sql) => getDB().exec(sql),
prepare: (sql) => new StatementWrapper(getDB().prepare(sql)),
dispose: () => {
_db?.close?.();
_db = undefined;
}
};
}
class StatementWrapper extends BoundableStatement {
all(...params) {
return Promise.resolve(this._statement.all(...params));
}
run(...params) {
const res = this._statement.run(...params);
return Promise.resolve({
success: true,
...res
});
}
get(...params) {
return Promise.resolve(this._statement.get(...params));
}
}

View file

@ -0,0 +1,6 @@
import type { D1Database } from "@cloudflare/workers-types";
import type { Connector } from "db0";
export interface ConnectorOptions {
bindingName?: string;
}
export default function cloudflareD1Connector(options: ConnectorOptions): Connector<D1Database>;

View file

@ -0,0 +1,32 @@
import { BoundableStatement } from "./_internal/statement.mjs";
export default function cloudflareD1Connector(options) {
const getDB = () => {
// TODO: Remove legacy __cf_env__ support in next major version
const binding = globalThis.__env__?.[options.bindingName] || globalThis.__cf_env__?.[options.bindingName];
if (!binding) {
throw new Error(`[db0] [d1] binding \`${options.bindingName}\` not found`);
}
return binding;
};
return {
name: "cloudflare-d1",
dialect: "sqlite",
getInstance: () => getDB(),
exec: (sql) => getDB().exec(sql),
prepare: (sql) => new StatementWrapper(getDB().prepare(sql))
};
}
class StatementWrapper extends BoundableStatement {
async all(...params) {
const res = await this._statement.bind(...params).all();
return res.results;
}
async run(...params) {
const res = await this._statement.bind(...params).run();
return res;
}
async get(...params) {
const res = await this._statement.bind(...params).first();
return res;
}
}

View file

@ -0,0 +1,7 @@
import mysql from "mysql2/promise";
import type { Connector } from "db0";
type OmitMysqlConfig = Omit<mysql.ConnectionOptions, "user" | "database" | "password" | "password1" | "password2" | "password3" | "port" | "host" | "uri" | "localAddress" | "socketPath" | "insecureAuth" | "passwordSha1" | "disableEval">;
export type ConnectorOptions = {
bindingName: string;
} & OmitMysqlConfig;
export default function cloudflareHyperdriveMysqlConnector(opts: ConnectorOptions): Connector<mysql.Connection>;

View file

@ -0,0 +1,58 @@
import mysql from "mysql2/promise";
import { BoundableStatement } from "./_internal/statement.mjs";
import { getHyperdrive } from "./_internal/cloudflare.mjs";
export default function cloudflareHyperdriveMysqlConnector(opts) {
let _connection;
const getConnection = async () => {
if (_connection) {
return _connection;
}
const hyperdrive = await getHyperdrive(opts.bindingName);
_connection = await mysql.createConnection({
...opts,
host: hyperdrive.host,
user: hyperdrive.user,
password: hyperdrive.password,
database: hyperdrive.database,
port: hyperdrive.port,
disableEval: true
});
return _connection;
};
const query = (sql, params) => getConnection().then((c) => c.query(sql, params)).then((res) => res[0]);
return {
name: "cloudflare-hyperdrive-mysql",
dialect: "mysql",
getInstance: () => getConnection(),
exec: (sql) => query(sql),
prepare: (sql) => new StatementWrapper(sql, query),
dispose: async () => {
await _connection?.end?.();
_connection = undefined;
}
};
}
class StatementWrapper extends BoundableStatement {
#query;
#sql;
constructor(sql, query) {
super();
this.#sql = sql;
this.#query = query;
}
async all(...params) {
const res = await this.#query(this.#sql, params);
return res;
}
async run(...params) {
const res = await this.#query(this.#sql, params);
return {
success: true,
...res
};
}
async get(...params) {
const res = await this.#query(this.#sql, params);
return res[0];
}
}

View file

@ -0,0 +1,7 @@
import pg from "pg";
import type { Connector } from "db0";
type OmitPgConfig = Omit<pg.ClientConfig, "user" | "database" | "password" | "port" | "host" | "connectionString">;
export type ConnectorOptions = {
bindingName: string;
} & OmitPgConfig;
export default function cloudflareHyperdrivePostgresqlConnector(opts: ConnectorOptions): Connector<pg.Client>;

View file

@ -0,0 +1,65 @@
import pg from "pg";
import { BoundableStatement } from "./_internal/statement.mjs";
import { getHyperdrive } from "./_internal/cloudflare.mjs";
export default function cloudflareHyperdrivePostgresqlConnector(opts) {
let _client;
async function getClient() {
if (_client) {
return _client;
}
const hyperdrive = await getHyperdrive(opts.bindingName);
const client = new pg.Client({
...opts,
connectionString: hyperdrive.connectionString
});
_client = client.connect().then(() => {
_client = client;
return _client;
});
return _client;
}
const query = async (sql, params) => {
const client = await getClient();
return client.query(normalizeParams(sql), params);
};
return {
name: "cloudflare-hyperdrive-postgresql",
dialect: "postgresql",
getInstance: () => getClient(),
exec: (sql) => query(sql),
prepare: (sql) => new StatementWrapper(sql, query),
dispose: async () => {
await (await _client)?.end?.();
_client = undefined;
}
};
}
// https://www.postgresql.org/docs/9.3/sql-prepare.html
function normalizeParams(sql) {
let i = 0;
return sql.replace(/\?/g, () => `$${++i}`);
}
class StatementWrapper extends BoundableStatement {
#query;
#sql;
constructor(sql, query) {
super();
this.#sql = sql;
this.#query = query;
}
async all(...params) {
const res = await this.#query(this.#sql, params);
return res.rows;
}
async run(...params) {
const res = await this.#query(this.#sql, params);
return {
success: true,
...res
};
}
async get(...params) {
const res = await this.#query(this.#sql, params);
return res.rows[0];
}
}

View file

@ -0,0 +1,7 @@
import type { Client } from "@libsql/client";
import type { Connector } from "db0";
export type ConnectorOptions = {
getClient: () => Client;
name?: string;
};
export default function libSqlCoreConnector(opts: ConnectorOptions): Connector<Client>;

View file

@ -0,0 +1,44 @@
import { BoundableStatement } from "../_internal/statement.mjs";
export default function libSqlCoreConnector(opts) {
const query = (sql) => opts.getClient().execute(sql);
return {
name: opts.name || "libsql-core",
dialect: "libsql",
getInstance: async () => opts.getClient(),
exec: (sql) => query(sql),
prepare: (sql) => new StatementWrapper(sql, query),
dispose: () => {
opts.getClient()?.close?.();
}
};
}
class StatementWrapper extends BoundableStatement {
#query;
#sql;
constructor(sql, query) {
super();
this.#sql = sql;
this.#query = query;
}
async all(...params) {
const res = await this.#query({
sql: this.#sql,
args: params
});
return res.rows;
}
async run(...params) {
const res = await this.#query({
sql: this.#sql,
args: params
});
return { ...res };
}
async get(...params) {
const res = await this.#query({
sql: this.#sql,
args: params
});
return res.rows[0];
}
}

View file

@ -0,0 +1,4 @@
import type { Config, Client } from "@libsql/client";
import type { Connector } from "db0";
export type ConnectorOptions = Config;
export default function libSqlConnector(opts: ConnectorOptions): Connector<Client>;

View file

@ -0,0 +1,15 @@
import { createClient } from "@libsql/client/http";
import libSqlCore from "./core.mjs";
export default function libSqlConnector(opts) {
let _client;
const getClient = () => {
if (!_client) {
_client = createClient(opts);
}
return _client;
};
return libSqlCore({
name: "libsql-http",
getClient
});
}

View file

@ -0,0 +1,4 @@
import type { Config, Client } from "@libsql/client";
import type { Connector } from "db0";
export type ConnectorOptions = Config;
export default function libSqlConnector(opts: ConnectorOptions): Connector<Client>;

View file

@ -0,0 +1,15 @@
import { createClient } from "@libsql/client";
import libSqlCore from "./core.mjs";
export default function libSqlConnector(opts) {
let _client;
const getClient = () => {
if (!_client) {
_client = createClient(opts);
}
return _client;
};
return libSqlCore({
name: "libsql-node",
getClient
});
}

View file

@ -0,0 +1,4 @@
import type { Config, Client } from "@libsql/client";
import type { Connector } from "db0";
export type ConnectorOptions = Config;
export default function libSqlConnector(opts: ConnectorOptions): Connector<Client>;

View file

@ -0,0 +1,15 @@
import { createClient } from "@libsql/client/http";
import libSqlCore from "./core.mjs";
export default function libSqlConnector(opts) {
let _client;
const getClient = () => {
if (!_client) {
_client = createClient(opts);
}
return _client;
};
return libSqlCore({
name: "libsql-web",
getClient
});
}

View file

@ -0,0 +1,4 @@
import mysql from "mysql2/promise";
import type { Connector } from "db0";
export type ConnectorOptions = mysql.ConnectionOptions;
export default function mysqlConnector(opts: ConnectorOptions): Connector<mysql.Connection>;

View file

@ -0,0 +1,48 @@
import mysql from "mysql2/promise";
import { BoundableStatement } from "./_internal/statement.mjs";
export default function mysqlConnector(opts) {
let _connection;
const getConnection = async () => {
if (_connection) {
return _connection;
}
_connection = await mysql.createConnection({ ...opts });
return _connection;
};
const query = (sql, params) => getConnection().then((c) => c.query(sql, params)).then((res) => res[0]);
return {
name: "mysql",
dialect: "mysql",
getInstance: () => getConnection(),
exec: (sql) => query(sql),
prepare: (sql) => new StatementWrapper(sql, query),
dispose: async () => {
await _connection?.end?.();
_connection = undefined;
}
};
}
class StatementWrapper extends BoundableStatement {
#query;
#sql;
constructor(sql, query) {
super();
this.#sql = sql;
this.#query = query;
}
async all(...params) {
const res = await this.#query(this.#sql, params);
return res;
}
async run(...params) {
const res = await this.#query(this.#sql, params);
return {
success: true,
...res
};
}
async get(...params) {
const res = await this.#query(this.#sql, params);
return res[0];
}
}

View file

@ -0,0 +1,8 @@
import type { Connector } from "db0";
import type { DatabaseSync } from "node:sqlite";
export interface ConnectorOptions {
cwd?: string;
path?: string;
name?: string;
}
export default function nodeSqlite3Connector(opts: ConnectorOptions): Connector<DatabaseSync>;

View file

@ -0,0 +1,54 @@
import { resolve, dirname } from "node:path";
import { mkdirSync } from "node:fs";
import { BoundableStatement } from "./_internal/statement.mjs";
export default function nodeSqlite3Connector(opts) {
let _db;
const getDB = () => {
if (_db) {
return _db;
}
const nodeSqlite = globalThis.process?.getBuiltinModule?.("node:sqlite");
if (!nodeSqlite) {
throw new Error("`node:sqlite` module is not available. Please ensure you are running in Node.js >= 22.5 or Deno >= 2.2.");
}
if (opts.name === ":memory:") {
_db = new nodeSqlite.DatabaseSync(":memory:");
return _db;
}
const filePath = resolve(opts.cwd || ".", opts.path || `.data/${opts.name || "db"}.sqlite`);
mkdirSync(dirname(filePath), { recursive: true });
_db = new nodeSqlite.DatabaseSync(filePath);
return _db;
};
return {
name: "node-sqlite",
dialect: "sqlite",
getInstance: () => getDB(),
exec(sql) {
getDB().exec(sql);
return { success: true };
},
prepare: (sql) => new StatementWrapper(() => getDB().prepare(sql)),
dispose: () => {
_db?.close?.();
_db = undefined;
}
};
}
class StatementWrapper extends BoundableStatement {
async all(...params) {
const raws = this._statement().all(...params);
return raws;
}
async run(...params) {
const res = this._statement().run(...params);
return {
success: true,
...res
};
}
async get(...params) {
const raw = this._statement().get(...params);
return raw;
}
}

View file

@ -0,0 +1,5 @@
import type { PGliteOptions, PGliteInterfaceExtensions } from "@electric-sql/pglite";
import { PGlite } from "@electric-sql/pglite";
import type { Connector } from "db0";
export type ConnectorOptions = PGliteOptions;
export default function pgliteConnector<TOptions extends ConnectorOptions>(opts?: TOptions): Connector<PGlite & PGliteInterfaceExtensions<TOptions["extensions"]>>;

View file

@ -0,0 +1,54 @@
import { PGlite } from "@electric-sql/pglite";
import { BoundableStatement } from "./_internal/statement.mjs";
export default function pgliteConnector(opts) {
let _client;
function getClient() {
return _client ||= PGlite.create(opts).then((res) => _client = res);
}
const query = async (sql, params) => {
const client = await getClient();
const normalizedSql = normalizeParams(sql);
const result = await client.query(normalizedSql, params);
return result;
};
return {
name: "pglite",
dialect: "postgresql",
getInstance: () => getClient(),
exec: (sql) => query(sql),
prepare: (sql) => new StatementWrapper(sql, query),
dispose: async () => {
await (await _client)?.close?.();
_client = undefined;
}
};
}
// https://www.postgresql.org/docs/9.3/sql-prepare.html
function normalizeParams(sql) {
let i = 0;
return sql.replace(/\?/g, () => `$${++i}`);
}
class StatementWrapper extends BoundableStatement {
#query;
#sql;
constructor(sql, query) {
super();
this.#sql = sql;
this.#query = query;
}
async all(...params) {
const result = await this.#query(this.#sql, params);
return result.rows;
}
async run(...params) {
const result = await this.#query(this.#sql, params);
return {
success: true,
...result
};
}
async get(...params) {
const result = await this.#query(this.#sql, params);
return result.rows[0];
}
}

View file

@ -0,0 +1,4 @@
import { Client, type Config } from "@planetscale/database";
import type { Connector } from "db0";
export type ConnectorOptions = Config;
export default function planetscaleConnector(opts: ConnectorOptions): Connector<Client>;

View file

@ -0,0 +1,50 @@
import { Client } from "@planetscale/database";
import { BoundableStatement } from "./_internal/statement.mjs";
export default function planetscaleConnector(opts) {
let _client;
function getClient() {
if (_client) {
return _client;
}
const client = new Client(opts);
_client = client;
return client;
}
// Discussion on how @planetscale/database client works:
// https://github.com/drizzle-team/drizzle-orm/issues/1743#issuecomment-1879479647
const query = (sql, params) => getClient().execute(sql, params);
return {
name: "planetscale",
dialect: "mysql",
getInstance: () => getClient(),
exec: (sql) => query(sql),
prepare: (sql) => new StatementWrapper(sql, query),
dispose: () => {
_client = undefined;
}
};
}
class StatementWrapper extends BoundableStatement {
#query;
#sql;
constructor(sql, query) {
super();
this.#sql = sql;
this.#query = query;
}
async all(...params) {
const res = await this.#query(this.#sql, params);
return res.rows;
}
async run(...params) {
const res = await this.#query(this.#sql, params);
return {
success: true,
...res
};
}
async get(...params) {
const res = await this.#query(this.#sql, params);
return res.rows[0];
}
}

View file

@ -0,0 +1,6 @@
import pg from "pg";
import type { Connector } from "db0";
export type ConnectorOptions = {
url: string;
} | pg.ClientConfig;
export default function postgresqlConnector(opts: ConnectorOptions): Connector<pg.Client>;

View file

@ -0,0 +1,60 @@
import pg from "pg";
import { BoundableStatement } from "./_internal/statement.mjs";
export default function postgresqlConnector(opts) {
let _client;
function getClient() {
if (_client) {
return _client;
}
const client = new pg.Client("url" in opts ? opts.url : opts);
_client = client.connect().then(() => {
_client = client;
return _client;
});
return _client;
}
const query = async (sql, params) => {
const client = await getClient();
return client.query(normalizeParams(sql), params);
};
return {
name: "postgresql",
dialect: "postgresql",
getInstance: () => getClient(),
exec: (sql) => query(sql),
prepare: (sql) => new StatementWrapper(sql, query),
dispose: async () => {
await (await _client)?.end?.();
_client = undefined;
}
};
}
// https://www.postgresql.org/docs/9.3/sql-prepare.html
function normalizeParams(sql) {
let i = 0;
return sql.replace(/\?/g, () => `$${++i}`);
}
class StatementWrapper extends BoundableStatement {
#query;
#sql;
constructor(sql, query) {
super();
this.#sql = sql;
this.#query = query;
}
async all(...params) {
const res = await this.#query(this.#sql, params);
return res.rows;
}
async run(...params) {
const res = await this.#query(this.#sql, params);
return {
success: true,
...res
};
}
async get(...params) {
const res = await this.#query(this.#sql, params);
return res.rows[0];
}
}

View file

@ -0,0 +1,8 @@
import sqlite3 from "sqlite3";
import type { Connector } from "db0";
export interface ConnectorOptions {
cwd?: string;
path?: string;
name?: string;
}
export default function nodeSqlite3Connector(opts: ConnectorOptions): Connector<sqlite3.Database>;

View file

@ -0,0 +1,88 @@
import { resolve, dirname } from "node:path";
import { mkdirSync } from "node:fs";
import sqlite3 from "sqlite3";
import { BoundableStatement } from "./_internal/statement.mjs";
export default function nodeSqlite3Connector(opts) {
let _db;
const _activeStatements = new Set();
const getDB = () => {
if (_db) {
return _db;
}
if (opts.name === ":memory:") {
_db = new sqlite3.Database(":memory:");
return _db;
}
const filePath = resolve(opts.cwd || ".", opts.path || `.data/${opts.name || "db"}.sqlite3`);
mkdirSync(dirname(filePath), { recursive: true });
_db = new sqlite3.Database(filePath);
return _db;
};
const query = (sql) => new Promise((resolve, reject) => {
getDB().exec(sql, (err) => {
if (err) {
return reject(err);
}
resolve({ success: true });
});
});
return {
name: "sqlite3",
dialect: "sqlite",
getInstance: () => getDB(),
exec: (sql) => query(sql),
prepare: (sql) => {
const stmt = new StatementWrapper(sql, getDB());
_activeStatements.add(stmt);
return stmt;
},
dispose: async () => {
await Promise.all([..._activeStatements].map((s) => s.finalize().catch((error) => {
console.warn("[db0] [sqlite3] failed to finalize statement", error);
})));
_activeStatements.clear();
await new Promise((resolve, reject) => _db?.close?.((error) => error ? reject(error) : resolve()));
_db = undefined;
}
};
}
class StatementWrapper extends BoundableStatement {
#onError;
constructor(sql, db) {
super(db.prepare(sql, (err) => {
if (err && this.#onError) {
return this.#onError(err);
}
}));
}
async all(...params) {
const rows = await new Promise((resolve, reject) => {
this.#onError = reject;
this._statement.all(...params, (err, rows) => err ? reject(err) : resolve(rows));
});
return rows;
}
async run(...params) {
await new Promise((resolve, reject) => {
this.#onError = reject;
this._statement.run(...params, (err) => err ? reject(err) : resolve());
});
return { success: true };
}
async get(...params) {
const row = await new Promise((resolve, reject) => {
this.#onError = reject;
this._statement.get(...params, (err, row) => err ? reject(err) : resolve(row));
});
return row;
}
finalize() {
try {
// TODO: Can we await on finalize cb?
this._statement.finalize();
return Promise.resolve();
} catch (error) {
return Promise.reject(error);
}
}
}

277
Frontend-Learner/node_modules/db0/dist/index.d.mts generated vendored Normal file
View file

@ -0,0 +1,277 @@
import "better-sqlite3";
import "bun:sqlite";
import mysql from "mysql2/promise";
import pg from "pg";
import { Client, Config } from "@libsql/client";
import "node:sqlite";
import { PGliteOptions } from "@electric-sql/pglite";
import { Config as Config$1 } from "@planetscale/database";
import "sqlite3";
//#region src/types.d.ts
/**
* Represents primitive types that can be used in SQL operations.
*/
type Primitive = string | number | boolean | undefined | null;
type SQLDialect = "mysql" | "postgresql" | "sqlite" | "libsql";
type Statement = {
/**
* Binds parameters to the statement.
* @param {...Primitive[]} params - Parameters to bind to the SQL statement.
* @returns {PreparedStatement} The instance of the statement with bound parameters.
*/
bind(...params: Primitive[]): PreparedStatement;
/**
* Executes the statement and returns all resulting rows as an array.
* @param {...Primitive[]} params - Parameters to bind to the SQL statement.
* @returns {Promise<unknown[]>} A promise that resolves to an array of rows.
*/
all(...params: Primitive[]): Promise<unknown[]>;
/**
* Executes the statement as an action (e.g. insert, update, delete).
* @param {...Primitive[]} params - Parameters to bind to the SQL statement.
* @returns {Promise<{ success: boolean }>} A promise that resolves to the success state of the action.
*/
run(...params: Primitive[]): Promise<{
success: boolean;
}>;
/**
* Executes the statement and returns a single row.
* @param {...Primitive[]} params - Parameters to bind to the SQL statement.
* @returns {Promise<unknown>} A promise that resolves to the first row in the result set.
*/
get(...params: Primitive[]): Promise<unknown>;
};
type PreparedStatement = {
/**
* Binds parameters to the statement.
* @param {...Primitive[]} params - Parameters to bind to the SQL statement.
* @returns {PreparedStatement} The instance of the statement with bound parameters.
*/
bind(...params: Primitive[]): PreparedStatement;
/**
* Executes the statement and returns all resulting rows as an array.
* @returns {Promise<unknown[]>} A promise that resolves to an array of rows.
*/
all(): Promise<unknown[]>;
/**
* Executes the statement as an action (e.g. insert, update, delete).
* @returns {Promise<{ success: boolean }>} A promise that resolves to the success state of the action.
*/
run(): Promise<{
success: boolean;
}>;
/**
* Executes the statement and returns a single row.
* @returns {Promise<unknown>} A promise that resolves to the first row in the result set.
*/
get(): Promise<unknown>;
};
/**
* Represents the result of a database execution.
*/
type ExecResult = unknown;
/**
* Defines a database connector for executing SQL queries and preparing statements.
*/
type Connector<TInstance = unknown> = {
/**
* The name of the connector.
*/
name: string;
/**
* The SQL dialect used by the connector.
*/
dialect: SQLDialect;
/**
* The client instance used internally.
*/
getInstance: () => TInstance | Promise<TInstance>;
/**
* Executes an SQL query directly and returns the result.
* @param {string} sql - The SQL string to execute.
* @returns {ExecResult | Promise<ExecResult>} The result of the execution.
*/
exec: (sql: string) => ExecResult | Promise<ExecResult>;
/**
* Prepares an SQL statement for execution.
* @param {string} sql - The SQL string to prepare.
* @returns {statement} The prepared SQL statement.
*/
prepare: (sql: string) => Statement;
/**
* Closes the database connection and cleans up resources.
* @returns {void | Promise<void>} A promise that resolves when the connection is closed.
*/
dispose?: () => void | Promise<void>;
};
/**
* Represents default SQL results, including any error messages, row changes and rows returned.
*/
type DefaultSQLResult = {
lastInsertRowid?: number;
changes?: number;
error?: string;
rows?: {
id?: string | number;
[key: string]: unknown;
}[];
success?: boolean;
};
interface Database<TConnector extends Connector = Connector> extends AsyncDisposable {
readonly dialect: SQLDialect;
/**
* Indicates whether the database instance has been disposed/closed.
* @returns {boolean} True if the database has been disposed, false otherwise.
*/
readonly disposed: boolean;
/**
* The client instance used internally.
* @returns {Promise<TInstance>} A promise that resolves with the client instance.
*/
getInstance: () => Promise<Awaited<ReturnType<TConnector["getInstance"]>>>;
/**
* Executes a raw SQL string.
* @param {string} sql - The SQL string to execute.
* @returns {Promise<ExecResult>} A promise that resolves with the execution result.
*/
exec: (sql: string) => Promise<ExecResult>;
/**
* Prepares an SQL statement from a raw SQL string.
* @param {string} sql - The SQL string to prepare.
* @returns {statement} The prepared SQL statement.
*/
prepare: (sql: string) => Statement;
/**
* Executes SQL queries using tagged template literals.
* @template T The expected type of query result.
* @param {TemplateStringsArray} strings - The segments of the SQL string.
* @param {...Primitive[]} values - The values to interpolate into the SQL string.
* @returns {Promise<T>} A promise that resolves with the typed result of the query.
*/
sql: <T = DefaultSQLResult>(strings: TemplateStringsArray, ...values: Primitive[]) => Promise<T>;
/**
* Closes the database connection and cleans up resources.
* @returns {Promise<void>} A promise that resolves when the connection is closed.
*/
dispose: () => Promise<void>;
/**
* AsyncDisposable implementation for using syntax support.
* @returns {Promise<void>} A promise that resolves when the connection is disposed.
*/
[Symbol.asyncDispose]: () => Promise<void>;
}
//#endregion
//#region src/database.d.ts
/**
* Creates and returns a database interface using the specified connector.
* This interface allows you to execute raw SQL queries, prepare SQL statements,
* and execute SQL queries with parameters using tagged template literals.
*
* @param {Connector} connector - The database connector used to execute and prepare SQL statements. See {@link Connector}.
* @returns {Database} The database interface that allows SQL operations. See {@link Database}.
*/
declare function createDatabase<TConnector extends Connector = Connector>(connector: TConnector): Database<TConnector>;
//#endregion
//#region src/connectors/better-sqlite3.d.ts
interface ConnectorOptions$15 {
cwd?: string;
path?: string;
name?: string;
}
//#endregion
//#region src/connectors/bun-sqlite.d.ts
interface ConnectorOptions$14 {
cwd?: string;
path?: string;
name?: string;
}
//#endregion
//#region src/connectors/cloudflare-d1.d.ts
interface ConnectorOptions$13 {
bindingName?: string;
}
//#endregion
//#region src/connectors/cloudflare-hyperdrive-mysql.d.ts
type OmitMysqlConfig = Omit<mysql.ConnectionOptions, "user" | "database" | "password" | "password1" | "password2" | "password3" | "port" | "host" | "uri" | "localAddress" | "socketPath" | "insecureAuth" | "passwordSha1" | "disableEval">;
type ConnectorOptions$12 = {
bindingName: string;
} & OmitMysqlConfig;
//#endregion
//#region src/connectors/cloudflare-hyperdrive-postgresql.d.ts
type OmitPgConfig = Omit<pg.ClientConfig, "user" | "database" | "password" | "port" | "host" | "connectionString">;
type ConnectorOptions$11 = {
bindingName: string;
} & OmitPgConfig;
//#endregion
//#region src/connectors/libsql/core.d.ts
type ConnectorOptions$10 = {
getClient: () => Client;
name?: string;
};
//#endregion
//#region src/connectors/libsql/http.d.ts
type ConnectorOptions$9 = Config;
//#endregion
//#region src/connectors/libsql/node.d.ts
type ConnectorOptions$8 = Config;
//#endregion
//#region src/connectors/libsql/web.d.ts
type ConnectorOptions$7 = Config;
//#endregion
//#region src/connectors/mysql2.d.ts
type ConnectorOptions$6 = mysql.ConnectionOptions;
//#endregion
//#region src/connectors/node-sqlite.d.ts
interface ConnectorOptions$5 {
cwd?: string;
path?: string;
name?: string;
}
//#endregion
//#region src/connectors/pglite.d.ts
type ConnectorOptions$4 = PGliteOptions;
//#endregion
//#region src/connectors/planetscale.d.ts
type ConnectorOptions$3 = Config$1;
//#endregion
//#region src/connectors/postgresql.d.ts
type ConnectorOptions$2 = {
url: string;
} | pg.ClientConfig;
//#endregion
//#region src/connectors/sqlite3.d.ts
interface ConnectorOptions$1 {
cwd?: string;
path?: string;
name?: string;
}
//#endregion
//#region src/_connectors.d.ts
type ConnectorName = "better-sqlite3" | "bun-sqlite" | "bun" | "cloudflare-d1" | "cloudflare-hyperdrive-mysql" | "cloudflare-hyperdrive-postgresql" | "libsql-core" | "libsql-http" | "libsql-node" | "libsql" | "libsql-web" | "mysql2" | "node-sqlite" | "sqlite" | "pglite" | "planetscale" | "postgresql" | "sqlite3";
type ConnectorOptions = {
"better-sqlite3": ConnectorOptions$15;
"bun-sqlite": ConnectorOptions$14;
/** alias of bun-sqlite */
"bun": ConnectorOptions$14;
"cloudflare-d1": ConnectorOptions$13;
"cloudflare-hyperdrive-mysql": ConnectorOptions$12;
"cloudflare-hyperdrive-postgresql": ConnectorOptions$11;
"libsql-core": ConnectorOptions$10;
"libsql-http": ConnectorOptions$9;
"libsql-node": ConnectorOptions$8;
/** alias of libsql-node */
"libsql": ConnectorOptions$8;
"libsql-web": ConnectorOptions$7;
"mysql2": ConnectorOptions$6;
"node-sqlite": ConnectorOptions$5;
/** alias of node-sqlite */
"sqlite": ConnectorOptions$5;
"pglite": ConnectorOptions$4;
"planetscale": ConnectorOptions$3;
"postgresql": ConnectorOptions$2;
"sqlite3": ConnectorOptions$1;
};
declare const connectors: Record<ConnectorName, string>;
//#endregion
export { type Connector, type ConnectorName, type ConnectorOptions, type Database, type ExecResult, type PreparedStatement, type Primitive, type SQLDialect, type Statement, connectors, createDatabase };

116
Frontend-Learner/node_modules/db0/dist/index.mjs generated vendored Normal file
View file

@ -0,0 +1,116 @@
//#region src/template.ts
function sqlTemplate(strings, ...values) {
if (!isTemplateStringsArray(strings) || !Array.isArray(values)) throw new Error("[db0] invalid template invocation");
const staticIndexes = [];
let result = strings[0] || "";
for (let i = 1; i < strings.length; i++) {
if (result.endsWith("{") && strings[i].startsWith("}")) {
result = result.slice(0, -1) + values[i - 1] + strings[i].slice(1);
staticIndexes.push(i - 1);
continue;
}
result += `?${strings[i] ?? ""}`;
}
const dynamicValues = values.filter((_, i) => !staticIndexes.includes(i));
return [result.trim(), dynamicValues];
}
function isTemplateStringsArray(strings) {
return Array.isArray(strings) && "raw" in strings && Array.isArray(strings.raw);
}
//#endregion
//#region src/database.ts
const SQL_SELECT_RE = /^select/i;
const SQL_RETURNING_RE = /[\s]returning[\s]/i;
const DIALECTS_WITH_RET = new Set(["postgresql", "sqlite"]);
const DISPOSED_ERR = "This database instance has been disposed and cannot be used.";
/**
* Creates and returns a database interface using the specified connector.
* This interface allows you to execute raw SQL queries, prepare SQL statements,
* and execute SQL queries with parameters using tagged template literals.
*
* @param {Connector} connector - The database connector used to execute and prepare SQL statements. See {@link Connector}.
* @returns {Database} The database interface that allows SQL operations. See {@link Database}.
*/
function createDatabase(connector) {
let _disposed = false;
const checkDisposed = () => {
if (_disposed) {
const err = new Error(DISPOSED_ERR);
Error.captureStackTrace?.(err, checkDisposed);
throw err;
}
};
return {
get dialect() {
return connector.dialect;
},
get disposed() {
return _disposed;
},
getInstance() {
checkDisposed();
return connector.getInstance();
},
exec: (sql) => {
checkDisposed();
return Promise.resolve(connector.exec(sql));
},
prepare: (sql) => {
checkDisposed();
return connector.prepare(sql);
},
sql: async (strings, ...values) => {
checkDisposed();
const [sql, params] = sqlTemplate(strings, ...values);
if (SQL_SELECT_RE.test(sql) || DIALECTS_WITH_RET.has(connector.dialect) && SQL_RETURNING_RE.test(sql)) {
const rows = await connector.prepare(sql).all(...params);
return {
rows,
success: true
};
} else {
const res = await connector.prepare(sql).run(...params);
return res;
}
},
dispose: () => {
if (_disposed) return Promise.resolve();
_disposed = true;
try {
return Promise.resolve(connector.dispose?.());
} catch (error) {
return Promise.reject(error);
}
},
[Symbol.asyncDispose]() {
return this.dispose();
}
};
}
//#endregion
//#region src/_connectors.ts
const connectors = Object.freeze({
"better-sqlite3": "db0/connectors/better-sqlite3",
"bun-sqlite": "db0/connectors/bun-sqlite",
"bun": "db0/connectors/bun-sqlite",
"cloudflare-d1": "db0/connectors/cloudflare-d1",
"cloudflare-hyperdrive-mysql": "db0/connectors/cloudflare-hyperdrive-mysql",
"cloudflare-hyperdrive-postgresql": "db0/connectors/cloudflare-hyperdrive-postgresql",
"libsql-core": "db0/connectors/libsql/core",
"libsql-http": "db0/connectors/libsql/http",
"libsql-node": "db0/connectors/libsql/node",
"libsql": "db0/connectors/libsql/node",
"libsql-web": "db0/connectors/libsql/web",
"mysql2": "db0/connectors/mysql2",
"node-sqlite": "db0/connectors/node-sqlite",
"sqlite": "db0/connectors/node-sqlite",
"pglite": "db0/connectors/pglite",
"planetscale": "db0/connectors/planetscale",
"postgresql": "db0/connectors/postgresql",
"sqlite3": "db0/connectors/sqlite3"
});
//#endregion
export { connectors, createDatabase };

View file

@ -0,0 +1,42 @@
import { type Logger, type RelationalSchemaConfig, type Query, type TablesRelationalConfig } from "drizzle-orm";
import { SQLiteAsyncDialect, SQLiteSession, SQLitePreparedQuery } from "drizzle-orm/sqlite-core";
import type { PreparedQueryConfig, SelectedFieldsOrdered, SQLiteExecuteMethod, SQLiteTransactionConfig } from "drizzle-orm/sqlite-core";
import type { Database, Statement } from "db0";
// Used as reference: https://github.com/drizzle-team/drizzle-orm/blob/main/drizzle-orm/src/d1/session.ts
export interface DB0SessionOptions {
logger?: Logger;
}
export declare class DB0Session<
TFullSchema extends Record<string, unknown>,
TSchema extends TablesRelationalConfig
> extends SQLiteSession<"async", unknown, TFullSchema, TSchema> {
private db;
private schema;
private options;
dialect: SQLiteAsyncDialect;
private logger;
constructor(db: Database, dialect: SQLiteAsyncDialect, schema: RelationalSchemaConfig<TSchema> | undefined, options?: DB0SessionOptions);
// @ts-expect-error TODO
prepareQuery(query: Query, fields: SelectedFieldsOrdered | undefined, executeMethod: SQLiteExecuteMethod, customResultMapper?: (rows: unknown[][]) => unknown): DB0PreparedQuery;
// TODO: Implement batch
// TODO: Implement transaction
transaction<T>(transaction: (tx: any) => T | Promise<T>, config?: SQLiteTransactionConfig): Promise<T>;
}
export declare class DB0PreparedQuery<T extends PreparedQueryConfig = PreparedQueryConfig> extends SQLitePreparedQuery<{
type: "async";
run: Awaited<ReturnType<Statement["run"]>>;
all: T["all"];
get: T["get"];
values: T["values"];
execute: T["execute"];
}> {
private stmt;
private logger;
constructor(stmt: Statement, query: Query, logger: Logger, fields: SelectedFieldsOrdered | undefined, executeMethod: SQLiteExecuteMethod, customResultMapper?: (rows: unknown[][]) => unknown);
run(): Promise<{
success: boolean;
}>;
all(): Promise<unknown[]>;
get(): Promise<unknown>;
values(): Promise<unknown[]>;
}

View file

@ -0,0 +1,57 @@
import { NoopLogger } from "drizzle-orm";
import { SQLiteSession, SQLitePreparedQuery } from "drizzle-orm/sqlite-core";
export class DB0Session extends SQLiteSession {
dialect;
logger;
constructor(db, dialect, schema, options = {}) {
super(dialect);
this.db = db;
this.schema = schema;
this.options = options;
this.logger = options.logger ?? new NoopLogger();
}
// @ts-expect-error TODO
prepareQuery(query, fields, executeMethod, customResultMapper) {
const stmt = this.db.prepare(query.sql);
return new DB0PreparedQuery(stmt, query, this.logger, fields, executeMethod, customResultMapper);
}
// TODO: Implement batch
// TODO: Implement transaction
transaction(transaction, config) {
throw new Error("transaction is not implemented!");
// const tx = new D1Transaction('async', this.dialect, this, this.schema);
// await this.run(sql.raw(`begin${config?.behavior ? ' ' + config.behavior : ''}`));
// try {
// const result = await transaction(tx);
// await this.run(sql`commit`);
// return result;
// } catch (err) {
// await this.run(sql`rollback`);
// throw err;
// }
}
}
export class DB0PreparedQuery extends SQLitePreparedQuery {
constructor(stmt, query, logger, fields, executeMethod, customResultMapper) {
super("async", executeMethod, query);
this.stmt = stmt;
this.logger = logger;
}
run() {
return this.stmt.run(...this.query.params);
}
all() {
return this.stmt.all(...this.query.params);
}
get() {
return this.stmt.get(...this.query.params);
}
values() {
return Promise.reject(new Error("values is not implemented!"));
}
}
// Object.defineProperty(DB0PreparedQuery, entityKind, {
// value: "DB0PreparedQuery",
// enumerable: true,
// configurable: true,
// });

View file

@ -0,0 +1 @@
export {};

View file

@ -0,0 +1,48 @@
import { getTableName, is, Column, SQL } from "drizzle-orm";
// Source: https://github.com/drizzle-team/drizzle-orm/blob/main/drizzle-orm/src/utils.ts#L14
/** @internal */
export function mapResultRow(columns, row, joinsNotNullableMap) {
// Key -> nested object key, value -> table name if all fields in the nested object are from the same table, false otherwise
const nullifyMap = {};
// eslint-disable-next-line unicorn/no-array-reduce
const result = columns.reduce((result, { path, field }, columnIndex) => {
let decoder;
if (is(field, Column)) {
decoder = field;
} else if (is(field, SQL)) {
decoder = "decoder" in field && field.decoder;
} else {
decoder = "decoder" in field.sql && field.sql.decoder;
}
let node = result;
for (const [pathChunkIndex, pathChunk] of path.entries()) {
if (pathChunkIndex < path.length - 1) {
if (!(pathChunk in node)) {
node[pathChunk] = {};
}
node = node[pathChunk];
} else {
const rawValue = row[columnIndex];
const value = node[pathChunk] = rawValue === null ? null : decoder.mapFromDriverValue(rawValue);
if (joinsNotNullableMap && is(field, Column) && path.length === 2) {
const objectName = path[0];
if (!(objectName in nullifyMap)) {
nullifyMap[objectName] = value === null ? getTableName(field.table) : false;
} else if (typeof nullifyMap[objectName] === "string" && nullifyMap[objectName] !== getTableName(field.table)) {
nullifyMap[objectName] = false;
}
}
}
}
return result;
}, {});
// Nullify all nested objects from nullifyMap that are nullable
if (joinsNotNullableMap && Object.keys(nullifyMap).length > 0) {
for (const [objectName, tableName] of Object.entries(nullifyMap)) {
if (typeof tableName === "string" && !joinsNotNullableMap[tableName]) {
result[objectName] = null;
}
}
}
return result;
}

View file

@ -0,0 +1,4 @@
import { BaseSQLiteDatabase } from "drizzle-orm/sqlite-core";
import type { Database } from "db0";
export type DrizzleDatabase<TSchema extends Record<string, unknown> = Record<string, never>> = BaseSQLiteDatabase<"async", any, TSchema>;
export declare function drizzle<TSchema extends Record<string, unknown> = Record<string, never>>(db: Database): DrizzleDatabase<TSchema>;

View file

@ -0,0 +1,15 @@
import { BaseSQLiteDatabase, SQLiteAsyncDialect } from "drizzle-orm/sqlite-core";
import { DB0Session } from "./_session.mjs";
export function drizzle(db) {
// TODO: Support schema
const schema = undefined;
const dialect = new SQLiteAsyncDialect();
const session = new DB0Session(db, dialect, schema);
return new BaseSQLiteDatabase(
"async",
dialect,
// @ts-expect-error TODO
session,
schema
);
}

99
Frontend-Learner/node_modules/db0/package.json generated vendored Normal file
View file

@ -0,0 +1,99 @@
{
"name": "db0",
"version": "0.3.4",
"description": "Lightweight SQL Connector",
"repository": "unjs/db0",
"license": "MIT",
"sideEffects": false,
"type": "module",
"exports": {
".": {
"types": "./dist/index.d.mts",
"default": "./dist/index.mjs"
},
"./connectors/*": {
"types": "./dist/connectors/*.d.ts",
"default": "./dist/connectors/*.mjs"
},
"./integrations/*": {
"types": "./dist/integrations/*/index.d.ts",
"default": "./dist/integrations/*/index.mjs"
},
"./connectors/libsql/*": {
"types": "./dist/connectors/libsql/*.d.ts",
"default": "./dist/connectors/libsql/*.mjs"
}
},
"types": "./dist/index.d.mts",
"files": [
"dist"
],
"devDependencies": {
"@cloudflare/workers-types": "^4.20251001.0",
"@electric-sql/pglite": "^0.3.10",
"@libsql/client": "^0.15.15",
"@planetscale/database": "^1.19.0",
"@types/better-sqlite3": "^7.6.13",
"@types/bun": "^1.2.23",
"@types/pg": "^8.15.5",
"@vitest/coverage-v8": "^3.2.4",
"automd": "^0.4.2",
"better-sqlite3": "^12.4.1",
"changelogen": "^0.6.2",
"db0": "link:.",
"dotenv": "^17.2.3",
"drizzle-orm": "^0.44.5",
"eslint": "^9.36.0",
"eslint-config-unjs": "^0.5.0",
"jiti": "^2.6.1",
"mlly": "^1.8.0",
"mysql2": "^3.15.1",
"obuild": "^0.2.1",
"pg": "^8.16.3",
"prettier": "^3.6.2",
"scule": "^1.3.0",
"typescript": "^5.9.3",
"vitest": "^3.2.4",
"wrangler": "^4.40.3"
},
"peerDependencies": {
"@electric-sql/pglite": "*",
"@libsql/client": "*",
"better-sqlite3": "*",
"drizzle-orm": "*",
"mysql2": "*",
"sqlite3": "*"
},
"peerDependenciesMeta": {
"@libsql/client": {
"optional": true
},
"better-sqlite3": {
"optional": true
},
"drizzle-orm": {
"optional": true
},
"mysql2": {
"optional": true
},
"@electric-sql/pglite": {
"optional": true
},
"sqlite3": {
"optional": true
}
},
"scripts": {
"build": "pnpm gen-connectors && obuild",
"gen-connectors": "jiti scripts/gen-connectors.ts",
"db0": "pnpm jiti src/cli",
"dev": "vitest",
"lint": "eslint . && prettier -c src test",
"lint:fix": "eslint . --fix && prettier -w src test",
"release": "pnpm test && changelogen --release --push && pnpm publish",
"test": "pnpm lint && pnpm test:types && vitest run --coverage && pnpm test:bun",
"test:bun": "bun test ./test/connectors/bun-test.ts",
"test:types": "tsc --noEmit"
}
}