UNPKG

alinea

Version:
1,799 lines (1,769 loc) 72.1 kB
import { and, asc, eq, gt, isNotNull, isNull, like, not, or, when } from "../../chunks/chunk-TO6JVYUN.js"; import { Field, Functions, callFunction, column, jsonAggregateArray, jsonArray, table } from "../../chunks/chunk-H54PGW2N.js"; import { Sql, getData, getField, getQuery, getResolver, getSelection, getSql, getTable, getTarget, hasField, hasQuery, hasSelection, hasSql, hasTable, hasTarget, input, internalData, internalQuery, internalResolver, internalSelection, internalSql, internalTarget, sql } from "../../chunks/chunk-PNILF4WM.js"; import { __export } from "../../chunks/chunk-NZLE2WMY.js"; // src/backend/api/CreateBackend.ts import { assert } from "alinea/core/util/Assert"; // node_modules/rado/dist/driver.js var driver_exports = {}; __export(driver_exports, { "@electric-sql/pglite": () => connect7, "@libsql/client": () => connect4, "@neondatabase/serverless": () => connect6, "@vercel/postgres": () => connect6, "better-sqlite3": () => connect, "bun:sqlite": () => connect2, d1: () => connect3, mysql2: () => connect5, pg: () => connect6, "sql.js": () => connect8 }); // node_modules/rado/dist/universal/functions.js var insertId = sql.universal({ sqlite: Functions.last_insert_rowid(), postgres: Functions.lastval(), mysql: Functions.last_insert_id() }).mapWith(Number); function concat(...slices) { return sql.universal({ mysql: Functions.concat(...slices), default: sql.join(slices.map(input), sql` || `) }); } // node_modules/rado/dist/universal/transactions.js function txGenerator(create) { function run(tx) { const iter = create(tx); const next = (inner) => { if (inner instanceof Promise) return inner.then(iter.next.bind(iter)).catch(iter.throw.bind(iter)).then(handle); try { return handle(iter.next(inner)); } catch (err) { return handle(iter.throw(err)); } }; const handle = ({ done, value }) => { if (done) return value; return next(typeof value === "function" ? tx.transaction(value) : value); }; return next(); } return Object.assign(run, { *[Symbol.iterator]() { return yield run; } }); } // node_modules/rado/dist/core/Virtual.js function virtual(alias, source) { const target = { [internalTarget]: sql.identifier(alias) }; if (source && hasSql(source)) { const expr = getSql(source); const name = expr.alias; if (!name) throw new Error("Cannot alias a virtual field without a name"); return Object.assign(new Field(alias, name, expr), target); } return new Proxy(target, { get(target2, field) { if (field in target2) return target2[field]; const from = source?.[field]; if (typeof field !== "string") return from; return target2[field] = new Field( alias, field, from ? getSql(from) : void 0 ); } }); } // node_modules/rado/dist/core/Selection.js var SqlColumn = class { constructor(sql2, targetName) { this.sql = sql2; this.targetName = targetName; } result(ctx) { const value = ctx.values[ctx.index++]; if (!this.sql.mapFromDriverValue) return value; return this.sql.mapFromDriverValue(value, ctx.specs); } }; var ObjectColumn = class { constructor(nullable, entries) { this.nullable = nullable; this.entries = entries; } result(ctx) { const result = {}; let isNullable = this.nullable.size > 0; for (const entry of this.entries) { const name = entry[0]; const col = entry[1]; const value = col.result(ctx); result[name] = value; if (isNullable) { if (value === null) { if (col.targetName && !this.nullable.has(col.targetName)) isNullable = false; } else { isNullable = false; } } } if (isNullable) return null; return result; } }; var Selection = class { constructor(input2, nullable) { this.input = input2; this.nullable = nullable; const root = this.#defineColumn(nullable, input2); this.mapRow = root.result.bind(root); } mapRow; makeVirtual(name) { return virtual(name, this.input); } #defineColumn(nullable, input2) { const expr = getSql(input2); if (expr) return new SqlColumn(expr, getField(input2)?.targetName); return new ObjectColumn( nullable, Object.entries(input2).map(([name, value]) => [ name, this.#defineColumn(nullable, value) ]) ); } fieldNames() { return this.#fieldNames(this.input, /* @__PURE__ */ new Set()); } #fieldNames(input2, names, name) { const expr = getSql(input2); if (expr) { let exprName = name ?? expr.alias; if (!exprName) throw new Error("Missing field name"); while (names.has(exprName)) exprName = `${exprName}_`; return [exprName]; } return Object.entries(input2).flatMap( ([name2, value]) => this.#fieldNames(value, names, name2) ); } #selectionToSql(input2, names, name) { const expr = getSql(input2); if (expr) { let exprName = name ?? expr.alias; if (exprName) { while (names.has(exprName)) exprName = `${exprName}_`; names.add(exprName); if (hasField(input2)) { const field = getField(input2); if (field.fieldName === exprName) return [expr]; } return [sql`${expr.forSelection()} as ${sql.identifier(exprName)}`]; } return [expr]; } return Object.entries(input2).flatMap( ([name2, value]) => this.#selectionToSql(value, names, name2) ); } get [internalSql]() { return sql.join(this.#selectionToSql(this.input, /* @__PURE__ */ new Set()), sql`, `); } join(right, operator) { return this; } }; var TableSelection = class extends Selection { constructor(table2) { super(table2, /* @__PURE__ */ new Set()); this.table = table2; } join(right, operator) { const leftTable = getTable(this.table); const rightTable = getTable(right); const nullable = new Set(this.nullable); if (operator === "right" || operator === "full") nullable.add(leftTable.aliased); if (operator === "left" || operator === "full") nullable.add(rightTable.aliased); return new JoinSelection([this.table, right], nullable); } }; var JoinSelection = class _JoinSelection extends Selection { constructor(tables, nullable) { super( Object.fromEntries(tables.map((table2) => [getTable(table2).aliased, table2])), nullable ); this.tables = tables; } join(right, operator) { const rightTable = getTable(right); const nullable = new Set(this.nullable); if (operator === "right" || operator === "full") this.tables.map((table2) => getTable(table2).aliased).forEach(nullable.add, nullable); if (operator === "left" || operator === "full") nullable.add(rightTable.aliased); return new _JoinSelection([...this.tables, right], nullable); } }; function selection(input2, nullable = []) { return new Selection(input2, new Set(nullable)); } ((selection2) => { function table2(table22) { return new TableSelection(table22); } selection2.table = table2; })(selection || (selection = {})); // node_modules/rado/dist/core/Query.js var Executable = class { #execute; constructor(exec) { this.#execute = exec; } *[Symbol.iterator]() { const interim = this.#execute(); const isAsync = interim instanceof Promise; if (!isAsync) return interim; let result; yield interim.then((v) => result = v); return result; } run() { return this.#execute(); } // biome-ignore lint/suspicious/noThenProperty: async then(onfulfilled, onrejected) { try { const result = await this.#execute(); return onfulfilled ? onfulfilled(result) : result; } catch (error) { return onrejected ? onrejected(error) : Promise.reject(error); } } catch(onrejected) { return this.then().catch(onrejected); } finally(onfinally) { return this.then().finally(onfinally); } }; var QueryBatch = class extends Executable { constructor(queryResolver, queries) { super(() => { return queryResolver.batch(queries).execute(); }); } }; var Query = class extends Executable { [internalData]; constructor(data) { super(() => this.#exec(void 0)); this[internalData] = data; } #exec(method, db) { const data = getData(this); const resolver = db ? getResolver(db) : data.resolver; const isSelection = hasSelection(this); const prepared = resolver.prepare(this, ""); const resultType = method ?? (isSelection ? "all" : "run"); try { const result = prepared[resultType](); if (result instanceof Promise) return result.then((res) => res ?? null).finally(prepared.free.bind(prepared)); prepared.free(); return result ?? null; } catch (error) { prepared.free(); throw error; } } all(db) { return this.#exec("all", db); } get(db) { return this.#exec("get", db); } run(db) { return this.#exec("run", db); } prepare(name) { return getData(this).resolver.prepare(this, name); } toSQL(db) { const resolver = db ? getResolver(db) : getData(this).resolver; if (!resolver) throw new Error("Query has no resolver"); return resolver.toSQL(this); } }; // node_modules/rado/dist/core/query/Delete.js var Delete = class extends Query { [internalData]; constructor(data) { super(data); this[internalData] = data; if (data.returning) this[internalSelection] = data.returning; } get [internalQuery]() { return sql.chunk("emitDelete", this); } }; var DeleteFrom = class _DeleteFrom extends Delete { where(...where) { return new _DeleteFrom({ ...getData(this), where: and(...where) }); } returning(returning) { const data = getData(this); return new Delete({ ...data, returning: returning ? selection(returning) : selection.table(data.from) }); } }; // node_modules/rado/dist/core/query/Insert.js var Insert = class extends Query { [internalData]; constructor(data) { super(data); this[internalData] = data; if (data.returning) this[internalSelection] = data.returning; } get [internalQuery]() { return sql.chunk("emitInsert", this); } }; var InsertCanReturn = class extends Insert { returning(returning) { const data = getData(this); return new Insert({ ...data, returning: returning ? selection(returning) : selection.table(data.into) }); } }; var InsertCanConflict = class extends InsertCanReturn { onConflictDoNothing(onConflict) { return this.#onConflict(onConflict ?? {}); } onConflictDoUpdate(onConflict) { return this.#onConflict(onConflict); } onDuplicateKeyUpdate(update) { return new InsertCanReturn({ ...getData(this), onDuplicateKeyUpdate: this.#updateFields(update.set) }); } #updateFields(update) { return sql.join( Object.entries(update).map( ([key, value]) => sql`${sql.identifier(key)} = ${input(value)}` ), sql`, ` ); } #onConflict({ target, targetWhere, set, setWhere }) { const update = set && this.#updateFields(set); return new InsertCanReturn({ ...getData(this), onConflict: sql.join([ target && sql`(${Array.isArray(target) ? sql.join(target, sql`, `) : target})`, targetWhere && sql`where ${targetWhere}`, update ? sql.join([ sql`do update set ${update}`, setWhere && sql`where ${setWhere}` ]) : sql`do nothing` ]) }); } }; var defaultKeyword = sql.universal({ sqlite: sql`null`, default: sql`default` }); var InsertInto = class { [internalData]; constructor(data) { this[internalData] = data; } values(insert) { const { into } = getData(this); const rows = Array.isArray(insert) ? insert : [insert]; const table2 = getTable(into); const values = sql.join( rows.map((row) => { return sql`(${sql.join( Object.entries(table2.columns).map(([key, column2]) => { const value = row[key]; const { $default, mapToDriverValue } = getData(column2); if (value !== void 0) { if (value && typeof value === "object" && hasSql(value)) return value; return input(mapToDriverValue?.(value) ?? value); } if ($default) return $default(); return defaultKeyword; }), sql`, ` )})`; }), sql`, ` ); return new InsertCanConflict({ ...getData(this), values }); } select(query) { return new InsertCanConflict({ ...getData(this), select: getQuery(query) }); } }; // node_modules/rado/dist/core/query/Union.js var UnionBase = class extends Query { [internalData]; #makeSelf() { const { select } = getData(this); return select.makeVirtual(Sql.SELF_TARGET); } union(right) { return new Union({ ...getData(this), left: this, operator: sql`union`, right: typeof right === "function" ? right(this.#makeSelf()) : right }); } unionAll(right) { return new Union({ ...getData(this), left: this, operator: sql`union all`, right: typeof right === "function" ? right(this.#makeSelf()) : right }); } intersect(right) { return new Union({ ...getData(this), left: this, operator: sql`intersect`, right: typeof right === "function" ? right(this.#makeSelf()) : right }); } intersectAll(right) { return new Union({ ...getData(this), left: this, operator: sql`intersect all`, right: typeof right === "function" ? right(this.#makeSelf()) : right }); } except(right) { return new Union({ ...getData(this), left: this, operator: sql`except`, right: typeof right === "function" ? right(this.#makeSelf()) : right }); } exceptAll(right) { return new Union({ ...getData(this), left: this, operator: sql`except all`, right: typeof right === "function" ? right(this.#makeSelf()) : right }); } }; var Union = class extends UnionBase { [internalData]; [internalSelection]; constructor(data) { super(data); this[internalData] = data; this[internalSelection] = data.select; } get [internalQuery]() { return sql.chunk("emitUnion", getData(this)); } }; // node_modules/rado/dist/core/query/Select.js var Select = class _Select extends UnionBase { [internalData]; constructor(data) { super(data); this[internalData] = data; } as(alias) { const fields = getSelection(this).makeVirtual(alias); return Object.assign(fields, { [internalTarget]: sql`(${getQuery(this)}) as ${sql.identifier( alias )}`.inlineFields(true) }); } from(target) { const { select: current } = getData(this); const from = hasTarget(target) ? getTarget(target) : getSql(target); const isTable = hasTable(target); const selected = current ?? (isTable ? selection.table(target) : selection(sql`*`)); return new _Select({ ...getData(this), select: selected, from }); } #join(operator, right, on) { const { from, select: current } = getData(this); return new _Select({ ...getData(this), select: hasTable(right) ? current?.join(right, operator) : current, from: sql.join([ from, sql.unsafe(`${operator} join`), getTarget(right), sql`on ${on}` ]) }); } leftJoin(right, on) { return this.#join("left", right, on); } rightJoin(right, on) { return this.#join("right", right, on); } innerJoin(right, on) { return this.#join("inner", right, on); } fullJoin(right, on) { return this.#join("full", right, on); } where(...where) { return new _Select({ ...getData(this), where: and(...where) }); } groupBy(...exprs) { return new _Select({ ...getData(this), groupBy: sql.join(exprs, sql.unsafe(", ")) }); } having(having) { return new _Select({ ...getData(this), having: typeof having === "function" ? having(getSelection(this).input) : having }); } orderBy(...exprs) { return new _Select({ ...getData(this), orderBy: sql.join(exprs, sql.unsafe(", ")) }); } limit(limit) { return new _Select({ ...getData(this), limit: input(limit) }); } offset(offset) { return new _Select({ ...getData(this), offset: input(offset) }); } get [internalSelection]() { const { select } = getData(this); if (!select) throw new Error("No selection defined"); return select; } get [internalQuery]() { return sql.chunk("emitSelect", getData(this)); } get [internalSql]() { return sql`(${getQuery(this)})`; } }; // node_modules/rado/dist/core/query/Update.js var Update = class extends Query { [internalData]; constructor(data) { super(data); this[internalData] = data; if (data.returning) this[internalSelection] = data.returning; } get [internalQuery]() { return sql.chunk("emitUpdate", this); } }; var UpdateTable = class _UpdateTable extends Update { set(values) { const { table: table2 } = getData(this); const set = sql.join( Object.entries(values).map(([key, value]) => { const column2 = getTable(table2).columns[key]; const { mapToDriverValue } = getData(column2); const expr = value && typeof value === "object" && hasSql(value) ? value : input(mapToDriverValue?.(value) ?? value); return sql`${sql.identifier(key)} = ${expr}`; }), sql`, ` ); return new _UpdateTable({ ...getData(this), set }); } where(...where) { return new _UpdateTable({ ...getData(this), where: and(...where) }); } returning(returning) { const data = getData(this); return new Update({ ...data, returning: returning ? selection(returning) : selection.table(data.table) }); } }; // node_modules/rado/dist/core/Builder.js var BuilderBase = class { [internalData]; constructor(data = {}) { this[internalData] = data; } select(input2) { return new Select({ ...getData(this), select: input2 && selection(input2) }); } selectDistinct(input2) { return new Select({ ...getData(this), select: input2 && selection(input2), distinct: true }); } selectDistinctOn(columns, input2) { return new Select({ ...getData(this), select: input2 && selection(input2), distinctOn: columns }); } update(table2) { return new UpdateTable({ ...getData(this), table: table2 }); } insert(into) { return new InsertInto({ ...getData(this), into }); } delete(from) { return new DeleteFrom({ ...getData(this), from }); } }; var Builder = class extends BuilderBase { $with(cteName) { return { as(query) { const fields = getSelection(query).makeVirtual(cteName); return Object.assign(fields, { [internalQuery]: getQuery(query).nameSelf(cteName) }); } }; } with(...definitions) { return new BuilderBase({ ...getData(this), cte: { recursive: false, definitions } }); } withRecursive(...definitions) { return new BuilderBase({ ...getData(this), cte: { recursive: true, definitions } }); } }; // node_modules/rado/dist/core/Resolver.js var Resolver = class { #driver; #dialect; constructor(driver, dialect) { this.#driver = driver; this.#dialect = dialect; } toSQL(query) { const emitter = this.#dialect.emit(query); return { sql: emitter.sql, params: emitter.bind() }; } prepare(query, name) { const isSelection = hasSelection(query); const mapRow = isSelection ? getSelection(query).mapRow : void 0; const emitter = this.#dialect.emit(query); const stmt = this.#driver.prepare(emitter.sql, { isSelection, name }); return new PreparedStatement(emitter, stmt, mapRow, this.#driver); } batch(queries) { return new Batch( this.#driver, queries.map((query) => { const isSelection = hasSelection(query); const mapRow = isSelection ? getSelection(query).mapRow : void 0; const emitter = this.#dialect.emit(query); return { sql: emitter.sql, params: emitter.bind(), isSelection, mapRow }; }) ); } }; var Batch = class { #driver; #queries; constructor(driver, queries) { this.#driver = driver; this.#queries = queries; } #transform = (results) => { const ctx = { values: void 0, index: 0, specs: this.#driver }; for (let i = 0; i < this.#queries.length; i++) { const { mapRow } = this.#queries[i]; if (!mapRow) continue; const rows = results[i]; for (let j = 0; j < results[i].length; j++) { ctx.values = rows[i]; ctx.index = 0; rows[i] = mapRow(ctx); } } return results; }; execute() { const results = this.#driver.batch(this.#queries); if (results instanceof Promise) return results.then(this.#transform); return this.#transform(results); } }; var PreparedStatement = class { #emitter; #stmt; #mapRow; #specs; constructor(emitter, stmt, mapRow, specs) { this.#emitter = emitter; this.#stmt = stmt; this.#mapRow = mapRow; this.#specs = specs; } #transform = (rows) => { if (!this.#mapRow) return rows; const ctx = { values: void 0, index: 0, specs: this.#specs }; for (let i = 0; i < rows.length; i++) { ctx.values = rows[i]; ctx.index = 0; rows[i] = this.#mapRow(ctx); } return rows; }; all(inputs) { const rows = this.#stmt.values(this.#emitter.bind(inputs)); if (rows instanceof Promise) return rows.then(this.#transform); return this.#transform(rows); } get(inputs) { const rows = this.all(inputs); if (rows instanceof Promise) return rows.then((rows2) => rows2[0]); return rows[0]; } run(inputs) { return this.#stmt.run(this.#emitter.bind(inputs)); } async execute(inputs) { return this.all(inputs); } free() { this.#stmt.free(); } }; // node_modules/rado/dist/core/Database.js var Database = class extends Builder { driver; dialect; diff; [internalResolver]; constructor(driver, dialect, diff) { const resolver = new Resolver(driver, dialect); super({ resolver }); this[internalResolver] = resolver; this.driver = driver; this.dialect = dialect; this.diff = diff; } close() { return this.driver.close(); } [Symbol.dispose]() { this.close(); } async [Symbol.asyncDispose]() { return this.close(); } create(...tables) { return new QueryBatch( getResolver(this), tables.flatMap((table2) => getTable(table2).create()) ); } drop(...tables) { return new QueryBatch( getResolver(this), tables.map((table2) => getTable(table2).drop()) ); } migrate(...tables) { const computeDiff = this.diff; return this.transaction( txGenerator(function* (tx) { for (const table2 of tables) { const diff = yield* computeDiff(table2); if (diff.length > 0) yield* tx.batch(diff.map(sql.unsafe)); } }) ); } batch(queries) { return new QueryBatch(getResolver(this), queries); } execute(input2) { const emitter = this.dialect.emit(input2); if (emitter.hasParams) throw new Error("Query has parameters"); return this.driver.exec(emitter.sql); } transaction(run, options = {}) { return this.driver.transaction( (inner) => { const tx = new Transaction(inner, this.dialect, this.diff); return run(tx); }, { async: run.constructor.name === "AsyncFunction", ...options } ); } }; var Rollback = class extends Error { constructor(data) { super("Rollback"); this.data = data; } }; var Transaction = class extends Database { rollback(data) { throw new Rollback(data); } }; var SyncDatabase = class extends Database { }; var AsyncDatabase = class extends Database { }; // node_modules/rado/dist/sqlite/columns.js function boolean(name) { return column({ name, type: column.integer(), mapFromDriverValue(value) { return value === 1; }, mapToDriverValue(value) { return value ? 1 : 0; } }); } function integer(name) { return column({ name, type: column.integer() }); } function text(name) { return column({ name, type: column.text() }); } // node_modules/rado/dist/core/Dialect.js var Dialect = class { runtime; #createEmitter; constructor(runtime, createEmitter) { this.runtime = runtime; this.#createEmitter = createEmitter; } emit = (input2) => { const sql2 = hasQuery(input2) ? getQuery(input2) : getSql(input2); const emitter = new this.#createEmitter(this.runtime); sql2.emitTo(emitter); return emitter; }; inline = (input2) => { const sql2 = hasQuery(input2) ? getQuery(input2) : getSql(input2); const emitter = new this.#createEmitter(this.runtime); sql2.inlineValues().emitTo(emitter); return emitter.sql; }; }; // node_modules/rado/dist/core/Param.js var NamedParam = class { constructor(name) { this.name = name; } }; var ValueParam = class { constructor(value) { this.value = value; } }; // node_modules/rado/dist/core/Emitter.js var Emitter = class { #runtime; sql = ""; params = []; constructor(runtime) { this.#runtime = runtime; } get hasParams() { return this.params.length > 0; } bind(inputs) { return this.params.map((param) => { if (param instanceof ValueParam) return this.processValue(param.value); if (inputs && param.name in inputs) return this.processValue(inputs[param.name]); throw new Error(`Missing input for named parameter: ${param.name}`); }); } processValue(value) { return value; } emitIdentifierOrSelf(value) { if (value === Sql.SELF_TARGET) { if (!this.selfName) throw new Error("Self target not defined"); this.emitIdentifier(this.selfName); } else { this.emitIdentifier(value); } } selfName; emitSelf({ name, inner }) { this.selfName = name; inner.emitTo(this); this.selfName = void 0; } emitUnsafe(value) { this.sql += value; } emitField({ targetName, fieldName }) { this.emitIdentifierOrSelf(targetName); this.emitUnsafe("."); this.emitIdentifier(fieldName); } emitCreateTable(tableApi) { sql.join([ sql`create table`, //ifNotExists ? sql`if not exists` : undefined, tableApi.target(), sql`(${tableApi.createDefinition()})` ]).emitTo(this); } emitColumn(column2) { sql.join([ column2.type, column2.primary && sql`primary key`, column2.notNull && sql`not null`, column2.isUnique && sql`unique`, column2.autoIncrement && sql`autoincrement`, column2.defaultValue && sql`default ${column2.defaultValue}`, column2.references && sql`references ${sql.chunk("emitReferences", [column2.references()])}`, column2.onUpdate && sql`on update ${column2.onUpdate}` ]).emitTo(this); } emitReferences(fields) { callFunction( sql.identifier(fields[0].targetName), fields.map((field) => sql.identifier(field.fieldName)) ).emitTo(this); } emitDelete(deleteOp) { const { cte, from, where, returning } = getData(deleteOp); if (cte) this.emitWith(cte); const table2 = getTable(from); sql.query({ deleteFrom: sql.identifier(table2.name), where, returning }).emitTo(this); } emitInsert(insert) { const { cte, into, values, select, onConflict, onDuplicateKeyUpdate, returning } = getData(insert); if (cte) this.emitWith(cte); const table2 = getTable(into); const tableName = sql.identifier(table2.name); sql.query({ insertInto: sql`${tableName}(${table2.listColumns()})`, ...values ? { values } : { "": select }, onConflict, onDuplicateKeyUpdate, returning }).inlineFields(false).emitTo(this); } emitSelect({ select, cte, from, distinct, distinctOn, where, groupBy, orderBy, having, limit, offset }) { if (cte) this.emitWith(cte); const prefix = distinctOn ? sql`distinct on (${sql.join(distinctOn, sql`, `)})` : distinct && sql`distinct`; sql.query({ select: sql.join([prefix, select]), from, where, groupBy, orderBy, having, limit, offset }).emitTo(this); } emitUnion({ left, operator, right }) { sql.join([getQuery(left), operator, getQuery(right)]).emitTo(this); } emitUpdate(update) { const { cte, table: table2, set, where, returning } = getData(update); const tableApi = getTable(table2); if (cte) this.emitWith(cte); sql.query({ update: sql.identifier(tableApi.name), set, where, returning }).inlineFields(false).emitTo(this); } emitWith(cte) { sql.query({ [cte.recursive ? "withRecursive" : "with"]: sql.join( cte.definitions.map((cte2) => { const query = getQuery(cte2); const target = getTarget(cte2); return sql`${target} as (${query})`; }), sql`, ` ) }).add(sql` `).emitTo(this); } emitInclude(data) { const wrapQuery = Boolean(data.limit || data.offset || data.orderBy); const innerQuery = sql.chunk("emitSelect", data); const inner = wrapQuery ? sql`select * from (${innerQuery})` : innerQuery; if (!data.select) throw new Error("No selection defined"); const fields = data.select.fieldNames(); const subject = jsonArray( ...fields.map((name) => sql`_.${sql.identifier(name)}`) ); sql`(select ${data.first ? subject : jsonAggregateArray(subject)} from (${inner}) as _)`.emitTo(this); } emitUniversal(runtimes) { const sql2 = runtimes[this.#runtime] ?? runtimes.default; if (!sql2) throw new Error("Unsupported runtime"); sql2.emitTo(this); } }; // node_modules/rado/dist/sqlite/dialect.js var DOUBLE_QUOTE = '"'; var ESCAPE_DOUBLE_QUOTE = '""'; var MATCH_DOUBLE_QUOTE = /"/g; var SINGLE_QUOTE = "'"; var ESCAPE_SINGLE_QUOTE = "''"; var MATCH_SINGLE_QUOTE = /'/g; var sqliteDialect = new Dialect( "sqlite", class extends Emitter { processValue(value) { return typeof value === "boolean" ? value ? 1 : 0 : value; } emitValue(value) { this.sql += "?"; this.params.push(new ValueParam(value)); } emitJsonPath({ target, asSql, segments }) { target.emitTo(this); this.sql += asSql ? "->>" : "->"; this.sql += this.quoteString( `$${segments.map((p) => typeof p === "number" ? `[${p}]` : `.${p}`).join("")}` ); } emitInline(value) { if (value === null || value === void 0) return this.sql += "null"; if (typeof value === "number") return this.sql += value; if (typeof value === "string") return this.sql += this.quoteString(value); if (typeof value === "boolean") return this.sql += value ? "1" : "0"; this.sql += `json(${this.quoteString(JSON.stringify(value))})`; } emitPlaceholder(name) { this.sql += "?"; this.params.push(new NamedParam(name)); } emitIdentifier(identifier) { this.sql += DOUBLE_QUOTE + identifier.replace(MATCH_DOUBLE_QUOTE, ESCAPE_DOUBLE_QUOTE) + DOUBLE_QUOTE; } quoteString(input2) { return SINGLE_QUOTE + input2.replace(MATCH_SINGLE_QUOTE, ESCAPE_SINGLE_QUOTE) + SINGLE_QUOTE; } } ); // node_modules/rado/dist/sqlite/diff.js var TableInfo = table("TableInfo", { cid: integer().notNull(), name: text().notNull(), type: text().notNull(), notnull: boolean().notNull(), dflt_value: text(), pk: integer().notNull() }); var SqliteMaster = table("SqliteMaster", { type: text().notNull(), name: text().notNull(), tbl_name: text().notNull(), rootpage: integer().notNull(), sql: text().notNull() }); var inline = (sql2) => sqliteDialect.inline(sql2); var sqliteDiff = (targetTable) => { return txGenerator(function* (tx) { const tableApi = getTable(targetTable); const columnInfo = yield* tx.select(TableInfo).from(sql`pragma_table_info(${sql.inline(tableApi.name)}) as "TableInfo"`); const indexInfo = yield* tx.select(SqliteMaster).from(sql`sqlite_master as "SqliteMaster"`).where( eq(SqliteMaster.tbl_name, tableApi.name), eq(SqliteMaster.type, "index") ); const hasSinglePrimaryKey = columnInfo.reduce((acc, column2) => acc + column2.pk, 0) === 1; const localColumns = new Map( columnInfo.map((column2) => { return [ column2.name, inline( sql.chunk("emitColumn", { type: sql.unsafe(column2.type.toLowerCase()), notNull: column2.notnull, primary: hasSinglePrimaryKey && column2.pk === 1, defaultValue: column2.dflt_value !== null ? sql.unsafe(column2.dflt_value) : void 0 }) ) ]; }) ); const schemaColumns = new Map( Object.entries(tableApi.columns).map(([name, column2]) => { const columnApi = getData(column2); return [ columnApi.name ?? name, inline(sql.chunk("emitColumn", columnApi)) ]; }) ); const localIndexes = new Map( indexInfo.filter((index) => !index.name.startsWith("sqlite_autoindex_")).map((index) => [index.name, index.sql]) ); const schemaIndexes = new Map( Object.entries(tableApi.indexes()).map(([name, index]) => { const indexApi = getData(index); return [name, inline(indexApi.toSql(tableApi.name, name, false))]; }) ); const stmts = []; const columnNames = /* @__PURE__ */ new Set([ ...localColumns.keys(), ...schemaColumns.keys() ]); for (const columnName of columnNames) { const localInstruction = localColumns.get(columnName); const schemaInstruction = schemaColumns.get(columnName); if (!schemaInstruction) { stmts.push( sql.query({ alterTable: sql.identifier(tableApi.name), dropColumn: sql.identifier(columnName) }) ); } else if (!localInstruction) { stmts.push( sql.query({ alterTable: sql.identifier(tableApi.name), addColumn: [ sql.identifier(columnName), sql.unsafe(schemaInstruction) ] }) ); } else if (localInstruction !== schemaInstruction) { return recreate(); } } const indexNames = /* @__PURE__ */ new Set([ ...localIndexes.keys(), ...schemaIndexes.keys() ]); for (const indexName of indexNames) { const localInstruction = localIndexes.get(indexName); const schemaInstruction = schemaIndexes.get(indexName); const dropLocal = sql.query({ dropIndex: sql.identifier(indexName) }); if (!schemaInstruction) { stmts.unshift(dropLocal); } else if (schemaInstruction && !localInstruction) { stmts.push(sql.unsafe(schemaInstruction)); } else if (schemaInstruction && localInstruction !== schemaInstruction) { stmts.unshift(dropLocal); stmts.push(sql.unsafe(schemaInstruction)); } } try { yield* txGenerator(function* (sp) { yield* sp.batch(stmts); const [tableInfo] = yield* sp.select(SqliteMaster.sql).from(sql`sqlite_master as "SqliteMaster"`).where( eq(SqliteMaster.tbl_name, tableApi.name), eq(SqliteMaster.type, "table") ); sp.rollback(tableInfo); }); } catch (err) { if (!(err instanceof Rollback)) throw err; const localInstruction = err.data; const schemaInstruction = inline(tableApi.createTable()); const stripStmt = (q) => q.slice("create table ".length); if (stripStmt(localInstruction) !== stripStmt(schemaInstruction)) { return recreate(); } } return stmts.map(inline); function recreate() { const tempName = `new_${tableApi.name}`; const tempTable = table(tempName, tableApi.columns); const missingColumns = new Set( Array.from(columnNames).filter((name) => !localColumns.has(name)) ); const selection2 = Object.fromEntries( Object.entries(tableApi.columns).map(([name, column2]) => { const columnApi = getData(column2); const key = columnApi.name ?? name; if (missingColumns.has(key)) return [name, columnApi.defaultValue ?? sql`null`]; return [name, targetTable[name]]; }) ); return [ // Create a new temporary table with the new definition tableApi.createTable(tempName), // Copy the data from the old table to the new table getQuery( tx.insert(tempTable).select(tx.select(selection2).from(targetTable)) ), // Drop the old table sql.query({ dropTable: sql.identifier(tableApi.name) }), // Rename the temporary table to the old table name sql.query({ alterTable: sql.identifier(tempName), renameTo: sql.identifier(tableApi.name) }), // Create missing indexes ...tableApi.createIndexes() ].map(inline); } }); }; // node_modules/rado/dist/sqlite/transactions.js var locks = /* @__PURE__ */ new WeakMap(); function execTransaction(driver, depth, wrap, run, options) { const needsLock = options.async; const behavior = options.behavior ?? "deferred"; if (!needsLock) return transact(); let trigger; const lock = new Promise((resolve) => trigger = resolve); const current = Promise.resolve(locks.get(driver)); locks.set(driver, lock); return current.then(transact).finally(trigger); function transact() { try { driver.exec(depth > 0 ? `savepoint d${depth}` : `begin ${behavior}`); const result = run(wrap(depth + 1)); if (result instanceof Promise) return result.then(release, rollback); return release(result); } catch (error) { return rollback(error); } } function release(result) { driver.exec(depth > 0 ? `release d${depth}` : "commit"); return result; } function rollback(error) { driver.exec(depth > 0 ? `rollback to d${depth}` : "rollback"); throw error; } } // node_modules/rado/dist/driver/better-sqlite3.js var PreparedStatement2 = class { constructor(stmt, isSelection) { this.stmt = stmt; this.isSelection = isSelection; } all(params) { return this.stmt.all(...params); } run(params) { return this.stmt.run(...params); } get(params) { return this.stmt.get(...params); } values(params) { if (this.isSelection) return this.stmt.raw(true).all(...params); this.stmt.run(...params); return []; } free() { } }; var BetterSqlite3Driver = class _BetterSqlite3Driver { constructor(client, depth = 0) { this.client = client; this.depth = depth; } parsesJson = false; supportsTransactions = true; exec(query) { this.client.exec(query); } close() { this.client.close(); } prepare(sql2, options) { return new PreparedStatement2(this.client.prepare(sql2), options.isSelection); } batch(queries) { return this.transaction( (tx) => queries.map( ({ sql: sql2, params, isSelection }) => tx.prepare(sql2, { isSelection }).values(params) ), {} ); } transaction(run, options) { return execTransaction( this, this.depth, (depth) => new _BetterSqlite3Driver(this.client, depth), run, options ); } }; function connect(db) { return new SyncDatabase( new BetterSqlite3Driver(db), sqliteDialect, sqliteDiff ); } // node_modules/rado/dist/driver/bun-sqlite.js var PreparedStatement3 = class { constructor(stmt) { this.stmt = stmt; } all(params) { return this.stmt.all(...params); } run(params) { return this.stmt.run(...params); } get(params) { return this.stmt.get(...params); } values(params) { return this.stmt.values(...params); } free() { this.stmt.finalize(); } }; var BunSqliteDriver = class _BunSqliteDriver { constructor(client, depth = 0) { this.client = client; this.depth = depth; } parsesJson = false; supportsTransactions = true; exec(query) { this.client.exec(query); } close() { this.client.close(); } prepare(sql2) { return new PreparedStatement3(this.client.prepare(sql2)); } batch(queries) { return this.transaction((tx) => { return queries.map(({ sql: sql2, params }) => tx.prepare(sql2).values(params)); }, {}); } transaction(run, options) { return execTransaction( this, this.depth, (depth) => new _BunSqliteDriver(this.client, depth), run, options ); } }; function connect2(db) { return new SyncDatabase(new BunSqliteDriver(db), sqliteDialect, sqliteDiff); } // node_modules/rado/dist/driver/d1.js var PreparedStatement4 = class { constructor(stmt, isSelection) { this.stmt = stmt; this.isSelection = isSelection; } async all(params) { return this.stmt.bind(...params).all().then(({ results }) => results); } async run(params) { const results = await this.stmt.bind(...params).run(); } async get(params) { return this.stmt.bind(...params).first(); } async values(params) { if (this.isSelection) return this.stmt.bind(...params).raw(); await this.stmt.bind(...params).run(); return []; } free() { } }; var D1Driver = class { constructor(client) { this.client = client; } parsesJson = false; supportsTransactions = false; async exec(query) { await this.client.exec(query); } prepare(sql2, options) { return new PreparedStatement4(this.client.prepare(sql2), options.isSelection); } async close() { } async batch(queries) { const stmts = queries.map( ({ sql: sql2, params }) => this.client.prepare(sql2).bind(...params) ); const rows = await this.client.batch(stmts); return rows.map((row) => row.results); } async transaction() { throw new Error("Transactions are not supported in D1"); } }; function connect3(client) { return new AsyncDatabase(new D1Driver(client), sqliteDialect, sqliteDiff); } // node_modules/rado/dist/driver/libsql.js var PreparedStatement5 = class { constructor(client, sql2) { this.client = client; this.sql = sql2; } async all(params) { const result = await this.client.execute({ sql: this.sql, args: params }); return result.rows; } async run(params) { const result = await this.client.execute({ sql: this.sql, args: params }); } async get(params) { return (await this.all(params))[0] ?? null; } async values(params) { const result = await this.client.execute({ sql: this.sql, args: params }); return result.rows; } free() { } }; var LibSQLClient = class _LibSQLClient { constructor(client, depth = 0) { this.client = client; this.depth = depth; } parsesJson = false; supportsTransactions = true; async exec(query) { await this.client.execute(query); } prepare(sql2, options) { return new PreparedStatement5(this.client, sql2); } async close() { if ("close" in this.client) return this.client.close(); } async batch(queries) { const stmts = queries.map(({ sql: sql2, params }) => { return { sql: sql2, args: params }; }); const rows = await this.client.batch(stmts); return rows.map((row) => row.rows); } async transaction(run, options) { const client = "transaction" in this.client ? await this.client.transaction() : this.client; const driver = new _LibSQLClient(client, this.depth + 1); if (this.depth > 0) await client.execute(`savepoint d${this.depth}`); try { const result = await run(driver); if (this.depth > 0) await client.execute(`release savepoint d${this.depth}`); else await client.commit(); return result; } catch (error) { if (this.depth > 0) await client.execute(`rollback to savepoint d${this.depth}`); else await client.rollback(); throw error; } finally { if (this.depth === 0) client.close(); } } }; function connect4(client) { return new AsyncDatabase(new LibSQLClient(client), sqliteDialect, sqliteDiff); } // node_modules/rado/dist/mysql/dialect.js var BACKTICK = "`"; var ESCAPE_BACKTICK = "``"; var MATCH_BACKTICK = /`/g; var SINGLE_QUOTE2 = "'"; var ESCAPE_SINGLE_QUOTE2 = "''"; var MATCH_SINGLE_QUOTE2 = /'/g; var mysqlDialect = new Dialect( "mysql", class extends Emitter { runtime = "mysql"; paramIndex = 0; emitValue(value) { this.sql += "?"; this.params.push(new ValueParam(value)); } emitJsonPath({ target, asSql, segments }) { target.emitTo(this); this.sql += asSql ? "->>" : "->"; this.sql += this.quoteString( `$${segments.map((p) => typeof p === "number" ? `[${p}]` : `.${p}`).join("")}` ); } emitInline(value) { if (value === null || value === void 0) return this.sql += "null"; if (typeof value === "number" || typeof value === "boolean") return this.sql += value; if (typeof value === "string") return this.sql += this.quoteString(value); this.sql += this.quoteString(JSON.stringify(value)); } emitPlaceholder(name) { this.sql += "?"; this.params.push(new NamedParam(name)); } quoteString(input2) { return SINGLE_QUOTE2 + input2.replace(MATCH_SINGLE_QUOTE2, ESCAPE_SINGLE_QUOTE2) + SINGLE_QUOTE2; } emitIdentifier(identifier) { this.sql += BACKTICK + identifier.replace(MATCH_BACKTICK, ESCAPE_BACKTICK) + BACKTICK; } } ); // node_modules/rado/dist/core/Schema.js function schema(schemaName) { return { table(tableName, columns, config) { return table(tableName, columns, config, schemaName); } }; } // node_modules/rado/dist/mysql/columns.js function integer2(name) { return column({ name, type: column.integer() }); } function text2(name) { return column({ name, type: column.text() }); } // node_modules/rado/dist/mysql/diff.js var ns = schema("information_schema"); var Information = ns.table("columns", { table_name: text2().notNull(), column_name: text2().notNull(), column_type: text2().notNull(), is_nullable: text2().notNull(), column_default: text2(), extra: text2().notNull(), table_schema: text2().notNull() }); var Statistics = ns.table("statistics", { table_name: text2().notNull(), column_name: text2().notNull(), index_name: text2().notNull(), non_unique: integer2().notNull(), seq_in_index: integer2().notNull(), table_schema: text2().notNull() }); var TableConstraints = ns.table("table_constraints", { constraint_name: text2().notNull(), table_name: text2().notNull(), constraint_type: text2().notNull(), table_schema: text2().notNull() }); var inline2 = (sql2) => mysqlDialect.inline(sql2); var mysqlDiff = (hasTable2) => { return txGenerator(function* (tx) { const tableApi = getTable(hasTable2); const stmts = []; const columnInfo = yield* tx.select({ name: Information.column_name, type: Information.column_type, notNull: eq(Information.is_nullable, "NO"), defaultValue: Information.column_default, extra: Information.extra }).from(Information).where( eq(Information.table_name, tableApi.name), eq(Information.table_schema, sql`database()`) ); const indexInfo = yield* tx.select({ index_name: Statistics.index_name, column_name: Statistics.column_name, non_unique: Statistics.non_unique, seq_in_index: Statistics.seq_in_index }).from(Statistics).where( eq(Statistics.table_name, tableApi.name), eq(Statistics.table_schema, sql`database()`) ).orderBy(Statistics.index_name, Statistics.seq_in_index); const indexMap = /* @__PURE__ */ new Map(); for (const index of indexInfo) { if (!indexMap.has(index.index_name)) { indexMap.set(index.index_name, []); } indexMap.get(index.index_name).push(index.column_name); } const localColumns = new Map( columnInfo.map((column2) => { let type = column2.type.toLowerCase(); const isAutoIncrement = column2.extra.toLowerCase().includes("auto_increment"); if (isAutoIncrement) { if (type.includes("bigint")) type = "bigserial"; else if (type.includes("smallint")) type = "smallserial"; else type = "serial"; } return [ column2.name, { type: sql.unsafe(type), notNull: column2.notNull && !isAutoIncrement, defaultValue: column2.defaultValue && !isAutoIncrement ? sql.unsafe(column2.defaultValue) : void 0 } ]; }) ); const schemaColumns = new Map( Object.entries(tableApi.columns).map(([name, column2]) => { const columnApi = getData(column2); return [columnApi.name ?? name, columnApi]; }) ); const columnNames = /* @__PURE__ */ new Set([ ...localColumns.keys(), ...schemaColumns.keys() ]); for (const columnName of columnNames) { const alterTable = sql.identifier(tableApi.name); const column2 = sql.identifier(columnName); const localInstruction =