UNPKG

flint-orm

Version:

Type-safe SQLite ORM for JavaScript

1,690 lines (1,669 loc) 119 kB
// @bun var __create = Object.create; var __getProtoOf = Object.getPrototypeOf; var __defProp = Object.defineProperty; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; function __accessProp(key) { return this[key]; } var __toESMCache_node; var __toESMCache_esm; var __toESM = (mod, isNodeMode, target) => { var canCache = mod != null && typeof mod === "object"; if (canCache) { var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap; var cached = cache.get(mod); if (cached) return cached; } target = mod != null ? __create(__getProtoOf(mod)) : {}; const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target; for (let key of __getOwnPropNames(mod)) if (!__hasOwnProp.call(to, key)) __defProp(to, key, { get: __accessProp.bind(mod, key), enumerable: true }); if (canCache) cache.set(mod, to); return to; }; var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports); var __returnValue = (v) => v; function __exportSetter(name, newValue) { this[name] = __returnValue.bind(null, newValue); } var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true, configurable: true, set: __exportSetter.bind(all, name) }); }; var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res); var __require = import.meta.require; // node_modules/@tursodatabase/database-common/dist/bind.js function bindParams(stmt, params) { const len = params?.length; if (len === 0) { return; } if (len === 1) { const param = params[0]; if (isPlainObject(param)) { bindNamedParams(stmt, param); return; } if (Array.isArray(param)) { bindPositionalParams(stmt, [param]); return; } bindValue(stmt, 1, param); return; } bindPositionalParams(stmt, params); } function isPlainObject(obj) { if (!obj || typeof obj !== "object") return false; const proto = Object.getPrototypeOf(obj); return proto === Object.prototype || proto === null; } function bindNamedParams(stmt, paramObj) { const paramCount = stmt.parameterCount(); for (let i = 1;i <= paramCount; i++) { const paramName = stmt.parameterName(i); if (paramName) { const key = paramName.substring(1); const value = paramObj[key]; if (value !== undefined) { bindValue(stmt, i, value); } } } } function bindPositionalParams(stmt, params) { let bindIndex = 1; for (let i = 0;i < params.length; i++) { const param = params[i]; if (Array.isArray(param)) { for (let j = 0;j < param.length; j++) { bindValue(stmt, bindIndex++, param[j]); } } else { bindValue(stmt, bindIndex++, param); } } } function bindValue(stmt, index, value) { stmt.bindAt(index, value); } // node_modules/@tursodatabase/database-common/dist/sqlite-error.js var SqliteError; var init_sqlite_error = __esm(() => { SqliteError = class SqliteError extends Error { name; code; rawCode; constructor(message, code, rawCode) { super(message); this.name = "SqliteError"; this.code = code; this.rawCode = rawCode; Error.captureStackTrace(this, SqliteError); } }; }); // node_modules/@tursodatabase/database-common/dist/types.js var STEP_ROW = 1, STEP_DONE = 2, STEP_IO = 3; // node_modules/@tursodatabase/database-common/dist/compat.js var init_compat = __esm(() => { init_sqlite_error(); }); // node_modules/@tursodatabase/database-common/dist/async-lock.js class AsyncLock { locked; queue; constructor() { this.locked = false; this.queue = []; } async acquire() { if (!this.locked) { this.locked = true; return Promise.resolve(); } else { const block = new Promise((resolve) => { this.queue.push(resolve); }); return block; } } release() { if (this.locked == false) { throw new Error("invalid state: lock was already unlocked"); } const item = this.queue.shift(); if (item != null) { this.locked = true; item(); } else { this.locked = false; } } } // node_modules/@tursodatabase/database-common/dist/promise.js function convertError(err) { if ((err.code ?? "").startsWith(CONVERTIBLE_ERROR_PREFIX)) { return createErrorByName(err.code.substring(CONVERTIBLE_ERROR_PREFIX.length), err.message); } return new SqliteError(err.message, err.code, err.rawCode); } function createErrorByName(name, message) { const ErrorConstructor = convertibleErrorTypes[name]; if (!ErrorConstructor) { throw new Error(`unknown error type ${name} from Turso`); } return new ErrorConstructor(message); } function isQueryOptions(value) { return value != null && typeof value === "object" && !Array.isArray(value) && Object.prototype.hasOwnProperty.call(value, "queryTimeout"); } function splitBindParameters(bindParameters) { if (bindParameters.length === 0) { return { params: undefined, queryOptions: undefined }; } if (bindParameters.length > 1 && isQueryOptions(bindParameters[bindParameters.length - 1])) { return { params: bindParameters.length === 2 ? bindParameters[0] : bindParameters.slice(0, -1), queryOptions: bindParameters[bindParameters.length - 1] }; } return { params: bindParameters.length === 1 ? bindParameters[0] : bindParameters, queryOptions: undefined }; } function toBindArgs(params) { if (params === undefined) { return []; } return [params]; } class Database { name; readonly; open; memory; inTransaction; db; ioStep; execLock; _inTransaction = false; connected = false; constructor(db, ioStep) { this.db = db; this.execLock = new AsyncLock; this.ioStep = ioStep ?? (async () => {}); Object.defineProperties(this, { name: { get: () => this.db.path }, readonly: { get: () => this.db.readonly }, open: { get: () => this.db.open }, memory: { get: () => this.db.memory }, inTransaction: { get: () => this._inTransaction } }); } async connect() { if (this.connected) { return; } await this.db.connectAsync(); this.connected = true; } prepare(sql) { if (this.connected && !this.open) { throw new TypeError("The database connection is not open"); } if (!sql) { throw new RangeError("The supplied SQL string contains no statements"); } try { if (this.connected) { return new Statement(maybeValue(this.db.prepare(sql)), this.db, this.execLock, this.ioStep); } else { return new Statement(maybePromise(() => this.connect().then(() => this.db.prepare(sql))), this.db, this.execLock, this.ioStep); } } catch (err) { throw convertError(err); } } transaction(fn) { if (typeof fn !== "function") throw new TypeError("Expected first argument to be a function"); const db = this; const wrapTxn = (mode) => { return async (...bindParameters) => { await db.exec("BEGIN " + mode); db._inTransaction = true; try { const result = await fn(...bindParameters); await db.exec("COMMIT"); db._inTransaction = false; return result; } catch (err) { await db.exec("ROLLBACK"); db._inTransaction = false; throw err; } }; }; const properties = { default: { value: wrapTxn("") }, deferred: { value: wrapTxn("DEFERRED") }, immediate: { value: wrapTxn("IMMEDIATE") }, exclusive: { value: wrapTxn("EXCLUSIVE") }, database: { value: this, enumerable: true } }; Object.defineProperties(properties.default.value, properties); Object.defineProperties(properties.deferred.value, properties); Object.defineProperties(properties.immediate.value, properties); Object.defineProperties(properties.exclusive.value, properties); return properties.default.value; } async run(sql, ...bindParameters) { const stmt = await this.prepare(sql); try { return await stmt.run(...bindParameters); } finally { await stmt.close(); } } async get(sql, ...bindParameters) { const stmt = await this.prepare(sql); try { return await stmt.get(...bindParameters); } finally { await stmt.close(); } } async all(sql, ...bindParameters) { const stmt = await this.prepare(sql); try { return await stmt.all(...bindParameters); } finally { await stmt.close(); } } async* iterate(sql, ...bindParameters) { const stmt = await this.prepare(sql); try { yield* stmt.iterate(...bindParameters); } finally { await stmt.close(); } } async pragma(source, options) { if (options == null) options = {}; if (typeof source !== "string") throw new TypeError("Expected first argument to be a string"); if (typeof options !== "object") throw new TypeError("Expected second argument to be an options object"); const pragma = `PRAGMA ${source}`; const stmt = await this.prepare(pragma); try { const results = await stmt.all(); return results; } finally { await stmt.close(); } } backup(filename, options) { throw new Error("not implemented"); } serialize(options) { throw new Error("not implemented"); } function(name, options, fn) { throw new Error("not implemented"); } aggregate(name, options) { throw new Error("not implemented"); } table(name, factory) { throw new Error("not implemented"); } loadExtension(path) { throw new Error("not implemented"); } maxWriteReplicationIndex() { throw new Error("not implemented"); } async exec(sql, queryOptions) { if (!this.open) { throw new TypeError("The database connection is not open"); } await this.execLock.acquire(); const exec = this.db.executor(sql, queryOptions); try { while (true) { const stepResult = exec.stepSync(); if (stepResult === STEP_IO) { await this.io(); continue; } if (stepResult === STEP_DONE) { break; } if (stepResult === STEP_ROW) { continue; } } } finally { exec.reset(); this.execLock.release(); } } interrupt() { throw new Error("not implemented"); } defaultSafeIntegers(toggle) { this.db.defaultSafeIntegers(toggle); } async close() { this.db.close(); } async io() { await this.ioStep(); } } function maybePromise(arg) { let lazy = arg; let promise = null; let value = null; return { apply(fn) { let previous = lazy; lazy = async () => { const result = await previous(); fn(result); return result; }; }, async resolve() { if (promise != null) { return await promise; } let valueResolve, valueReject; promise = new Promise((resolve, reject) => { valueResolve = (x) => { resolve(x); value = x; }; valueReject = reject; }); await lazy().then(valueResolve, valueReject); return await promise; }, must() { if (value == null) { throw new Error(`database must be connected before execution the function`); } return value; } }; } function maybeValue(value) { return { apply(fn) { fn(value); }, resolve() { return Promise.resolve(value); }, must() { return value; } }; } class Statement { stmt; db; execLock; ioStep; constructor(stmt, db, execLock, ioStep) { this.stmt = stmt; this.db = db; this.execLock = execLock; this.ioStep = ioStep; } raw(raw) { this.stmt.apply((s) => s.raw(raw)); return this; } pluck(pluckMode) { this.stmt.apply((s) => s.pluck(pluckMode)); return this; } safeIntegers(toggle) { this.stmt.apply((s) => s.safeIntegers(toggle)); return this; } columns() { return this.stmt.must().columns(); } get source() { throw new Error("not implemented"); } get reader() { return this.stmt.must().columns().length > 0; } get database() { return this.db; } async run(...bindParameters) { let stmt = await this.stmt.resolve(); const { params, queryOptions } = splitBindParameters(bindParameters); stmt.setQueryTimeout(queryOptions); bindParams(stmt, toBindArgs(params)); const totalChangesBefore = this.db.totalChanges(); await this.execLock.acquire(); try { while (true) { const stepResult = await stmt.stepSync(); if (stepResult === STEP_IO) { await this.io(); continue; } if (stepResult === STEP_DONE) { break; } if (stepResult === STEP_ROW) { continue; } } const lastInsertRowid = this.db.lastInsertRowid(); const changes = this.db.totalChanges() === totalChangesBefore ? 0 : this.db.changes(); return { changes, lastInsertRowid }; } finally { stmt.reset(); this.execLock.release(); } } async get(...bindParameters) { let stmt = await this.stmt.resolve(); const { params, queryOptions } = splitBindParameters(bindParameters); stmt.setQueryTimeout(queryOptions); bindParams(stmt, toBindArgs(params)); await this.execLock.acquire(); let row = undefined; try { while (true) { const stepResult = await stmt.stepSync(); if (stepResult === STEP_IO) { await this.io(); continue; } if (stepResult === STEP_DONE) { break; } if (stepResult === STEP_ROW && row === undefined) { row = stmt.row(); continue; } } return row; } finally { stmt.reset(); this.execLock.release(); } } async* iterate(...bindParameters) { let stmt = await this.stmt.resolve(); const { params, queryOptions } = splitBindParameters(bindParameters); stmt.setQueryTimeout(queryOptions); bindParams(stmt, toBindArgs(params)); await this.execLock.acquire(); try { while (true) { const stepResult = await stmt.stepSync(); if (stepResult === STEP_IO) { await this.io(); continue; } if (stepResult === STEP_DONE) { break; } if (stepResult === STEP_ROW) { yield stmt.row(); } } } finally { stmt.reset(); this.execLock.release(); } } async all(...bindParameters) { let stmt = await this.stmt.resolve(); const { params, queryOptions } = splitBindParameters(bindParameters); stmt.setQueryTimeout(queryOptions); bindParams(stmt, toBindArgs(params)); const rows = []; await this.execLock.acquire(); try { while (true) { const stepResult = await stmt.stepSync(); if (stepResult === STEP_IO) { await this.io(); continue; } if (stepResult === STEP_DONE) { break; } if (stepResult === STEP_ROW) { rows.push(stmt.row()); } } return rows; } finally { stmt.reset(); this.execLock.release(); } } async io() { await this.ioStep(); } interrupt() { throw new Error("not implemented"); } bind(...bindParameters) { try { bindParams(this.stmt, bindParameters); return this; } catch (err) { throw convertError(err); } } close() { let stmt; try { stmt = this.stmt.must(); } catch (e) { return; } stmt.finalize(); } } var convertibleErrorTypes, CONVERTIBLE_ERROR_PREFIX = "[TURSO_CONVERT_TYPE]"; var init_promise = __esm(() => { init_sqlite_error(); convertibleErrorTypes = { TypeError }; }); // node_modules/@tursodatabase/database-common/dist/index.js var init_dist = __esm(() => { init_compat(); init_promise(); init_sqlite_error(); }); // node_modules/@tursodatabase/sync-common/dist/run.js function trackPromise(p) { let status = { promise: null, finished: false }; status.promise = p.finally(() => status.finished = true); return status; } function timeoutMs(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); } function normalizeUrl(url) { return url.replace(/^libsql:\/\//, "https://"); } async function process2(opts, io, request) { const requestType = request.request(); const completion = request.completion(); if (requestType.type == "Http") { let url = requestType.url; if (typeof opts.url == "function") { url = opts.url(); } else { url = opts.url; } if (url == null) { completion.poison(`url is empty - sync is paused`); return; } url = normalizeUrl(url); try { let headers = typeof opts.headers === "function" ? await opts.headers() : opts.headers; if (requestType.headers != null && requestType.headers.length > 0) { headers = { ...headers }; for (let header of requestType.headers) { headers[header[0]] = header[1]; } } const fetchImpl = opts.fetch ?? fetch; const response = await fetchImpl(`${url}${requestType.path}`, { method: requestType.method, headers, body: requestType.body != null ? new Uint8Array(requestType.body) : null }); completion.status(response.status); const reader = response.body?.getReader(); if (reader == null) { throw new Error("reader is null"); } while (true) { const { done, value } = await reader.read(); if (done) { completion.done(); break; } completion.pushBuffer(value); } } catch (error) { completion.poison(`fetch error: ${error}`); } } else if (requestType.type == "FullRead") { try { const metadata = await io.read(requestType.path); if (metadata != null) { completion.pushBuffer(metadata); } completion.done(); } catch (error) { completion.poison(`metadata read error: ${error}`); } } else if (requestType.type == "FullWrite") { try { await io.write(requestType.path, requestType.content); completion.done(); } catch (error) { completion.poison(`metadata write error: ${error}`); } } else if (requestType.type == "Transform") { if (opts.transform == null) { completion.poison("transform is not set"); return; } const results = []; for (const mutation of requestType.mutations) { const result = opts.transform(mutation); if (result == null) { results.push({ type: "Keep" }); } else if (result.operation == "skip") { results.push({ type: "Skip" }); } else if (result.operation == "rewrite") { results.push({ type: "Rewrite", stmt: result.stmt }); } else { completion.poison("unexpected transform operation"); return; } } completion.pushTransform(results); completion.done(); } } function retryFetch(opts = {}) { const attempts = opts.attempts ?? 3; const baseDelay = opts.delayMs ?? 500; const backoff = opts.backoff ?? 2; const underlying = opts.fetch ?? ((input, init) => fetch(input, init)); if (!Number.isFinite(attempts) || attempts < 1) { throw new Error(`retryFetch: attempts must be a finite integer >= 1, got ${attempts}`); } return async (input, init) => { let lastError = null; let lastResponse = null; let delay = baseDelay; for (let i = 0;i < attempts; i++) { try { const response = await underlying(input, init); if (response.status < 500 && response.status !== 429) { return response; } lastResponse = response; lastError = null; } catch (error) { lastError = error; lastResponse = null; } if (i + 1 < attempts) { await timeoutMs(delay); delay *= backoff; } } if (lastResponse != null) { return lastResponse; } throw lastError ?? new Error("retryFetch: exhausted with no response"); }; } function runner(opts, io, engine) { let tasks = []; return { async wait() { for (let request = engine.protocolIo();request != null; request = engine.protocolIo()) { tasks.push(trackPromise(process2(opts, io, request))); } const tasksRace = tasks.length == 0 ? Promise.resolve() : Promise.race([timeoutMs(opts.preemptionMs), ...tasks.map((t) => t.promise)]); await Promise.all([engine.ioLoopAsync(), tasksRace]); tasks = tasks.filter((t) => !t.finished); engine.protocolIoStep(); } }; } async function run(runner2, generator) { while (true) { const { type, ...rest } = await generator.resumeAsync(null); if (type == "Done") { return null; } if (type == "SyncEngineStats") { return rest; } if (type == "SyncEngineChanges") { return rest.changes; } await runner2.wait(); } } class SyncEngineGuards { waitLock; pushLock; pullLock; checkpointLock; constructor() { this.waitLock = new AsyncLock; this.pushLock = new AsyncLock; this.pullLock = new AsyncLock; this.checkpointLock = new AsyncLock; } async wait(f) { try { await this.waitLock.acquire(); return await f(); } finally { this.waitLock.release(); } } async push(f) { try { await this.pushLock.acquire(); await this.pullLock.acquire(); await this.checkpointLock.acquire(); return await f(); } finally { this.pushLock.release(); this.pullLock.release(); this.checkpointLock.release(); } } async apply(f) { try { await this.waitLock.acquire(); await this.pushLock.acquire(); await this.pullLock.acquire(); await this.checkpointLock.acquire(); return await f(); } finally { this.waitLock.release(); this.pushLock.release(); this.pullLock.release(); this.checkpointLock.release(); } } async checkpoint(f) { try { await this.waitLock.acquire(); await this.pushLock.acquire(); await this.pullLock.acquire(); await this.checkpointLock.acquire(); return await f(); } finally { this.waitLock.release(); this.pushLock.release(); this.pullLock.release(); this.checkpointLock.release(); } } } var init_run = __esm(() => { init_dist(); }); // node_modules/@tursodatabase/serverless/dist/error.js var DatabaseError; var init_error = __esm(() => { DatabaseError = class DatabaseError extends Error { constructor(message, code, rawCode, cause) { super(message); this.name = "DatabaseError"; this.code = code; this.rawCode = rawCode; this.cause = cause; Object.setPrototypeOf(this, DatabaseError.prototype); } }; }); // node_modules/@tursodatabase/serverless/dist/protocol.js function encodeValue(value) { if (value === null || value === undefined) { return { type: "null" }; } if (typeof value === "number") { if (!Number.isFinite(value)) { throw new Error("Only finite numbers (not Infinity or NaN) can be passed as arguments"); } return { type: "float", value }; } if (typeof value === "bigint") { return { type: "integer", value: value.toString() }; } if (typeof value === "boolean") { return { type: "integer", value: value ? "1" : "0" }; } if (typeof value === "string") { return { type: "text", value }; } if (value instanceof ArrayBuffer || value instanceof Uint8Array) { const base64 = btoa(String.fromCharCode(...new Uint8Array(value))); return { type: "blob", base64 }; } return { type: "text", value: String(value) }; } function decodeValue(value, safeIntegers = false) { switch (value.type) { case "null": return null; case "integer": if (safeIntegers) { return BigInt(value.value); } return parseInt(value.value, 10); case "float": return value.value; case "text": return value.value; case "blob": if (value.base64) { const binaryString = atob(value.base64); const bytes = new Uint8Array(binaryString.length); for (let i = 0;i < binaryString.length; i++) { bytes[i] = binaryString.charCodeAt(i); } return Buffer.from(bytes); } return null; default: return null; } } async function executeCursor(url, authToken, request, remoteEncryptionKey) { const headers = { "Content-Type": "application/json" }; if (authToken) { headers["Authorization"] = `Bearer ${authToken}`; } if (remoteEncryptionKey) { headers[ENCRYPTION_KEY_HEADER] = remoteEncryptionKey; } const response = await fetch(`${url}/v3/cursor`, { method: "POST", headers, body: JSON.stringify(request) }); if (!response.ok) { let errorMessage = `HTTP error! status: ${response.status}`; try { const errorBody = await response.text(); const errorData = JSON.parse(errorBody); if (errorData.message) { errorMessage = errorData.message; } } catch {} throw new DatabaseError(errorMessage); } const reader = response.body?.getReader(); if (!reader) { throw new DatabaseError("No response body"); } const decoder = new TextDecoder; let buffer = ""; let cursorResponse; while (!cursorResponse) { const { done, value } = await reader.read(); if (done) break; buffer += decoder.decode(value, { stream: true }); const newlineIndex = buffer.indexOf(` `); if (newlineIndex !== -1) { const line = buffer.slice(0, newlineIndex).trim(); buffer = buffer.slice(newlineIndex + 1); if (line) { cursorResponse = JSON.parse(line); break; } } } if (!cursorResponse) { throw new DatabaseError("No cursor response received"); } async function* parseEntries() { try { let newlineIndex; while ((newlineIndex = buffer.indexOf(` `)) !== -1) { const line = buffer.slice(0, newlineIndex).trim(); buffer = buffer.slice(newlineIndex + 1); if (line) { yield JSON.parse(line); } } while (true) { const { done, value } = await reader.read(); if (done) break; buffer += decoder.decode(value, { stream: true }); while ((newlineIndex = buffer.indexOf(` `)) !== -1) { const line = buffer.slice(0, newlineIndex).trim(); buffer = buffer.slice(newlineIndex + 1); if (line) { yield JSON.parse(line); } } } if (buffer.trim()) { yield JSON.parse(buffer.trim()); } } finally { reader.releaseLock(); } } return { response: cursorResponse, entries: parseEntries() }; } async function executePipeline(url, authToken, request, remoteEncryptionKey) { const headers = { "Content-Type": "application/json" }; if (authToken) { headers["Authorization"] = `Bearer ${authToken}`; } if (remoteEncryptionKey) { headers[ENCRYPTION_KEY_HEADER] = remoteEncryptionKey; } const response = await fetch(`${url}/v3/pipeline`, { method: "POST", headers, body: JSON.stringify(request) }); if (!response.ok) { throw new DatabaseError(`HTTP error! status: ${response.status}`); } return response.json(); } var ENCRYPTION_KEY_HEADER = "x-turso-encryption-key"; var init_protocol = __esm(() => { init_error(); }); // node_modules/@tursodatabase/serverless/dist/session.js function normalizeUrl2(url) { return url.replace(/^libsql:\/\//, "https://"); } function isValidIdentifier(str) { return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(str); } class Session { constructor(config) { this.baton = null; this.config = config; this.baseUrl = normalizeUrl2(config.url); } async describe(sql) { const request = { baton: this.baton, requests: [{ type: "describe", sql }] }; const response = await executePipeline(this.baseUrl, this.config.authToken, request, this.config.remoteEncryptionKey); this.baton = response.baton; if (response.base_url) { this.baseUrl = response.base_url; } if (response.results && response.results[0]) { const result = response.results[0]; if (result.type === "error") { throw new DatabaseError(result.error?.message || "Describe execution failed", result.error?.code); } if (result.response?.type === "describe" && result.response.result) { return result.response.result; } } throw new DatabaseError("Unexpected describe response"); } async execute(sql, args = [], safeIntegers = false) { const { response, entries } = await this.executeRaw(sql, args); const result = await this.processCursorEntries(entries, safeIntegers); return result; } async executeRaw(sql, args = []) { let positionalArgs = []; let namedArgs = []; if (Array.isArray(args)) { positionalArgs = args.map(encodeValue); } else { const keys = Object.keys(args); const isNumericKeys = keys.length > 0 && keys.every((key) => /^\d+$/.test(key)); if (isNumericKeys) { const sortedKeys = keys.sort((a, b) => parseInt(a) - parseInt(b)); const maxIndex = parseInt(sortedKeys[sortedKeys.length - 1]); positionalArgs = new Array(maxIndex); for (const key of sortedKeys) { const index = parseInt(key) - 1; positionalArgs[index] = encodeValue(args[key]); } for (let i = 0;i < positionalArgs.length; i++) { if (positionalArgs[i] === undefined) { positionalArgs[i] = { type: "null" }; } } } else { namedArgs = Object.entries(args).map(([name, value]) => ({ name, value: encodeValue(value) })); } } const request = { baton: this.baton, batch: { steps: [{ stmt: { sql, args: positionalArgs, named_args: namedArgs, want_rows: true } }] } }; const { response, entries } = await executeCursor(this.baseUrl, this.config.authToken, request, this.config.remoteEncryptionKey); this.baton = response.baton; if (response.base_url) { this.baseUrl = response.base_url; } return { response, entries }; } async processCursorEntries(entries, safeIntegers = false) { let columns = []; let columnTypes = []; let rows = []; let rowsAffected = 0; let lastInsertRowid; for await (const entry of entries) { switch (entry.type) { case "step_begin": if (entry.cols) { columns = entry.cols.map((col) => col.name); columnTypes = entry.cols.map((col) => col.decltype || ""); } break; case "row": if (entry.row) { const decodedRow = entry.row.map((value) => decodeValue(value, safeIntegers)); const rowObject = this.createRowObject(decodedRow, columns); rows.push(rowObject); } break; case "step_end": if (entry.affected_row_count !== undefined) { rowsAffected = entry.affected_row_count; } if (entry.last_insert_rowid) { lastInsertRowid = parseInt(entry.last_insert_rowid, 10); } break; case "step_error": case "error": throw new DatabaseError(entry.error?.message || "SQL execution failed", entry.error?.code); } } return { columns, columnTypes, rows, rowsAffected, lastInsertRowid }; } createRowObject(values, columns) { const row = [...values]; columns.forEach((column, index) => { if (column && isValidIdentifier(column)) { Object.defineProperty(row, column, { value: values[index], enumerable: false, writable: false, configurable: true }); } }); return row; } async batch(statements) { const request = { baton: this.baton, batch: { steps: statements.map((sql) => ({ stmt: { sql, args: [], named_args: [], want_rows: false } })) } }; const { response, entries } = await executeCursor(this.baseUrl, this.config.authToken, request, this.config.remoteEncryptionKey); this.baton = response.baton; if (response.base_url) { this.baseUrl = response.base_url; } let totalRowsAffected = 0; let lastInsertRowid; for await (const entry of entries) { switch (entry.type) { case "step_end": if (entry.affected_row_count !== undefined) { totalRowsAffected += entry.affected_row_count; } if (entry.last_insert_rowid) { lastInsertRowid = parseInt(entry.last_insert_rowid, 10); } break; case "step_error": case "error": throw new DatabaseError(entry.error?.message || "Batch execution failed", entry.error?.code); } } return { rowsAffected: totalRowsAffected, lastInsertRowid }; } async sequence(sql) { const request = { baton: this.baton, requests: [{ type: "sequence", sql }] }; const response = await executePipeline(this.baseUrl, this.config.authToken, request, this.config.remoteEncryptionKey); this.baton = response.baton; if (response.base_url) { this.baseUrl = response.base_url; } if (response.results && response.results[0]) { const result = response.results[0]; if (result.type === "error") { throw new DatabaseError(result.error?.message || "Sequence execution failed", result.error?.code); } } } async close() { if (this.baton) { try { const request = { baton: this.baton, requests: [{ type: "close" }] }; await executePipeline(this.baseUrl, this.config.authToken, request, this.config.remoteEncryptionKey); } catch (error) { console.error("Error closing session:", error); } } this.baton = null; this.baseUrl = ""; } } var init_session = __esm(() => { init_protocol(); init_error(); }); // node_modules/@tursodatabase/serverless/dist/statement.js var init_statement = __esm(() => { init_protocol(); init_session(); init_error(); }); // node_modules/@tursodatabase/serverless/dist/connection.js var init_connection = __esm(() => { init_session(); init_statement(); }); // node_modules/@tursodatabase/serverless/dist/index.js var init_dist2 = __esm(() => { init_connection(); init_statement(); init_session(); init_error(); init_protocol(); }); // node_modules/@tursodatabase/sync-common/dist/remote-writer.js class RemoteWriter { session = null; _inRemoteTxn = false; config; constructor(config) { this.config = config; } async resolveAuthToken() { if (typeof this.config.authToken === "function") { return await this.config.authToken(); } return this.config.authToken; } async createSession() { const authToken = await this.resolveAuthToken(); const sessionConfig = { url: this.config.url, authToken, remoteEncryptionKey: this.config.remoteEncryptionKey }; return new Session(sessionConfig); } async execute(sql, args = []) { if (this._inRemoteTxn) { return await this.session.execute(sql, args); } const session = await this.createSession(); try { return await session.execute(sql, args); } finally { await session.close(); } } async sequence(sql) { if (this._inRemoteTxn) { await this.session.sequence(sql); return; } const session = await this.createSession(); try { await session.sequence(sql); } finally { await session.close(); } } async beginTransaction(mode) { this.session = await this.createSession(); await this.session.sequence("BEGIN " + mode); this._inRemoteTxn = true; } async commitTransaction() { if (!this.session) { throw new Error("No active remote transaction"); } try { await this.session.sequence("COMMIT"); } finally { this._inRemoteTxn = false; await this.session.close(); this.session = null; } } async rollbackTransaction() { if (!this.session) { throw new Error("No active remote transaction"); } try { await this.session.sequence("ROLLBACK"); } finally { this._inRemoteTxn = false; await this.session.close(); this.session = null; } } async execRemote(sql, category) { if (category === "begin") { this.session = await this.createSession(); await this.session.sequence(sql); this._inRemoteTxn = true; return { shouldPull: false }; } if (category === "commit") { if (!this.session) throw new Error("No active remote transaction"); try { await this.session.sequence(sql); } finally { this._inRemoteTxn = false; await this.session.close(); this.session = null; } return { shouldPull: true }; } if (category === "rollback") { if (!this.session) throw new Error("No active remote transaction"); try { await this.session.sequence(sql); } finally { this._inRemoteTxn = false; await this.session.close(); this.session = null; } return { shouldPull: false }; } await this.sequence(sql); return { shouldPull: !this._inRemoteTxn }; } get isInTransaction() { return this._inRemoteTxn; } async close() { if (this.session) { try { if (this._inRemoteTxn) { await this.session.sequence("ROLLBACK"); } } catch {} await this.session.close(); this.session = null; this._inRemoteTxn = false; } } } var init_remote_writer = __esm(() => { init_dist2(); }); // node_modules/@tursodatabase/sync-common/dist/remote-write-statement.js class RemoteWriteStatement { localStmt; sql; isStmtReadonly; remoteWriter; pullFn; _boundArgs = []; constructor(localStmt, sql, isStmtReadonly, remoteWriter, pullFn) { this.localStmt = localStmt; this.sql = sql; this.isStmtReadonly = isStmtReadonly; this.remoteWriter = remoteWriter; this.pullFn = pullFn; } shouldGoRemote() { return this.remoteWriter.isInTransaction || !this.isStmtReadonly; } shouldPullAfter() { return !this.isStmtReadonly && !this.remoteWriter.isInTransaction; } raw(toggle) { this.localStmt.raw(toggle); return this; } pluck(toggle) { this.localStmt.pluck(toggle); return this; } safeIntegers(toggle) { this.localStmt.safeIntegers(toggle); return this; } columns() { return this.localStmt.columns(); } get reader() { return this.localStmt.reader; } bind(...bindParameters) { this._boundArgs = flattenArgs(bindParameters); this.localStmt.bind(...bindParameters); return this; } async run(...bindParameters) { if (!this.shouldGoRemote()) { return await this.localStmt.run(...bindParameters); } const args = bindParameters.length > 0 ? flattenArgs(bindParameters) : this._boundArgs; const result = await this.remoteWriter.execute(this.sql, args); if (this.shouldPullAfter()) { await this.pullFn(); } return { changes: result.rowsAffected, lastInsertRowid: result.lastInsertRowid }; } async get(...bindParameters) { if (!this.shouldGoRemote()) { return await this.localStmt.get(...bindParameters); } const args = bindParameters.length > 0 ? flattenArgs(bindParameters) : this._boundArgs; const result = await this.remoteWriter.execute(this.sql, args); if (this.shouldPullAfter()) { await this.pullFn(); } return result.rows.length > 0 ? result.rows[0] : undefined; } async all(...bindParameters) { if (!this.shouldGoRemote()) { return await this.localStmt.all(...bindParameters); } const args = bindParameters.length > 0 ? flattenArgs(bindParameters) : this._boundArgs; const result = await this.remoteWriter.execute(this.sql, args); if (this.shouldPullAfter()) { await this.pullFn(); } return result.rows; } async* iterate(...bindParameters) { if (!this.shouldGoRemote()) { yield* this.localStmt.iterate(...bindParameters); return; } const args = bindParameters.length > 0 ? flattenArgs(bindParameters) : this._boundArgs; const result = await this.remoteWriter.execute(this.sql, args); if (this.shouldPullAfter()) { await this.pullFn(); } for (const row of result.rows) { yield row; } } close() { this.localStmt.close(); } } function flattenArgs(bindParameters) { if (bindParameters.length === 1 && Array.isArray(bindParameters[0])) { return bindParameters[0]; } return bindParameters; } // node_modules/@tursodatabase/sync-common/dist/index.js var init_dist3 = __esm(() => { init_run(); init_remote_writer(); }); // node_modules/@tursodatabase/sync/index.js import { createRequire } from "module"; function requireNative() { if (process.env.NAPI_RS_NATIVE_LIBRARY_PATH) { try { nativeBinding = require2(process.env.NAPI_RS_NATIVE_LIBRARY_PATH); } catch (err) { loadErrors.push(err); } } else if (process.platform === "android") { if (process.arch === "arm64") { try { return require2("./sync.android-arm64.node"); } catch (e) { loadErrors.push(e); } try { const binding = require2("@tursodatabase/sync-android-arm64"); const bindingPackageVersion = require2("@tursodatabase/sync-android-arm64/package.json").version; if (bindingPackageVersion !== "0.6.0-pre.22" && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== "0") { throw new Error(`Native binding package version mismatch, expected 0.6.0-pre.22 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`); } return binding; } catch (e) { loadErrors.push(e); } } else if (process.arch === "arm") { try { return require2("./sync.android-arm-eabi.node"); } catch (e) { loadErrors.push(e); } try { const binding = require2("@tursodatabase/sync-android-arm-eabi"); const bindingPackageVersion = require2("@tursodatabase/sync-android-arm-eabi/package.json").version; if (bindingPackageVersion !== "0.6.0-pre.22" && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== "0") { throw new Error(`Native binding package version mismatch, expected 0.6.0-pre.22 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`); } return binding; } catch (e) { loadErrors.push(e); } } else { loadErrors.push(new Error(`Unsupported architecture on Android ${process.arch}`)); } } else if (process.platform === "win32") { if (process.arch === "x64") { try { return require2("./sync.win32-x64-msvc.node"); } catch (e) { loadErrors.push(e); } try { const binding = require2("@tursodatabase/sync-win32-x64-msvc"); const bindingPackageVersion = require2("@tursodatabase/sync-win32-x64-msvc/package.json").version; if (bindingPackageVersion !== "0.6.0-pre.22" && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== "0") { throw new Error(`Native binding package version mismatch, expected 0.6.0-pre.22 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`); } return binding; } catch (e) { loadErrors.push(e); } } else if (process.arch === "ia32") { try { return require2("./sync.win32-ia32-msvc.node"); } catch (e) { loadErrors.push(e); } try { const binding = require2("@tursodatabase/sync-win32-ia32-msvc"); const bindingPackageVersion = require2("@tursodatabase/sync-win32-ia32-msvc/package.json").version; if (bindingPackageVersion !== "0.6.0-pre.22" && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== "0") { throw new Error(`Native binding package version mismatch, expected 0.6.0-pre.22 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`); } return binding; } catch (e) { loadErrors.push(e); } } else if (process.arch === "arm64") { try { return require2("./sync.win32-arm64-msvc.node"); } catch (e) { loadErrors.push(e); } try { const binding = require2("@tursodatabase/sync-win32-arm64-msvc"); const bindingPackageVersion = require2("@tursodatabase/sync-win32-arm64-msvc/package.json").version; if (bindingPackageVersion !== "0.6.0-pre.22" && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== "0") { throw new Error(`Native binding package version mismatch, expected 0.6.0-pre.22 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`); } return binding; } catch (e) { loadErrors.push(e); } } else { loadErrors.push(new Error(`Unsupported architecture on Windows: ${process.arch}`)); } } else if (process.platform === "darwin") { try { return require2("./sync.darwin-universal.node"); } catch (e) { loadErrors.push(e); } try { const binding = require2("@tursodatabase/sync-darwin-universal"); const bindingPackageVersion = require2("@tursodatabase/sync-darwin-universal/package.json").version; if (bindingPackageVersion !== "0.6.0-pre.22" && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== "0") { throw new Error(`Native binding package version mismatch, expected 0.6.0-pre.22 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`); } return binding; } catch (e) { loadErrors.push(e); } if (process.arch === "x64") { try { return require2("./sync.darwin-x64.node"); } catch (e) { loadErrors.push(e); } try { const binding = require2("@tursodatabase/sync-darwin-x64"); const bindingPackageVersion = require2("@tursodatabase/sync-darwin-x64/package.json").version; if (bindingPackageVersion !== "0.6.0-pre.22" && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== "0") { throw new Error(`Native binding package version mismatch, expected 0.6.0-pre.22 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`); } return binding; } catch (e) { loadErrors.push(e); } } else if (process.arch === "arm64") { try { return require2("./sync.darwin-arm64.node"); } catch (e) { loadErrors.push(e); } try { const binding = require2("@tursodatabase/sync-darwin-arm64"); const bindingPackageVersion = require2("@tursodatabase/sync-darwin-arm64/package.json").version; if (bindingPackageVersion !== "0.6.0-pre.22" && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== "0") { throw new Error(`Native binding package version mismatch, expected 0.6.0-pre.22 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`); } return binding; } catch (e) { loadErrors.push(e); } } else { loadErrors.push(new Error(`Unsupported architecture on macOS: ${process.arch}`)); } } else if (process.platform === "freebsd") { if (process.arch === "x64") { try { return require2("./sync.freebsd-x64.node"); } catch (e) { loadErrors.push(e); } try { const binding = require2("@tursodatabase/sync-freebsd-x64"); const bindingPackageVersion = require2("@tursodatabase/sync-freebsd-x64/package.json").version; if (bindingPackageVersion !== "0.6.0-pre.22" && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== "0") { throw new Error(`Native binding package version mismatch, expected 0.6.0-pre.22 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`); } return binding; } catch (e) { loadErrors.push(e); } } else if (process.arch === "arm64") { try { return require2("./sync.freebsd-arm64.node"); } catch (e) { loadErrors.push(e); } try { const binding = require2("@tursodatabase/sync-freebsd-arm64"); const bindingPackageVersion = require2("@tursodatabase/sync-freebsd-arm64/package.json").version; if (bindingPackageVersion !== "0.6.0-pre.22" && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== "0") { throw new Err