@happyvertical/sql 0.74.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENT.md +33 -0
- package/LICENSE +7 -0
- package/README.md +287 -0
- package/dist/backup/index.d.ts +119 -0
- package/dist/backup/index.d.ts.map +1 -0
- package/dist/backup/index.js +212 -0
- package/dist/backup/index.js.map +1 -0
- package/dist/backup/manifest.d.ts +51 -0
- package/dist/backup/manifest.d.ts.map +1 -0
- package/dist/chunks/duckdb-Djx8WKZE.js +924 -0
- package/dist/chunks/duckdb-Djx8WKZE.js.map +1 -0
- package/dist/chunks/index-DL-5nB7l.js +3468 -0
- package/dist/chunks/index-DL-5nB7l.js.map +1 -0
- package/dist/chunks/postgres-cli-Cr6bBZ3q.js +209 -0
- package/dist/chunks/postgres-cli-Cr6bBZ3q.js.map +1 -0
- package/dist/chunks/sqlite-DkCGjXmu.js +937 -0
- package/dist/chunks/sqlite-DkCGjXmu.js.map +1 -0
- package/dist/chunks/sqlite-native-B6q-0nLs.js +1129 -0
- package/dist/chunks/sqlite-native-B6q-0nLs.js.map +1 -0
- package/dist/cli/claude-context.d.ts +3 -0
- package/dist/cli/claude-context.d.ts.map +1 -0
- package/dist/cli/claude-context.js +21 -0
- package/dist/cli/claude-context.js.map +1 -0
- package/dist/doctor.d.ts +69 -0
- package/dist/doctor.d.ts.map +1 -0
- package/dist/duckdb.d.ts +9 -0
- package/dist/duckdb.d.ts.map +1 -0
- package/dist/index.d.ts +109 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +34 -0
- package/dist/index.js.map +1 -0
- package/dist/json.d.ts +30 -0
- package/dist/json.d.ts.map +1 -0
- package/dist/postgres-cli.d.ts +135 -0
- package/dist/postgres-cli.d.ts.map +1 -0
- package/dist/postgres.d.ts +77 -0
- package/dist/postgres.d.ts.map +1 -0
- package/dist/schema-manager.d.ts +86 -0
- package/dist/schema-manager.d.ts.map +1 -0
- package/dist/shared/alter-utils.d.ts +83 -0
- package/dist/shared/alter-utils.d.ts.map +1 -0
- package/dist/shared/duckdb-schema-utils.d.ts +86 -0
- package/dist/shared/duckdb-schema-utils.d.ts.map +1 -0
- package/dist/shared/types.d.ts +1016 -0
- package/dist/shared/types.d.ts.map +1 -0
- package/dist/shared/utils.d.ts +104 -0
- package/dist/shared/utils.d.ts.map +1 -0
- package/dist/sqlite-native.d.ts +4 -0
- package/dist/sqlite-native.d.ts.map +1 -0
- package/dist/sqlite.d.ts +54 -0
- package/dist/sqlite.d.ts.map +1 -0
- package/metadata.json +38 -0
- package/package.json +84 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite-native-B6q-0nLs.js","sources":["../../src/sqlite-native.ts"],"sourcesContent":["import { createRequire } from 'node:module';\nimport { resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { DatabaseError } from '@happyvertical/utils';\nimport { DatabaseSchemaManager } from './schema-manager.js';\nimport {\n generateAddColumnStatement,\n generateCreateIndexStatement,\n validateColumnName,\n validateIndexName,\n validateTableName,\n} from './shared/alter-utils.js';\nimport type {\n ColumnDefinition,\n ColumnDefinitionWithName,\n DatabaseInterface,\n IndexDefinition,\n NotificationCapabilities,\n NotificationListenOptions,\n NotificationPruneOptions,\n NotificationWaitOptions,\n QueryResult,\n SchemaInitializationOptions,\n SchemaProvider,\n SqliteNotificationCapabilityOptions,\n SqliteVectorCapabilityOptions,\n TableInterface,\n TableSchemaInfo,\n TransactionHandle,\n UpsertOptions,\n VectorCapabilities,\n VectorIndexOptions,\n VectorSearchOptions,\n VectorSearchResult,\n WhereClause,\n} from './shared/types.js';\nimport { resolveSchemas } from './shared/types.js';\nimport { buildWhere, formatDbError } from './shared/utils.js';\nimport type { SqliteOptions } from './sqlite.js';\n\ntype NativeDatabase = any;\ntype NativeStatement = any;\n\nconst nativeMemoryConnectionCache = new Map<string, DatabaseInterface>();\nconst nativePendingConnections = new Map<string, Promise<DatabaseInterface>>();\nconst nativeNullAwareUpsertLocks = new Map<string, Promise<void>>();\nlet nodeSqliteModulePromise: Promise<any> | null = null;\n// sqlite-vector's ESM wrapper uses dynamic require for platform packages.\nconst requireOptionalPackage = createRequire(import.meta.url);\n\ninterface NativeSqliteLocation {\n location: string;\n filePath: string | null;\n isMemory: boolean;\n}\n\ninterface NativeQueryResult {\n rows: Record<string, any>[];\n rowCount: number;\n command?: string;\n fields?: Array<{ name: string }>;\n}\n\nfunction getCapabilityOptions<T extends Record<string, any>>(\n value: boolean | T | undefined,\n): T {\n return typeof value === 'object' && value ? value : ({} as T);\n}\n\nfunction resolveNativeLocation(url = ':memory:'): NativeSqliteLocation {\n if (\n url.startsWith('libsql://') ||\n url.startsWith('http://') ||\n url.startsWith('https://')\n ) {\n throw new DatabaseError(\n 'SQLite native capabilities are only supported for local SQLite databases',\n {\n url,\n hint: \"Use a local file path, 'file:...' URL, or ':memory:' when enabling SQLite capabilities.\",\n },\n );\n }\n\n if (url === ':memory:' || url.startsWith('file::memory:')) {\n return { location: url, filePath: null, isMemory: true };\n }\n\n if (url.startsWith('file://')) {\n const filePath = fileURLToPath(new URL(url));\n return { location: filePath, filePath, isMemory: false };\n }\n\n if (url.startsWith('file:')) {\n const path = url.slice('file:'.length);\n if (!path || path.includes('?')) {\n throw new DatabaseError(\n 'SQLite native capabilities do not support file: URLs with query parameters',\n { url },\n );\n }\n const filePath = resolve(path);\n return { location: filePath, filePath, isMemory: false };\n }\n\n const filePath = resolve(url);\n return { location: filePath, filePath, isMemory: false };\n}\n\nasync function loadNodeSqlite(): Promise<any> {\n nodeSqliteModulePromise ??= importNodeSqlite().catch((error) => {\n nodeSqliteModulePromise = null;\n throw error;\n });\n return nodeSqliteModulePromise;\n}\n\nasync function importNodeSqlite(): Promise<any> {\n const originalEmitWarning = process.emitWarning;\n\n try {\n process.emitWarning = function suppressNodeSqliteExperimentalWarning(\n warning: string | Error,\n ...args: any[]\n ) {\n if (\n args[0] === 'ExperimentalWarning' &&\n String(warning).includes('SQLite is an experimental feature')\n ) {\n return;\n }\n\n return originalEmitWarning.call(process, warning as any, ...args);\n } as typeof process.emitWarning;\n\n const moduleName = 'node:sqlite';\n return (await import(/* @vite-ignore */ moduleName)) as any;\n } catch (error) {\n throw new DatabaseError('Node native SQLite is not available', {\n originalError: formatDbError(error),\n hint: 'SQLite native capabilities require a Node.js runtime with node:sqlite support.',\n });\n } finally {\n process.emitWarning = originalEmitWarning;\n }\n}\n\nasync function loadSqliteVectorExtension(\n database: NativeDatabase,\n): Promise<void> {\n try {\n const moduleName = '@sqliteai/sqlite-vector';\n const module = requireOptionalPackage(moduleName) as any;\n const getExtensionPath =\n module.getExtensionPath ?? module.default?.getExtensionPath;\n\n if (typeof getExtensionPath !== 'function') {\n throw new Error('getExtensionPath export was not found');\n }\n\n database.enableLoadExtension(true);\n database.loadExtension(getExtensionPath());\n } catch (error) {\n throw new DatabaseError(\n 'Failed to load optional SQLite vector capability: install @sqliteai/sqlite-vector',\n {\n packageName: '@sqliteai/sqlite-vector',\n originalError: formatDbError(error),\n hint: 'Install @sqliteai/sqlite-vector to use SQLite vector capabilities.',\n },\n );\n } finally {\n try {\n database.enableLoadExtension(false);\n } catch (_error) {\n // Leave the original extension-loading failure intact.\n }\n }\n}\n\nasync function openHonkerDatabase(\n filePath: string,\n options: SqliteNotificationCapabilityOptions,\n): Promise<any> {\n try {\n const moduleName = '@russellthehippo/honker-node';\n const module = requireOptionalPackage(moduleName) as any;\n const open = module.open ?? module.default?.open;\n\n if (typeof open !== 'function') {\n throw new Error('open export was not found');\n }\n\n return open(filePath, options.maxReaders, options.watcherBackend);\n } catch (error) {\n throw new DatabaseError(\n 'Failed to load optional SQLite notification capability: install @russellthehippo/honker-node',\n {\n packageName: '@russellthehippo/honker-node',\n originalError: formatDbError(error),\n hint: 'Install @russellthehippo/honker-node to use SQLite notification capabilities.',\n },\n );\n }\n}\n\nfunction toPlainRow(row: Record<string, any>): Record<string, any> {\n return Object.fromEntries(Object.entries(row));\n}\n\nfunction getErrorMessage(error: unknown): string | undefined {\n return error instanceof Error ? error.message : undefined;\n}\n\nfunction firstSqlToken(sql: string): string {\n return sql.trim().split(/\\s+/)[0]?.toUpperCase() ?? '';\n}\n\nfunction normalizeNativeQuery(\n sql: string,\n values: any[],\n): { sql: string; args: any[] } {\n const flatArgs = Array.isArray(values[0]) ? values[0] : values;\n const parameterIndexes = Array.from(sql.matchAll(/\\$(\\d+)/g)).map((match) =>\n Number(match[1]),\n );\n\n if (parameterIndexes.length === 0) {\n return { sql, args: flatArgs };\n }\n\n const args = parameterIndexes.map((index) => flatArgs[index - 1]);\n return { sql: sql.replace(/\\$(\\d+)/g, '?'), args };\n}\n\nfunction executeNativeQuery(\n database: NativeDatabase,\n sql: string,\n args: any[] = [],\n): NativeQueryResult {\n const statement: NativeStatement = database.prepare(sql);\n const columns = statement.columns();\n\n if (columns.length > 0) {\n const rows = statement.all(...args).map(toPlainRow);\n return {\n rows,\n rowCount: rows.length,\n command: firstSqlToken(sql),\n fields: columns.map((column: { name: string }) => ({\n name: column.name,\n })),\n };\n }\n\n const result = statement.run(...args);\n return {\n rows: [],\n rowCount: Number(result?.changes ?? 0),\n command: firstSqlToken(sql),\n fields: [],\n };\n}\n\nfunction createNativeTablesFromSchemas(\n database: NativeDatabase,\n schemas: Record<string, SchemaProvider>,\n): void {\n for (const [tableName, schema] of Object.entries(schemas)) {\n try {\n const result = executeNativeQuery(\n database,\n \"SELECT name FROM sqlite_master WHERE type='table' AND name=?\",\n [tableName],\n );\n\n if (result.rows.length > 0) {\n continue;\n }\n\n database.exec(schema.ddl);\n\n for (const indexSql of schema.indexes ?? []) {\n try {\n database.exec(indexSql);\n } catch (error) {\n console.warn(\n `[sqlite] Failed to create index for ${tableName}: ${formatDbError(error)}`,\n );\n }\n }\n\n for (const triggerSql of schema.triggers ?? []) {\n try {\n database.exec(triggerSql);\n } catch (error) {\n console.warn(\n `[sqlite] Failed to create trigger for ${tableName}: ${formatDbError(error)}`,\n );\n }\n }\n } catch (error) {\n throw new DatabaseError(\n `Failed to create table ${tableName} from schema`,\n {\n tableName,\n schema,\n originalError: formatDbError(error),\n },\n );\n }\n }\n}\n\nfunction quoteIdentifier(identifier: string): string {\n return `\"${identifier.replace(/\"/g, '\"\"')}\"`;\n}\n\nfunction buildQuestionWhere(where: WhereClause, startIndex = 1) {\n const built = buildWhere(where, startIndex, 'sqlite');\n return {\n sql: built.sql.replace(/\\$(\\d+)/g, '?'),\n values: built.values,\n };\n}\n\nfunction serializeValue(value: any): any {\n if (value === null || value === undefined) {\n return value;\n }\n if (value instanceof Date) {\n return value.toISOString();\n }\n if (typeof value === 'object') {\n return JSON.stringify(value);\n }\n return value;\n}\n\nfunction serializeRecord(record: Record<string, any>): Record<string, any> {\n const serialized: Record<string, any> = {};\n for (const [key, value] of Object.entries(record)) {\n if (value === undefined) {\n continue;\n }\n serialized[key] = serializeValue(value);\n }\n return serialized;\n}\n\nasync function withNativeNullAwareUpsertLock<T>(\n lockKey: string,\n callback: () => Promise<T>,\n): Promise<T> {\n const previous = nativeNullAwareUpsertLocks.get(lockKey) ?? Promise.resolve();\n let release: () => void = () => {};\n const current = new Promise<void>((resolve) => {\n release = resolve;\n });\n const next = previous.catch(() => {}).then(() => current);\n\n nativeNullAwareUpsertLocks.set(lockKey, next);\n await previous.catch(() => {});\n\n try {\n return await callback();\n } finally {\n release();\n if (nativeNullAwareUpsertLocks.get(lockKey) === next) {\n nativeNullAwareUpsertLocks.delete(lockKey);\n }\n }\n}\n\nfunction sqliteVectorDistance(metric: 'cosine' | 'l2' | 'ip'): string {\n switch (metric) {\n case 'l2':\n return 'L2';\n case 'ip':\n return 'DOT';\n default:\n return 'COSINE';\n }\n}\n\nfunction sqliteVectorQuantization(\n options: SqliteVectorCapabilityOptions,\n): string {\n const parts: string[] = [];\n\n switch (options.quantization ?? 'turbo4') {\n case 'turbo2':\n parts.push('qtype=TURBO,qbits=2');\n break;\n case 'turbo3':\n parts.push('qtype=TURBO,qbits=3');\n break;\n case 'turbo4':\n parts.push('qtype=TURBO,qbits=4');\n break;\n case 'uint8':\n parts.push('qtype=UINT8');\n break;\n case 'int8':\n parts.push('qtype=INT8');\n break;\n case '1bit':\n parts.push('qtype=1BIT');\n break;\n }\n\n if (options.maxMemory) {\n parts.push(`max_memory=${options.maxMemory}`);\n }\n\n return parts.join(',');\n}\n\nfunction createNotificationCapabilities(\n honkerDb: any,\n closeables: Set<{ close?: () => void }>,\n): NotificationCapabilities {\n return {\n async notify(channel: string, payload: any): Promise<number> {\n return Number(honkerDb.notify(channel, payload));\n },\n\n listen(channel: string, options?: NotificationListenOptions) {\n const listener = honkerDb.listen(channel, {\n fallbackPollS:\n options?.fallbackPollMs === null\n ? null\n : options?.fallbackPollMs !== undefined\n ? options.fallbackPollMs / 1000\n : undefined,\n });\n closeables.add(listener);\n return listener;\n },\n\n async waitForUpdate(options?: NotificationWaitOptions): Promise<boolean> {\n const updateEvents = honkerDb.updateEvents();\n closeables.add(updateEvents);\n let timeout: NodeJS.Timeout | undefined;\n let removeAbortListener: (() => void) | undefined;\n\n try {\n if (options?.signal?.aborted) {\n return false;\n }\n\n const updatePromise = updateEvents.next().then(\n () => true,\n () => false,\n );\n const races: Array<Promise<boolean>> = [updatePromise];\n\n if (options?.timeoutMs !== undefined) {\n const timeoutMs = options.timeoutMs;\n races.push(\n new Promise((resolve) => {\n timeout = setTimeout(\n () => resolve(false),\n Math.max(0, timeoutMs),\n );\n }),\n );\n }\n\n if (options?.signal) {\n races.push(\n new Promise((resolve) => {\n const onAbort = () => resolve(false);\n options.signal?.addEventListener('abort', onAbort, {\n once: true,\n });\n removeAbortListener = () =>\n options.signal?.removeEventListener('abort', onAbort);\n }),\n );\n }\n\n return await Promise.race(races);\n } finally {\n if (timeout) {\n clearTimeout(timeout);\n }\n removeAbortListener?.();\n closeables.delete(updateEvents);\n updateEvents.close?.();\n }\n },\n\n async prune(options?: NotificationPruneOptions): Promise<number> {\n return Number(\n honkerDb.pruneNotifications(options?.olderThanS, options?.maxKeep),\n );\n },\n };\n}\n\nfunction createVectorCapabilities(\n database: NativeDatabase,\n options: SqliteVectorCapabilityOptions,\n): VectorCapabilities {\n const initialized = new Map<\n string,\n { dimensions: number; metric: 'cosine' | 'l2' | 'ip' }\n >();\n const indexed = new Map<\n string,\n { metric: 'cosine' | 'l2' | 'ip'; options: SqliteVectorCapabilityOptions }\n >();\n\n const keyFor = (table: string, column: string) => `${table}.${column}`;\n\n const columnExists = (table: string, column: string): boolean => {\n const rows = database\n .prepare(`PRAGMA table_info(${quoteIdentifier(table)})`)\n .all()\n .map(toPlainRow);\n return rows.some((row: Record<string, any>) => row.name === column);\n };\n\n const ensureInitialized = (\n table: string,\n column: string,\n dimensions: number,\n metric: 'cosine' | 'l2' | 'ip' = 'cosine',\n ): void => {\n if (!Number.isInteger(dimensions) || dimensions <= 0) {\n throw new DatabaseError('Vector dimensions must be a positive integer', {\n dimensions,\n });\n }\n\n validateTableName(table);\n validateColumnName(column);\n\n executeNativeQuery(database, 'SELECT vector_init(?, ?, ?)', [\n table,\n column,\n `dimension=${dimensions},type=FLOAT32,distance=${sqliteVectorDistance(metric)}`,\n ]);\n initialized.set(keyFor(table, column), { dimensions, metric });\n };\n\n const quantize = (\n table: string,\n column: string,\n vectorOptions: SqliteVectorCapabilityOptions,\n ): void => {\n const quantizationOptions = sqliteVectorQuantization(vectorOptions);\n if (quantizationOptions) {\n executeNativeQuery(database, 'SELECT vector_quantize(?, ?, ?)', [\n table,\n column,\n quantizationOptions,\n ]);\n } else {\n executeNativeQuery(database, 'SELECT vector_quantize(?, ?)', [\n table,\n column,\n ]);\n }\n\n if (vectorOptions.preload) {\n executeNativeQuery(database, 'SELECT vector_quantize_preload(?, ?)', [\n table,\n column,\n ]);\n }\n };\n\n return {\n async ensureColumn(\n table: string,\n column: string,\n dimensions: number,\n ): Promise<void> {\n validateTableName(table);\n validateColumnName(column);\n\n try {\n if (!columnExists(table, column)) {\n executeNativeQuery(\n database,\n `ALTER TABLE ${quoteIdentifier(table)} ADD COLUMN ${quoteIdentifier(column)} BLOB`,\n );\n }\n ensureInitialized(table, column, dimensions, 'cosine');\n } catch (error) {\n throw new DatabaseError('Failed to ensure SQLite vector column', {\n table,\n column,\n dimensions,\n originalError: formatDbError(error),\n });\n }\n },\n\n async ensureIndex(\n table: string,\n column: string,\n indexOptions?: VectorIndexOptions,\n ): Promise<void> {\n validateTableName(table);\n validateColumnName(column);\n\n const key = keyFor(table, column);\n const dimensions =\n indexOptions?.dimensions ?? initialized.get(key)?.dimensions;\n if (!dimensions) {\n throw new DatabaseError(\n 'SQLite vector index creation requires dimensions',\n {\n table,\n column,\n hint: 'Call ensureColumn(table, column, dimensions) first or pass dimensions to ensureIndex().',\n },\n );\n }\n\n const metric = indexOptions?.metric ?? 'cosine';\n\n try {\n ensureInitialized(table, column, dimensions, metric);\n const vectorOptions = { ...options };\n quantize(table, column, vectorOptions);\n indexed.set(key, { metric, options: vectorOptions });\n } catch (error) {\n throw new DatabaseError('Failed to ensure SQLite vector index', {\n table,\n column,\n originalError: formatDbError(error),\n });\n }\n },\n\n async upsertVector(\n table: string,\n where: Record<string, any>,\n column: string,\n embedding: number[],\n ): Promise<void> {\n validateTableName(table);\n validateColumnName(column);\n\n const key = keyFor(table, column);\n const dimensions = initialized.get(key)?.dimensions ?? embedding.length;\n const { sql: whereClause, values } = buildQuestionWhere(where);\n\n if (!whereClause) {\n throw new DatabaseError(\n 'SQLite vector update requires at least one WHERE condition',\n { table, column },\n );\n }\n\n try {\n ensureInitialized(\n table,\n column,\n dimensions,\n initialized.get(key)?.metric ?? 'cosine',\n );\n executeNativeQuery(\n database,\n `UPDATE ${quoteIdentifier(table)} SET ${quoteIdentifier(column)} = vector_as_f32(?) ${whereClause}`,\n [JSON.stringify(embedding), ...values],\n );\n\n const indexState = indexed.get(key);\n if (indexState) {\n quantize(table, column, indexState.options);\n }\n } catch (error) {\n throw new DatabaseError('Failed to upsert SQLite vector', {\n table,\n column,\n where,\n originalError: formatDbError(error),\n });\n }\n },\n\n async search(\n table: string,\n column: string,\n embedding: number[],\n searchOptions?: VectorSearchOptions,\n ): Promise<VectorSearchResult[]> {\n validateTableName(table);\n validateColumnName(column);\n\n const key = keyFor(table, column);\n const metric = searchOptions?.metric ?? 'cosine';\n const limit = searchOptions?.limit ?? 10;\n const limitArg = BigInt(limit);\n const dimensions = initialized.get(key)?.dimensions ?? embedding.length;\n const indexState = indexed.get(key);\n const useQuantizedScan = indexState?.metric === metric;\n const scanFunction = useQuantizedScan\n ? 'vector_quantize_scan'\n : 'vector_full_scan';\n const convertedWhere = searchOptions?.where\n ? searchOptions.where.replace(/\\$(\\d+)/g, '?')\n : '';\n const whereParams = searchOptions?.params ?? [];\n\n try {\n ensureInitialized(table, column, dimensions, metric);\n\n const rows = convertedWhere\n ? executeNativeQuery(\n database,\n `SELECT base.*, base.rowid AS __sqlite_rowid, vec.distance\n FROM ${scanFunction}(?, ?, vector_as_f32(?)) AS vec\n JOIN ${quoteIdentifier(table)} AS base ON base.rowid = vec.rowid\n WHERE (${convertedWhere})\n ORDER BY vec.distance\n LIMIT ?`,\n [\n table,\n column,\n JSON.stringify(embedding),\n ...whereParams,\n limitArg,\n ],\n ).rows\n : executeNativeQuery(\n database,\n `SELECT base.*, base.rowid AS __sqlite_rowid, vec.distance\n FROM ${scanFunction}(?, ?, vector_as_f32(?), ?) AS vec\n JOIN ${quoteIdentifier(table)} AS base ON base.rowid = vec.rowid\n ORDER BY vec.distance`,\n [table, column, JSON.stringify(embedding), limitArg],\n ).rows;\n\n return rows.map((row) => {\n const { __sqlite_rowid: rowid, ...result } = row;\n return {\n ...result,\n id: String(result.id ?? rowid),\n distance: Number(row.distance),\n };\n });\n } catch (error) {\n throw new DatabaseError('Failed to execute SQLite vector search', {\n table,\n column,\n metric,\n limit,\n originalError: formatDbError(error),\n });\n }\n },\n };\n}\n\nexport async function getNativeSqliteDatabase(\n options: SqliteOptions = {},\n): Promise<DatabaseInterface> {\n const url = options.url || ':memory:';\n\n if (options.dbid) {\n const cached = nativeMemoryConnectionCache.get(options.dbid);\n if (cached) {\n return cached;\n }\n\n const pending = nativePendingConnections.get(options.dbid);\n if (pending) {\n return pending;\n }\n }\n\n const connectionPromise = createNativeSqliteDatabase(options, url);\n\n if (options.dbid) {\n nativePendingConnections.set(options.dbid, connectionPromise);\n }\n\n try {\n const db = await connectionPromise;\n if (options.dbid) {\n nativeMemoryConnectionCache.set(options.dbid, db);\n }\n return db;\n } finally {\n if (options.dbid) {\n nativePendingConnections.delete(options.dbid);\n }\n }\n}\n\nasync function createNativeSqliteDatabase(\n options: SqliteOptions,\n url: string,\n): Promise<DatabaseInterface> {\n const location = resolveNativeLocation(url);\n const notificationsOptions = getCapabilityOptions(\n options.capabilities?.notifications,\n );\n const vectorOptions = getCapabilityOptions(options.capabilities?.vector);\n const wantsNotifications = Boolean(options.capabilities?.notifications);\n const wantsVector = Boolean(options.capabilities?.vector);\n\n if (wantsNotifications && location.isMemory) {\n throw new DatabaseError(\n 'SQLite notification capabilities require a file-backed database',\n {\n url,\n hint: 'Use a temporary file-backed .db for development and tests that need notifications.',\n },\n );\n }\n\n const { DatabaseSync } = await loadNodeSqlite();\n const database = new DatabaseSync(location.location, {\n allowExtension: wantsVector,\n });\n\n try {\n if (wantsVector) {\n await loadSqliteVectorExtension(database);\n }\n\n const honkerDb =\n wantsNotifications && location.filePath\n ? await openHonkerDatabase(location.filePath, notificationsOptions)\n : null;\n const notificationCloseables = new Set<{ close?: () => void }>();\n let closed = false;\n\n const vectorCapabilities = wantsVector\n ? createVectorCapabilities(database, vectorOptions)\n : undefined;\n const notificationCapabilities = honkerDb\n ? createNotificationCapabilities(honkerDb, notificationCloseables)\n : undefined;\n\n const query = async (\n sql: string,\n ...values: any[]\n ): Promise<{ rows: Record<string, any>[]; rowCount: number }> => {\n const normalized = normalizeNativeQuery(sql, values);\n try {\n const result = executeNativeQuery(\n database,\n normalized.sql,\n normalized.args,\n );\n return { rows: result.rows, rowCount: result.rowCount };\n } catch (error) {\n throw new DatabaseError('Failed to execute raw query', {\n sql: normalized.sql,\n values: normalized.args,\n originalError: formatDbError(error),\n });\n }\n };\n\n const parseTemplate = (strings: TemplateStringsArray, ...vars: any[]) => {\n let sql = strings[0];\n const values = [];\n for (let i = 0; i < vars.length; i++) {\n values.push(vars[i]);\n sql += `?${strings[i + 1]}`;\n }\n return { sql, values };\n };\n\n const insert = async (\n table: string,\n data: Record<string, any> | Record<string, any>[],\n ): Promise<QueryResult> => {\n const records = (Array.isArray(data) ? data : [data]).map(\n serializeRecord,\n );\n const keys = Object.keys(records[0]);\n const placeholders = records\n .map(() => `(${keys.map(() => '?').join(', ')})`)\n .join(', ');\n const values = records.flatMap((record) =>\n keys.map((key) => record[key]),\n );\n const sql = `INSERT INTO ${table} (${keys.join(', ')}) VALUES ${placeholders}`;\n\n try {\n const result = executeNativeQuery(database, sql, values);\n return { operation: 'insert', affected: result.rowCount };\n } catch (error) {\n throw new DatabaseError('Failed to insert records into table', {\n table,\n sql,\n values,\n originalError: formatDbError(error),\n });\n }\n };\n\n const get = async (\n table: string,\n where: WhereClause,\n ): Promise<Record<string, any> | null> => {\n const { sql: whereClause, values } = buildQuestionWhere(where);\n if (!whereClause) {\n throw new DatabaseError(\n 'GET requires at least one WHERE condition to prevent returning an arbitrary record',\n { table },\n );\n }\n\n const sql = `SELECT * FROM ${table} ${whereClause}`;\n try {\n const result = executeNativeQuery(database, sql, values);\n return result.rows[0] || null;\n } catch (error) {\n throw new DatabaseError('Failed to retrieve record from table', {\n table,\n sql,\n values,\n originalError: formatDbError(error),\n });\n }\n };\n\n const list = async (\n table: string,\n where: WhereClause,\n ): Promise<Record<string, any>[]> => {\n const { sql: whereClause, values } = buildQuestionWhere(where);\n const sql = `SELECT * FROM ${table} ${whereClause}`;\n try {\n return executeNativeQuery(database, sql, values).rows;\n } catch (error) {\n throw new DatabaseError('Failed to list records from table', {\n table,\n sql,\n values,\n originalError: formatDbError(error),\n });\n }\n };\n\n const update = async (\n table: string,\n where: WhereClause,\n data: Record<string, any>,\n ): Promise<QueryResult> => {\n const serializedData = serializeRecord(data);\n const keys = Object.keys(serializedData);\n const values = Object.values(serializedData);\n const setClause = keys.map((key) => `${key} = ?`).join(', ');\n const { sql: whereClause, values: whereValues } =\n buildQuestionWhere(where);\n\n if (!whereClause) {\n throw new DatabaseError(\n 'UPDATE requires at least one WHERE condition to prevent accidental update of all records',\n { table },\n );\n }\n\n const sql = `UPDATE ${table} SET ${setClause} ${whereClause}`;\n try {\n const result = executeNativeQuery(database, sql, [\n ...values,\n ...whereValues,\n ]);\n return { operation: 'update', affected: result.rowCount };\n } catch (error) {\n throw new DatabaseError('Failed to update records in table', {\n table,\n sql,\n values: [...values, ...whereValues],\n originalError: formatDbError(error),\n });\n }\n };\n\n const hasNullConflictValue = (\n conflictColumns: string[],\n data: Record<string, any>,\n ): boolean => conflictColumns.some((column) => data[column] === null);\n\n const validateUpsertConflictColumns = (\n table: string,\n conflictColumns: string[],\n serializedData: Record<string, any>,\n ): void => {\n const missingColumns = conflictColumns.filter(\n (column) => !(column in serializedData),\n );\n\n if (missingColumns.length > 0) {\n throw new DatabaseError('Conflict columns missing from data', {\n table,\n conflictColumns,\n missingColumns,\n availableColumns: Object.keys(serializedData),\n hint: 'All columns specified in ON CONFLICT must be present in the data being inserted. Undefined values are filtered out during serialization - consider using null or an empty string instead.',\n });\n }\n };\n\n const executeStandardUpsert = (\n table: string,\n conflictColumns: string[],\n serializedData: Record<string, any>,\n ): QueryResult => {\n const keys = Object.keys(serializedData);\n const values = Object.values(serializedData);\n const placeholders = keys.map(() => '?').join(', ');\n const updateSet = keys\n .map((key) => `${key} = excluded.${key}`)\n .join(', ');\n const conflict = conflictColumns.join(', ');\n const sql = `INSERT INTO ${table} (${keys.join(', ')}) VALUES (${placeholders}) ON CONFLICT(${conflict}) DO UPDATE SET ${updateSet}`;\n const result = executeNativeQuery(database, sql, values);\n return { operation: 'upsert', affected: result.rowCount };\n };\n\n const executeNullAwareUpsertAttempt = (\n table: string,\n conflictColumns: string[],\n serializedData: Record<string, any>,\n ): QueryResult => {\n const keys = Object.keys(serializedData);\n const values = Object.values(serializedData);\n const updateSet = keys.map((key) => `${key} = ?`).join(', ');\n const whereClause = conflictColumns\n .map((column) => `${column} IS ?`)\n .join(' AND ');\n const whereValues = conflictColumns.map(\n (column) => serializedData[column],\n );\n\n const updateResult = executeNativeQuery(\n database,\n `UPDATE ${table} SET ${updateSet} WHERE ${whereClause}`,\n [...values, ...whereValues],\n );\n\n if (updateResult.rowCount > 0) {\n return { operation: 'upsert', affected: updateResult.rowCount };\n }\n\n const placeholders = keys.map(() => '?').join(', ');\n const insertResult = executeNativeQuery(\n database,\n `INSERT INTO ${table} (${keys.join(', ')}) VALUES (${placeholders})`,\n values,\n );\n\n return { operation: 'upsert', affected: insertResult.rowCount };\n };\n\n const executeUpsert = async (\n table: string,\n conflictColumns: string[],\n data: Record<string, any>,\n upsertOptions: UpsertOptions | undefined,\n acquireTransaction: boolean,\n ): Promise<QueryResult> => {\n const serializedData = serializeRecord(data);\n validateUpsertConflictColumns(table, conflictColumns, serializedData);\n\n if (\n upsertOptions?.nullsDistinct ||\n !hasNullConflictValue(conflictColumns, serializedData)\n ) {\n return executeStandardUpsert(table, conflictColumns, serializedData);\n }\n\n if (!acquireTransaction) {\n return executeNullAwareUpsertAttempt(\n table,\n conflictColumns,\n serializedData,\n );\n }\n\n const lockKey = `${location.location}:${table}:${conflictColumns\n .map((column) => `${column}:${JSON.stringify(serializedData[column])}`)\n .join('|')}`;\n\n return withNativeNullAwareUpsertLock(lockKey, async () => {\n try {\n database.exec('BEGIN IMMEDIATE');\n const result = executeNullAwareUpsertAttempt(\n table,\n conflictColumns,\n serializedData,\n );\n database.exec('COMMIT');\n return result;\n } catch (error) {\n try {\n database.exec('ROLLBACK');\n } catch (_rollbackError) {\n // Preserve the original failure.\n }\n throw error;\n }\n });\n };\n\n const upsert = async (\n table: string,\n conflictColumns: string[],\n data: Record<string, any>,\n upsertOptions?: UpsertOptions,\n ): Promise<QueryResult> => {\n try {\n return await executeUpsert(\n table,\n conflictColumns,\n data,\n upsertOptions,\n true,\n );\n } catch (error) {\n if (getErrorMessage(error) === 'Conflict columns missing from data') {\n throw error;\n }\n throw new DatabaseError('Failed to upsert record into table', {\n table,\n values: data,\n conflictColumns,\n originalError: formatDbError(error),\n });\n }\n };\n\n const upsertInCurrentTransaction = (\n table: string,\n conflictColumns: string[],\n data: Record<string, any>,\n upsertOptions?: UpsertOptions,\n ): Promise<QueryResult> =>\n executeUpsert(table, conflictColumns, data, upsertOptions, false);\n\n const getOrInsert = async (\n table: string,\n where: WhereClause,\n data: Record<string, any>,\n ): Promise<Record<string, any>> => {\n const existing = await get(table, where);\n if (existing) return existing;\n await insert(table, data);\n const inserted = await get(table, where);\n if (!inserted) {\n throw new DatabaseError('Failed to insert and retrieve record', {\n table,\n where,\n data,\n });\n }\n return inserted;\n };\n\n const deleteRecords = async (\n table: string,\n where: WhereClause,\n ): Promise<QueryResult> => {\n validateTableName(table);\n const { sql: whereClause, values } = buildQuestionWhere(where);\n if (!whereClause) {\n throw new DatabaseError(\n 'DELETE requires at least one WHERE condition to prevent accidental deletion of all records',\n { table },\n );\n }\n\n try {\n const result = executeNativeQuery(\n database,\n `DELETE FROM ${table} ${whereClause}`,\n values,\n );\n return { operation: 'delete', affected: result.rowCount };\n } catch (error) {\n throw new DatabaseError('Failed to delete records from table', {\n table,\n where,\n originalError: formatDbError(error),\n });\n }\n };\n\n const count = async (\n table: string,\n where?: WhereClause,\n ): Promise<number> => {\n validateTableName(table);\n if (\n !where ||\n (typeof where === 'object' && Object.keys(where).length === 0)\n ) {\n const result = executeNativeQuery(\n database,\n `SELECT COUNT(*) as count FROM ${table}`,\n );\n return Number(result.rows[0]?.count) || 0;\n }\n\n const { sql: whereClause, values } = buildQuestionWhere(where);\n const result = executeNativeQuery(\n database,\n `SELECT COUNT(*) as count FROM ${table} ${whereClause}`,\n values,\n );\n return Number(result.rows[0]?.count) || 0;\n };\n\n const tableExists = async (tableName: string): Promise<boolean> => {\n const result = executeNativeQuery(\n database,\n \"SELECT name FROM sqlite_master WHERE type='table' AND name=?\",\n [tableName],\n );\n return result.rows.length > 0;\n };\n\n const syncSchema = async (schema: string): Promise<void> => {\n const commands = schema\n .replace(/\\s+/g, ' ')\n .replace(/DEFAULT CAST\\(([^)]+)\\s+AS\\s+\\w+\\)/gi, 'DEFAULT $1')\n .trim()\n .split(';')\n .map((command) => command.trim())\n .filter((command) => command.length > 0);\n\n for (const command of commands) {\n database.exec(command);\n }\n };\n\n const many = async (\n strings: TemplateStringsArray,\n ...vars: any[]\n ): Promise<Record<string, any>[]> => {\n const { sql, values } = parseTemplate(strings, ...vars);\n try {\n return executeNativeQuery(database, sql, values).rows;\n } catch (error) {\n throw new DatabaseError('Failed to execute many query', {\n sql,\n values,\n originalError: formatDbError(error),\n });\n }\n };\n\n const single = async (\n strings: TemplateStringsArray,\n ...vars: any[]\n ): Promise<Record<string, any> | null> => {\n const { sql, values } = parseTemplate(strings, ...vars);\n try {\n return executeNativeQuery(database, sql, values).rows[0] || null;\n } catch (error) {\n throw new DatabaseError('Failed to execute single query', {\n sql,\n values,\n originalError: formatDbError(error),\n });\n }\n };\n\n const pluck = async (\n strings: TemplateStringsArray,\n ...vars: any[]\n ): Promise<any> => {\n const { sql, values } = parseTemplate(strings, ...vars);\n try {\n const row = executeNativeQuery(database, sql, values).rows[0];\n return row ? Object.values(row)[0] : null;\n } catch (error) {\n throw new DatabaseError('Failed to execute pluck query', {\n sql,\n values,\n originalError: formatDbError(error),\n });\n }\n };\n\n const execute = async (\n strings: TemplateStringsArray,\n ...vars: any[]\n ): Promise<void> => {\n const { sql, values } = parseTemplate(strings, ...vars);\n try {\n if (values.length === 0) {\n database.exec(sql);\n return;\n }\n executeNativeQuery(database, sql, values);\n } catch (error) {\n throw new DatabaseError('Failed to execute query', {\n sql,\n values,\n originalError: formatDbError(error),\n });\n }\n };\n\n const oo = many;\n const oO = single;\n const ox = pluck;\n const xx = execute;\n\n const table = (tableName: string): TableInterface => ({\n insert: (data) => insert(tableName, data),\n get: (where) => get(tableName, where),\n list: (where) => list(tableName, where),\n });\n\n const transaction = async <T>(\n callback: (tx: DatabaseInterface) => Promise<T>,\n ): Promise<T> => {\n try {\n database.exec('BEGIN TRANSACTION');\n const txDb = buildDatabaseInterface(upsertInCurrentTransaction);\n const result = await callback(txDb);\n database.exec('COMMIT');\n return result;\n } catch (error) {\n database.exec('ROLLBACK');\n throw error;\n }\n };\n\n const beginTransaction = async (): Promise<TransactionHandle> => {\n database.exec('BEGIN TRANSACTION');\n let active = true;\n\n const commit = async (): Promise<void> => {\n if (!active) {\n throw new DatabaseError('Transaction already ended', {});\n }\n database.exec('COMMIT');\n active = false;\n };\n\n const rollback = async (): Promise<void> => {\n if (!active) {\n throw new DatabaseError('Transaction already ended', {});\n }\n database.exec('ROLLBACK');\n active = false;\n };\n\n return {\n ...buildDatabaseInterface(upsertInCurrentTransaction),\n commit,\n rollback,\n isActive: () => active,\n };\n };\n\n const initializeSchemas = async (\n schemaOptions: SchemaInitializationOptions,\n ): Promise<void> => {\n const schemaManager = new DatabaseSchemaManager();\n await schemaManager.initializeSchemas(\n buildDatabaseInterface(upsert),\n schemaOptions,\n );\n };\n\n const getTableSchema = async (\n tableName: string,\n ): Promise<TableSchemaInfo | null> => {\n validateTableName(tableName);\n\n if (!(await tableExists(tableName))) {\n return null;\n }\n\n const columnRows = database\n .prepare(`PRAGMA table_info(${quoteIdentifier(tableName)})`)\n .all()\n .map(toPlainRow);\n\n const columns: Record<string, ColumnDefinition> = {};\n for (const row of columnRows) {\n columns[row.name as string] = {\n type: row.type as string,\n primaryKey: row.pk === 1,\n notNull: row.notnull === 1,\n defaultValue: row.dflt_value,\n };\n }\n\n const indexRows = executeNativeQuery(\n database,\n `SELECT name FROM sqlite_master\n WHERE type = 'index'\n AND tbl_name = ?\n AND name NOT LIKE 'sqlite_%'`,\n [tableName],\n ).rows;\n\n const indexes: IndexDefinition[] = [];\n for (const row of indexRows) {\n const indexName = row.name as string;\n const indexInfoRows = database\n .prepare(`PRAGMA index_info(${quoteIdentifier(indexName)})`)\n .all()\n .map(toPlainRow);\n const indexListRows = database\n .prepare(`PRAGMA index_list(${quoteIdentifier(tableName)})`)\n .all()\n .map(toPlainRow);\n\n indexes.push({\n name: indexName,\n columns: indexInfoRows.map((info: Record<string, any>) => info.name),\n unique: indexListRows.some(\n (info: Record<string, any>) =>\n info.name === indexName && info.unique === 1,\n ),\n });\n }\n\n const fkRows = database\n .prepare(`PRAGMA foreign_key_list(${quoteIdentifier(tableName)})`)\n .all()\n .map(toPlainRow);\n\n return {\n tableName,\n columns,\n indexes,\n foreignKeys: fkRows.map((row: Record<string, any>) => ({\n column: row.from as string,\n referencesTable: row.table as string,\n referencesColumn: row.to as string,\n onDelete: row.on_delete as string | undefined,\n onUpdate: row.on_update as string | undefined,\n })),\n };\n };\n\n const alterTable = {\n addColumn: async (\n tableName: string,\n column: ColumnDefinitionWithName,\n ): Promise<void> => {\n validateTableName(tableName);\n validateColumnName(column.name);\n const sql = generateAddColumnStatement(tableName, column, 'sqlite');\n executeNativeQuery(database, sql);\n },\n\n addIndex: async (\n tableName: string,\n index: IndexDefinition,\n ): Promise<void> => {\n validateTableName(tableName);\n validateIndexName(index.name);\n for (const column of index.columns) {\n validateColumnName(column);\n }\n const sql = generateCreateIndexStatement(tableName, index);\n executeNativeQuery(database, sql);\n },\n };\n\n const close = async (): Promise<void> => {\n if (closed) {\n return;\n }\n closed = true;\n for (const closeable of notificationCloseables) {\n closeable.close?.();\n }\n notificationCloseables.clear();\n honkerDb?.close?.();\n database.close();\n if (options.dbid) {\n nativeMemoryConnectionCache.delete(options.dbid);\n }\n };\n\n function buildDatabaseInterface(\n upsertImpl: DatabaseInterface['upsert'],\n ): DatabaseInterface {\n return {\n url,\n client: database,\n query,\n insert,\n update,\n upsert: upsertImpl,\n get,\n list,\n getOrInsert,\n delete: deleteRecords,\n count,\n table,\n tableExists,\n many,\n single,\n pluck,\n execute,\n oo,\n oO,\n ox,\n xx,\n syncSchema,\n initializeSchemas,\n transaction,\n beginTransaction,\n getTableSchema,\n alterTable,\n close,\n ...(vectorCapabilities ? { vector: vectorCapabilities } : {}),\n ...(notificationCapabilities\n ? { notifications: notificationCapabilities }\n : {}),\n };\n }\n\n const db = buildDatabaseInterface(upsert);\n const resolvedSchemas = resolveSchemas(options.schemas);\n if (resolvedSchemas && Object.keys(resolvedSchemas).length > 0) {\n createNativeTablesFromSchemas(database, resolvedSchemas);\n }\n\n return db;\n } catch (error) {\n try {\n database.close();\n } catch (_closeError) {\n // Preserve the original failure.\n }\n throw error;\n }\n}\n"],"names":["filePath","resolve","table","result"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-context.d.ts","sourceRoot":"","sources":["../../src/cli/claude-context.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { existsSync, mkdirSync, copyFileSync } from "node:fs";
|
|
3
|
+
import { dirname, join } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
const Dirname = dirname(fileURLToPath(import.meta.url));
|
|
6
|
+
const pkgRoot = join(Dirname, "../..");
|
|
7
|
+
const targetDir = join(process.cwd(), ".claude");
|
|
8
|
+
if (!existsSync(targetDir)) {
|
|
9
|
+
mkdirSync(targetDir, { recursive: true });
|
|
10
|
+
}
|
|
11
|
+
const pkgName = "sql";
|
|
12
|
+
const agentMdSrc = existsSync(join(pkgRoot, "AGENT.md")) ? join(pkgRoot, "AGENT.md") : join(pkgRoot, "CLAUDE.md");
|
|
13
|
+
const metaSrc = existsSync(join(pkgRoot, "metadata.json")) ? join(pkgRoot, "metadata.json") : join(pkgRoot, ".claude-meta.json");
|
|
14
|
+
if (existsSync(agentMdSrc)) {
|
|
15
|
+
copyFileSync(agentMdSrc, join(targetDir, `have-${pkgName}.md`));
|
|
16
|
+
}
|
|
17
|
+
if (existsSync(metaSrc)) {
|
|
18
|
+
copyFileSync(metaSrc, join(targetDir, `have-${pkgName}.meta.json`));
|
|
19
|
+
}
|
|
20
|
+
console.log(`✓ Installed @happyvertical/${pkgName} context to .claude/`);
|
|
21
|
+
//# sourceMappingURL=claude-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-context.js","sources":["../../src/cli/claude-context.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * CLI script to install agent context for @happyvertical/sql\n * Run the published context installer binary for this package.\n */\nimport { copyFileSync, existsSync, mkdirSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nconst Dirname = dirname(fileURLToPath(import.meta.url));\nconst pkgRoot = join(Dirname, '../..');\nconst targetDir = join(process.cwd(), '.claude');\n\nif (!existsSync(targetDir)) {\n mkdirSync(targetDir, { recursive: true });\n}\n\nconst pkgName = 'sql';\nconst agentMdSrc = existsSync(join(pkgRoot, 'AGENT.md'))\n ? join(pkgRoot, 'AGENT.md')\n : join(pkgRoot, 'CLAUDE.md');\nconst metaSrc = existsSync(join(pkgRoot, 'metadata.json'))\n ? join(pkgRoot, 'metadata.json')\n : join(pkgRoot, '.claude-meta.json');\n\nif (existsSync(agentMdSrc)) {\n copyFileSync(agentMdSrc, join(targetDir, `have-${pkgName}.md`));\n}\n\nif (existsSync(metaSrc)) {\n copyFileSync(metaSrc, join(targetDir, `have-${pkgName}.meta.json`));\n}\n\nconsole.log(`✓ Installed @happyvertical/${pkgName} context to .claude/`);\n"],"names":[],"mappings":";;;;AASA,MAAM,UAAU,QAAQ,cAAc,YAAY,GAAG,CAAC;AACtD,MAAM,UAAU,KAAK,SAAS,OAAO;AACrC,MAAM,YAAY,KAAK,QAAQ,IAAA,GAAO,SAAS;AAE/C,IAAI,CAAC,WAAW,SAAS,GAAG;AAC1B,YAAU,WAAW,EAAE,WAAW,KAAA,CAAM;AAC1C;AAEA,MAAM,UAAU;AAChB,MAAM,aAAa,WAAW,KAAK,SAAS,UAAU,CAAC,IACnD,KAAK,SAAS,UAAU,IACxB,KAAK,SAAS,WAAW;AAC7B,MAAM,UAAU,WAAW,KAAK,SAAS,eAAe,CAAC,IACrD,KAAK,SAAS,eAAe,IAC7B,KAAK,SAAS,mBAAmB;AAErC,IAAI,WAAW,UAAU,GAAG;AAC1B,eAAa,YAAY,KAAK,WAAW,QAAQ,OAAO,KAAK,CAAC;AAChE;AAEA,IAAI,WAAW,OAAO,GAAG;AACvB,eAAa,SAAS,KAAK,WAAW,QAAQ,OAAO,YAAY,CAAC;AACpE;AAEA,QAAQ,IAAI,8BAA8B,OAAO,sBAAsB;"}
|
package/dist/doctor.d.ts
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { DatabaseInterface } from './shared/types';
|
|
2
|
+
export type DoctorLevel = 'fail' | 'warn';
|
|
3
|
+
export interface DoctorIssue {
|
|
4
|
+
level: DoctorLevel;
|
|
5
|
+
message: string;
|
|
6
|
+
}
|
|
7
|
+
export interface DoctorContext {
|
|
8
|
+
db: DatabaseInterface;
|
|
9
|
+
tables: Set<string>;
|
|
10
|
+
}
|
|
11
|
+
export type DoctorCheck = (ctx: DoctorContext) => Promise<DoctorIssue[]>;
|
|
12
|
+
export interface RunDoctorOptions {
|
|
13
|
+
db: DatabaseInterface;
|
|
14
|
+
checks: DoctorCheck[];
|
|
15
|
+
}
|
|
16
|
+
export interface DoctorResult {
|
|
17
|
+
failures: DoctorIssue[];
|
|
18
|
+
warnings: DoctorIssue[];
|
|
19
|
+
issues: DoctorIssue[];
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Execute every check against the public-schema tables of `db` and
|
|
23
|
+
* partition the results by severity. Returns the aggregate; callers
|
|
24
|
+
* format/exit as they see fit.
|
|
25
|
+
*
|
|
26
|
+
* The current table set is enumerated once and shared across checks so
|
|
27
|
+
* each check can cheaply decide whether its target tables exist.
|
|
28
|
+
*/
|
|
29
|
+
export declare function runDoctor(options: RunDoctorOptions): Promise<DoctorResult>;
|
|
30
|
+
/**
|
|
31
|
+
* Emit a 'warn' for each table in `expected` that's missing.
|
|
32
|
+
*
|
|
33
|
+
* Marked as `warn` rather than `fail` because a missing table often
|
|
34
|
+
* indicates a migration that hasn't been run yet, not active data
|
|
35
|
+
* corruption — callers can promote to fail by mapping the issues.
|
|
36
|
+
*/
|
|
37
|
+
export declare function checkExpectedTables(expected: readonly string[]): DoctorCheck;
|
|
38
|
+
export interface UniqueColumnSpec {
|
|
39
|
+
table: string;
|
|
40
|
+
column: string;
|
|
41
|
+
/** Human-readable label used in the issue message. */
|
|
42
|
+
label: string;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Emit a 'fail' for each value that appears more than once in
|
|
46
|
+
* `(table, column)` (ignoring NULL and empty-string values).
|
|
47
|
+
*
|
|
48
|
+
* Useful for catching slug/key collisions that the schema didn't
|
|
49
|
+
* declare a UNIQUE constraint for (or where the constraint was added
|
|
50
|
+
* after data already existed).
|
|
51
|
+
*/
|
|
52
|
+
export declare function checkUniqueColumn(spec: UniqueColumnSpec): DoctorCheck;
|
|
53
|
+
export interface RelationshipSpec {
|
|
54
|
+
childTable: string;
|
|
55
|
+
childColumn: string;
|
|
56
|
+
parentTable: string;
|
|
57
|
+
/** Defaults to 'id'. */
|
|
58
|
+
parentColumn?: string;
|
|
59
|
+
/** Human-readable label used in the issue message. */
|
|
60
|
+
label: string;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Emit a 'fail' counting orphan rows where the child column points at a
|
|
64
|
+
* parent row that doesn't exist (FK-shaped check, but doesn't require an
|
|
65
|
+
* actual FK constraint to be declared — useful for soft references like
|
|
66
|
+
* tag-id-or-slug lookup columns).
|
|
67
|
+
*/
|
|
68
|
+
export declare function checkRelationship(spec: RelationshipSpec): DoctorCheck;
|
|
69
|
+
//# sourceMappingURL=doctor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../src/doctor.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,CAAC;AAE1C,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,WAAW,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,iBAAiB,CAAC;IACtB,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACrB;AAED,MAAM,MAAM,WAAW,GAAG,CAAC,GAAG,EAAE,aAAa,KAAK,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;AAEzE,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,iBAAiB,CAAC;IACtB,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB;AAED;;;;;;;GAOG;AACH,wBAAsB,SAAS,CAC7B,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,YAAY,CAAC,CAevB;AAmBD;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,WAAW,CAa5E;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,sDAAsD;IACtD,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,gBAAgB,GAAG,WAAW,CAkBrE;AAED,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,wBAAwB;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,sDAAsD;IACtD,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,gBAAgB,GAAG,WAAW,CAsBrE"}
|
package/dist/duckdb.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { DatabaseInterface, DuckDBOptions } from './shared/types';
|
|
2
|
+
/**
|
|
3
|
+
* Creates a DuckDB database adapter
|
|
4
|
+
*
|
|
5
|
+
* @param options - DuckDB connection options
|
|
6
|
+
* @returns Database interface for DuckDB
|
|
7
|
+
*/
|
|
8
|
+
export declare function getDatabase(options?: DuckDBOptions): Promise<DatabaseInterface>;
|
|
9
|
+
//# sourceMappingURL=duckdb.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"duckdb.d.ts","sourceRoot":"","sources":["../src/duckdb.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAGV,iBAAiB,EACjB,aAAa,EAQd,MAAM,gBAAgB,CAAC;AAqPxB;;;;;GAKG;AACH,wBAAsB,WAAW,CAC/B,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,iBAAiB,CAAC,CAysC5B"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { PostgresOptions } from './postgres';
|
|
2
|
+
import { DatabaseInterface, DuckDBOptions, JSONOptions } from './shared/types';
|
|
3
|
+
import { SqliteOptions } from './sqlite';
|
|
4
|
+
import { buildWhere, formatDbError } from './shared/utils';
|
|
5
|
+
import { convertUniqueIndexesToInlineConstraints } from './shared/duckdb-schema-utils';
|
|
6
|
+
/**
|
|
7
|
+
* Union type of options for creating different database types
|
|
8
|
+
*/
|
|
9
|
+
type GetDatabaseOptions = (PostgresOptions & {
|
|
10
|
+
type?: 'postgres';
|
|
11
|
+
}) | (SqliteOptions & {
|
|
12
|
+
type?: 'sqlite';
|
|
13
|
+
}) | (DuckDBOptions & {
|
|
14
|
+
type?: 'duckdb';
|
|
15
|
+
}) | JSONOptions;
|
|
16
|
+
/**
|
|
17
|
+
* Creates a database connection based on the provided options, or returns an existing database instance
|
|
18
|
+
*
|
|
19
|
+
* Loads configuration from environment variables using the HAVE_SQL_* pattern:
|
|
20
|
+
* - HAVE_SQL_TYPE → type ('sqlite' | 'postgres' | 'duckdb' | 'json')
|
|
21
|
+
* - HAVE_SQL_URL → url (connection string)
|
|
22
|
+
* - HAVE_SQL_HOST → host (database server hostname)
|
|
23
|
+
* - HAVE_SQL_PORT → port (database server port number)
|
|
24
|
+
* - HAVE_SQL_DATABASE → database (database name)
|
|
25
|
+
* - HAVE_SQL_USER → user (authentication username)
|
|
26
|
+
* - HAVE_SQL_PASSWORD → password (authentication password)
|
|
27
|
+
*
|
|
28
|
+
* User-provided options always take precedence over environment variables.
|
|
29
|
+
*
|
|
30
|
+
* ## Lazy schemas
|
|
31
|
+
*
|
|
32
|
+
* The `schemas` option accepts either an eagerly-built record or a lazy
|
|
33
|
+
* function (`() => Record<string, SchemaProvider>`). Adapters that manage
|
|
34
|
+
* tables via migrations (Postgres, SQLite) never resolve the function, so
|
|
35
|
+
* there is zero cost for callers that pass schemas uniformly regardless of
|
|
36
|
+
* adapter type. Only JSON and DuckDB adapters call the function.
|
|
37
|
+
*
|
|
38
|
+
* ```typescript
|
|
39
|
+
* // Caller doesn't need to know the adapter type:
|
|
40
|
+
* await getDatabase({
|
|
41
|
+
* ...config,
|
|
42
|
+
* schemas: () => ObjectRegistry.getAllSchemas(),
|
|
43
|
+
* });
|
|
44
|
+
* ```
|
|
45
|
+
*
|
|
46
|
+
* @param options - Configuration options for the database connection or an existing database instance
|
|
47
|
+
* @returns Promise resolving to a DatabaseInterface implementation
|
|
48
|
+
* @throws Error if the database type is invalid
|
|
49
|
+
*/
|
|
50
|
+
export declare function getDatabase(options?: GetDatabaseOptions | DatabaseInterface): Promise<DatabaseInterface>;
|
|
51
|
+
/**
|
|
52
|
+
* Synchronizes a SQL schema definition with a database
|
|
53
|
+
* Creates tables if they don't exist and adds missing columns to existing tables
|
|
54
|
+
*
|
|
55
|
+
* @param options - Object containing database and schema
|
|
56
|
+
* @param options.db - Database interface to use
|
|
57
|
+
* @param options.schema - SQL schema definition
|
|
58
|
+
* @throws Error if db or schema are missing or if the database doesn't support syncSchema
|
|
59
|
+
*/
|
|
60
|
+
export declare function syncSchema(options: {
|
|
61
|
+
db: DatabaseInterface;
|
|
62
|
+
schema: string;
|
|
63
|
+
}): Promise<void>;
|
|
64
|
+
/**
|
|
65
|
+
* Checks if a table exists in the database
|
|
66
|
+
*
|
|
67
|
+
* @param db - Database interface to use
|
|
68
|
+
* @param tableName - Name of the table to check
|
|
69
|
+
* @returns Promise resolving to boolean indicating if the table exists
|
|
70
|
+
*/
|
|
71
|
+
export declare function tableExists(db: DatabaseInterface, tableName: string): Promise<boolean>;
|
|
72
|
+
/**
|
|
73
|
+
* Escapes and formats a value for use in SQL queries
|
|
74
|
+
*
|
|
75
|
+
* @param value - Value to escape
|
|
76
|
+
* @returns String representation of the value safe for SQL use
|
|
77
|
+
*/
|
|
78
|
+
export declare function escapeSqlValue(value: any): string;
|
|
79
|
+
/**
|
|
80
|
+
* Validates a column name for use in SQL queries
|
|
81
|
+
*
|
|
82
|
+
* @param column - Column name to validate
|
|
83
|
+
* @returns The validated column name
|
|
84
|
+
* @throws Error if the column name contains invalid characters
|
|
85
|
+
*/
|
|
86
|
+
export declare function validateColumnName(column: string): string;
|
|
87
|
+
export type { SqlAdapterType } from './shared/utils';
|
|
88
|
+
export { buildWhere, formatDbError };
|
|
89
|
+
export { checkExpectedTables, checkRelationship, checkUniqueColumn, type DoctorCheck, type DoctorContext, type DoctorIssue, type DoctorLevel, type DoctorResult, type RelationshipSpec, type RunDoctorOptions, runDoctor, type UniqueColumnSpec, } from './doctor';
|
|
90
|
+
export { clearConnectionCache } from './json.js';
|
|
91
|
+
export { clearPostgresConnectionCache } from './postgres.js';
|
|
92
|
+
export { assertCanExportDatabase, assertCanImportDatabase, type CreateDropOptions, createPostgresDatabase, type DumpOptions, databaseNameFromUrl, dropPostgresDatabase, dumpPostgresDatabase, isLocalDatabaseUrl, type PostgresImportLocalityOptions, type PostgresLocalityOptions, postgresEnvFromUrl, type RestoreOptions, redactDatabaseUrl, restorePostgresDatabase, } from './postgres-cli';
|
|
93
|
+
export type { SchemaInitializationResult } from './schema-manager';
|
|
94
|
+
export { DatabaseSchemaManager } from './schema-manager';
|
|
95
|
+
export * from './shared/types';
|
|
96
|
+
export { convertUniqueIndexesToInlineConstraints };
|
|
97
|
+
declare const _default: {
|
|
98
|
+
getDatabase: typeof getDatabase;
|
|
99
|
+
syncSchema: typeof syncSchema;
|
|
100
|
+
tableExists: typeof tableExists;
|
|
101
|
+
buildWhere: (where: import('.').WhereClause, startIndex?: number, adapterType?: import('.').SqlAdapterType) => {
|
|
102
|
+
sql: string;
|
|
103
|
+
values: any[];
|
|
104
|
+
};
|
|
105
|
+
};
|
|
106
|
+
export default _default;
|
|
107
|
+
/** @internal */
|
|
108
|
+
export declare const PACKAGE_VERSION_INITIALIZED = true;
|
|
109
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,KAAK,EACV,iBAAiB,EACjB,aAAa,EACb,WAAW,EACZ,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C;;GAEG;AACH,KAAK,kBAAkB,GACnB,CAAC,eAAe,GAAG;IAAE,IAAI,CAAC,EAAE,UAAU,CAAA;CAAE,CAAC,GACzC,CAAC,aAAa,GAAG;IAAE,IAAI,CAAC,EAAE,QAAQ,CAAA;CAAE,CAAC,GACrC,CAAC,aAAa,GAAG;IAAE,IAAI,CAAC,EAAE,QAAQ,CAAA;CAAE,CAAC,GACrC,WAAW,CAAC;AAmBhB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAsB,WAAW,CAC/B,OAAO,GAAE,kBAAkB,GAAG,iBAAsB,GACnD,OAAO,CAAC,iBAAiB,CAAC,CAiD5B;AAaD;;;;;;;;GAQG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE;IACxC,EAAE,EAAE,iBAAiB,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;CAChB,iBAYA;AAED;;;;;;GAMG;AACH,wBAAsB,WAAW,CAAC,EAAE,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,oBAEzE;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,GAAG,GAAG,MAAM,CAejD;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAMzD;AAGD,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE3D,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,CAAC;AAGrC,OAAO,EAAE,uCAAuC,EAAE,MAAM,8BAA8B,CAAC;AAGvF,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,EACjB,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,SAAS,EACT,KAAK,gBAAgB,GACtB,MAAM,UAAU,CAAC;AAGlB,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,4BAA4B,EAAE,MAAM,eAAe,CAAC;AAE7D,OAAO,EACL,uBAAuB,EACvB,uBAAuB,EACvB,KAAK,iBAAiB,EACtB,sBAAsB,EACtB,KAAK,WAAW,EAChB,mBAAmB,EACnB,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,EAClB,KAAK,6BAA6B,EAClC,KAAK,uBAAuB,EAC5B,kBAAkB,EAClB,KAAK,cAAc,EACnB,iBAAiB,EACjB,uBAAuB,GACxB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,0BAA0B,EAAE,MAAM,kBAAkB,CAAC;AAEnE,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AACzD,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EAAE,uCAAuC,EAAE,CAAC;;;;;;;;;;AAEnD,wBAKE;AAEF,gBAAgB;AAChB,eAAO,MAAM,2BAA2B,OAAO,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import "@happyvertical/utils";
|
|
2
|
+
import { D, P, d, h, i, j, k, l, e, m, n, f, o, r, p, s, t, q } from "./chunks/index-DL-5nB7l.js";
|
|
3
|
+
import { a, b, c, d as d2, e as e2, f as f2, i as i2, p as p2, r as r2, g } from "./chunks/postgres-cli-Cr6bBZ3q.js";
|
|
4
|
+
export {
|
|
5
|
+
D as DatabaseSchemaManager,
|
|
6
|
+
P as PACKAGE_VERSION_INITIALIZED,
|
|
7
|
+
a as assertCanExportDatabase,
|
|
8
|
+
b as assertCanImportDatabase,
|
|
9
|
+
d as buildWhere,
|
|
10
|
+
h as checkExpectedTables,
|
|
11
|
+
i as checkRelationship,
|
|
12
|
+
j as checkUniqueColumn,
|
|
13
|
+
k as clearConnectionCache,
|
|
14
|
+
l as clearPostgresConnectionCache,
|
|
15
|
+
e as convertUniqueIndexesToInlineConstraints,
|
|
16
|
+
c as createPostgresDatabase,
|
|
17
|
+
d2 as databaseNameFromUrl,
|
|
18
|
+
m as default,
|
|
19
|
+
e2 as dropPostgresDatabase,
|
|
20
|
+
f2 as dumpPostgresDatabase,
|
|
21
|
+
n as escapeSqlValue,
|
|
22
|
+
f as formatDbError,
|
|
23
|
+
o as getDatabase,
|
|
24
|
+
i2 as isLocalDatabaseUrl,
|
|
25
|
+
p2 as postgresEnvFromUrl,
|
|
26
|
+
r2 as redactDatabaseUrl,
|
|
27
|
+
r as resolveSchemas,
|
|
28
|
+
g as restorePostgresDatabase,
|
|
29
|
+
p as runDoctor,
|
|
30
|
+
s as syncSchema,
|
|
31
|
+
t as tableExists,
|
|
32
|
+
q as validateColumnName
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;"}
|
package/dist/json.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { DatabaseInterface, JSONOptions } from './shared/types';
|
|
2
|
+
/**
|
|
3
|
+
* Extend globalThis to include our connection cache properties.
|
|
4
|
+
* Using globalThis ensures all module instances share the same cache,
|
|
5
|
+
* which is critical in monorepos where the same package can be loaded
|
|
6
|
+
* from different paths (e.g., pnpm store vs workspace symlink).
|
|
7
|
+
*
|
|
8
|
+
* @see https://github.com/happyvertical/sdk/issues/678
|
|
9
|
+
*/
|
|
10
|
+
declare global {
|
|
11
|
+
var __haveSqlMemoryConnectionCache: Map<string, DatabaseInterface> | undefined;
|
|
12
|
+
var __haveSqlPendingConnections: Map<string, Promise<DatabaseInterface>> | undefined;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Clears all cached connections
|
|
16
|
+
* Useful for testing to ensure test isolation
|
|
17
|
+
*/
|
|
18
|
+
export declare function clearConnectionCache(): void;
|
|
19
|
+
/**
|
|
20
|
+
* Creates a JSON database adapter using DuckDB in-memory engine
|
|
21
|
+
*
|
|
22
|
+
* This adapter provides SQL query capabilities over JSON files without creating
|
|
23
|
+
* persistent database files or WAL files. All data is stored in-memory during
|
|
24
|
+
* runtime and written back to JSON files based on the write strategy.
|
|
25
|
+
*
|
|
26
|
+
* @param options - JSON database options
|
|
27
|
+
* @returns Database interface for JSON files
|
|
28
|
+
*/
|
|
29
|
+
export declare function getDatabase(options: JSONOptions): Promise<DatabaseInterface>;
|
|
30
|
+
//# sourceMappingURL=json.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json.d.ts","sourceRoot":"","sources":["../src/json.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,iBAAiB,EACjB,WAAW,EAMZ,MAAM,gBAAgB,CAAC;AAIxB;;;;;;;GAOG;AACH,OAAO,CAAC,MAAM,CAAC;IAEb,IAAI,8BAA8B,EAC9B,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,GAC9B,SAAS,CAAC;IAEd,IAAI,2BAA2B,EAC3B,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC,GACvC,SAAS,CAAC;CACf;AAgCD;;;GAGG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAG3C;AAigBD;;;;;;;;;GASG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,iBAAiB,CAAC,CAo2C5B"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
export interface PostgresLocalityOptions {
|
|
2
|
+
/** Allow exporting from a non-local database without --allow-production. */
|
|
3
|
+
allowProduction?: boolean;
|
|
4
|
+
/** Allow exporting a local database when `prod: true` is set. */
|
|
5
|
+
allowLocal?: boolean;
|
|
6
|
+
/** True when the caller is running a production-flavored export. */
|
|
7
|
+
prod?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface PostgresImportLocalityOptions {
|
|
10
|
+
allowProduction?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export interface DumpOptions {
|
|
13
|
+
/** Extra args appended after the built-in pg_dump flags. */
|
|
14
|
+
extraArgs?: string[];
|
|
15
|
+
/** Override the binary name (e.g. `/usr/local/pg17/bin/pg_dump`). */
|
|
16
|
+
binary?: string;
|
|
17
|
+
}
|
|
18
|
+
export interface RestoreOptions {
|
|
19
|
+
extraArgs?: string[];
|
|
20
|
+
binary?: string;
|
|
21
|
+
/**
|
|
22
|
+
* Wrap the restore in `--single-transaction --exit-on-error` so a
|
|
23
|
+
* mid-restore failure rolls the target database back to its prior
|
|
24
|
+
* state instead of leaving it partially-restored-but-failing.
|
|
25
|
+
* Defaults to `true`. Set to `false` if you need parallel restore
|
|
26
|
+
* (`--jobs N` in `extraArgs`); pg_restore rejects `--single-transaction`
|
|
27
|
+
* combined with `--jobs`.
|
|
28
|
+
*/
|
|
29
|
+
singleTransaction?: boolean;
|
|
30
|
+
}
|
|
31
|
+
export interface CreateDropOptions {
|
|
32
|
+
/** Database name to drop. Defaults to the one parsed from the URL. */
|
|
33
|
+
database?: string;
|
|
34
|
+
/**
|
|
35
|
+
* The maintenance database to connect to when running create/drop
|
|
36
|
+
* (the target DB itself can't be open). Defaults to 'postgres'.
|
|
37
|
+
*/
|
|
38
|
+
maintenanceDatabase?: string;
|
|
39
|
+
extraArgs?: string[];
|
|
40
|
+
binary?: string;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Extract the database name from a postgres connection URL.
|
|
44
|
+
*
|
|
45
|
+
* Throws if the URL has no path/db segment (postgres rejects connections
|
|
46
|
+
* without one anyway).
|
|
47
|
+
*/
|
|
48
|
+
export declare function databaseNameFromUrl(databaseUrl: string): string;
|
|
49
|
+
/**
|
|
50
|
+
* Treat localhost / 127.0.0.1 / ::1 / empty-hostname URLs as "local".
|
|
51
|
+
*
|
|
52
|
+
* Used by the export/import safety guards to decide whether a command
|
|
53
|
+
* needs `--allow-production` to proceed.
|
|
54
|
+
*/
|
|
55
|
+
export declare function isLocalDatabaseUrl(databaseUrl: string): boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Strip credentials from a postgres URL for logging/manifest use.
|
|
58
|
+
* Returns `[invalid database url]` if parsing fails.
|
|
59
|
+
*
|
|
60
|
+
* Redacts both the userinfo (`user:password@`) and any credential-shaped
|
|
61
|
+
* query parameters (`?password=…`, `?passwd=…`, `?pass=…`) — cloud
|
|
62
|
+
* providers like Neon and Supabase emit URLs with `?password=` instead of
|
|
63
|
+
* (or in addition to) the userinfo form, and leaking those into logs or
|
|
64
|
+
* the backup manifest defeats the rest of the redaction.
|
|
65
|
+
*/
|
|
66
|
+
export declare function redactDatabaseUrl(databaseUrl: string): string;
|
|
67
|
+
/**
|
|
68
|
+
* Translate a postgres URL into the libpq env vars that pg_dump/pg_restore
|
|
69
|
+
* read. Passing credentials this way keeps them out of process argv (and
|
|
70
|
+
* therefore out of `ps`, audit logs, and error output).
|
|
71
|
+
*
|
|
72
|
+
* `databaseOverride` lets callers point pg tools at a different db on the
|
|
73
|
+
* same server (e.g. connecting to `postgres` to drop the real target).
|
|
74
|
+
*/
|
|
75
|
+
export declare function postgresEnvFromUrl(databaseUrl: string, databaseOverride?: string): Record<string, string>;
|
|
76
|
+
/**
|
|
77
|
+
* Guard for export operations. Two distinct hazards:
|
|
78
|
+
* - running a "prod" export against a local DB by mistake (likely a
|
|
79
|
+
* developer running prod scripts on their laptop)
|
|
80
|
+
* - running a regular export against a non-local DB (likely a developer
|
|
81
|
+
* pointing at staging or prod when they meant to target their laptop)
|
|
82
|
+
*
|
|
83
|
+
* Each escape hatch is named so the override has to be deliberate.
|
|
84
|
+
*/
|
|
85
|
+
export declare function assertCanExportDatabase(databaseUrl: string, options: PostgresLocalityOptions): void;
|
|
86
|
+
/**
|
|
87
|
+
* Guard for import/restore operations against non-local databases.
|
|
88
|
+
* Restoring is destructive, so the default is "local only".
|
|
89
|
+
*/
|
|
90
|
+
export declare function assertCanImportDatabase(databaseUrl: string, options: PostgresImportLocalityOptions): void;
|
|
91
|
+
/**
|
|
92
|
+
* Run `pg_dump` against `databaseUrl`, writing a custom-format archive to
|
|
93
|
+
* `dumpPath`. Defaults match the common "logical backup, no-owner, no-acl"
|
|
94
|
+
* recipe used for cross-environment restores.
|
|
95
|
+
*
|
|
96
|
+
* Credentials travel via env vars, never argv.
|
|
97
|
+
*/
|
|
98
|
+
export declare function dumpPostgresDatabase(databaseUrl: string, dumpPath: string, options?: DumpOptions): Promise<void>;
|
|
99
|
+
/**
|
|
100
|
+
* Run `pg_restore` against `databaseUrl` from a custom-format archive at
|
|
101
|
+
* `dumpPath`. Uses `--clean --if-exists` so the target db can be a previous
|
|
102
|
+
* state of the same schema.
|
|
103
|
+
*/
|
|
104
|
+
export declare function restorePostgresDatabase(databaseUrl: string, dumpPath: string, options?: RestoreOptions): Promise<void>;
|
|
105
|
+
/**
|
|
106
|
+
* `createdb`-equivalent. Connects via the maintenance database (default
|
|
107
|
+
* `postgres`) and creates the database named in the URL, or in
|
|
108
|
+
* `options.database` if provided.
|
|
109
|
+
*/
|
|
110
|
+
export declare function createPostgresDatabase(databaseUrl: string, options?: CreateDropOptions): Promise<void>;
|
|
111
|
+
/**
|
|
112
|
+
* `dropdb`-equivalent, with `--if-exists` by default so callers can use
|
|
113
|
+
* this idempotently as part of a reset flow.
|
|
114
|
+
*/
|
|
115
|
+
export declare function dropPostgresDatabase(databaseUrl: string, options?: CreateDropOptions): Promise<void>;
|
|
116
|
+
/**
|
|
117
|
+
* Spawn helper used by the wrappers above. Inherits stdio so progress and
|
|
118
|
+
* error output stream to the parent terminal (these are interactive ops),
|
|
119
|
+
* unless the caller passes `stdio: 'pipe'` for programmatic use — in
|
|
120
|
+
* which case stderr is captured and included in the thrown error so the
|
|
121
|
+
* failure isn't an opaque `"pg_dump exited with status 1"`.
|
|
122
|
+
*
|
|
123
|
+
* Libpq connection vars (PGHOST, PGSERVICE, ...) inherited from the
|
|
124
|
+
* parent process are scrubbed before merging with `options.env`. This is
|
|
125
|
+
* the half of "URL-determined connection target" that
|
|
126
|
+
* `postgresEnvFromUrl` can't do alone: without scrubbing, a developer
|
|
127
|
+
* with `PGHOST=staging` in their shell would silently redirect the
|
|
128
|
+
* child's connection regardless of what the URL specified.
|
|
129
|
+
*/
|
|
130
|
+
export declare function runCommand(command: string, args: string[], options?: {
|
|
131
|
+
cwd?: string;
|
|
132
|
+
env?: Record<string, string>;
|
|
133
|
+
stdio?: 'inherit' | 'pipe';
|
|
134
|
+
}): Promise<void>;
|
|
135
|
+
//# sourceMappingURL=postgres-cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres-cli.d.ts","sourceRoot":"","sources":["../src/postgres-cli.ts"],"names":[],"mappings":"AAcA,MAAM,WAAW,uBAAuB;IACtC,4EAA4E;IAC5E,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,iEAAiE;IACjE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,oEAAoE;IACpE,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,6BAA6B;IAC5C,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,WAAW;IAC1B,4DAA4D;IAC5D,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;;OAOG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,iBAAiB;IAChC,sEAAsE;IACtE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAK/D;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAa/D;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAc7D;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,EACnB,gBAAgB,CAAC,EAAE,MAAM,GACxB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAqDxB;AA4CD;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,uBAAuB,GAC/B,IAAI,CAYN;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,6BAA6B,GACrC,IAAI,CAMN;AAED;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CACxC,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,IAAI,CAAC,CAef;AAED;;;;GAIG;AACH,wBAAsB,uBAAuB,CAC3C,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,IAAI,CAAC,CA+Bf;AAED;;;;GAIG;AACH,wBAAsB,sBAAsB,CAC1C,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,IAAI,CAAC,CAYf;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,IAAI,CAAC,CAYf;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,UAAU,CAC9B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,GAAE;IACP,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,KAAK,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;CACvB,GACL,OAAO,CAAC,IAAI,CAAC,CAkCf"}
|