@agent-native/core 0.12.25 → 0.12.27

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.
Files changed (56) hide show
  1. package/dist/agent/production-agent.d.ts.map +1 -1
  2. package/dist/agent/production-agent.js +20 -2
  3. package/dist/agent/production-agent.js.map +1 -1
  4. package/dist/client/AgentTaskCard.d.ts.map +1 -1
  5. package/dist/client/AgentTaskCard.js +16 -3
  6. package/dist/client/AgentTaskCard.js.map +1 -1
  7. package/dist/client/AssistantChat.d.ts.map +1 -1
  8. package/dist/client/AssistantChat.js +22 -12
  9. package/dist/client/AssistantChat.js.map +1 -1
  10. package/dist/client/IframeEmbed.d.ts.map +1 -1
  11. package/dist/client/IframeEmbed.js +2 -2
  12. package/dist/client/IframeEmbed.js.map +1 -1
  13. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  14. package/dist/client/agent-chat-adapter.js +62 -9
  15. package/dist/client/agent-chat-adapter.js.map +1 -1
  16. package/dist/client/composer/ComposerPlusMenu.d.ts.map +1 -1
  17. package/dist/client/composer/ComposerPlusMenu.js +1 -1
  18. package/dist/client/composer/ComposerPlusMenu.js.map +1 -1
  19. package/dist/client/composer/PromptComposer.d.ts.map +1 -1
  20. package/dist/client/composer/PromptComposer.js +8 -7
  21. package/dist/client/composer/PromptComposer.js.map +1 -1
  22. package/dist/client/composer/attachment-accept.d.ts +7 -0
  23. package/dist/client/composer/attachment-accept.d.ts.map +1 -0
  24. package/dist/client/composer/attachment-accept.js +36 -0
  25. package/dist/client/composer/attachment-accept.js.map +1 -0
  26. package/dist/client/sse-event-processor.d.ts.map +1 -1
  27. package/dist/client/sse-event-processor.js +8 -0
  28. package/dist/client/sse-event-processor.js.map +1 -1
  29. package/dist/db/client.d.ts +3 -0
  30. package/dist/db/client.d.ts.map +1 -1
  31. package/dist/db/client.js +70 -34
  32. package/dist/db/client.js.map +1 -1
  33. package/dist/db/create-get-db.d.ts.map +1 -1
  34. package/dist/db/create-get-db.js +30 -7
  35. package/dist/db/create-get-db.js.map +1 -1
  36. package/dist/deploy/build.js +64 -0
  37. package/dist/deploy/build.js.map +1 -1
  38. package/dist/scripts/db/exec.d.ts.map +1 -1
  39. package/dist/scripts/db/exec.js +3 -6
  40. package/dist/scripts/db/exec.js.map +1 -1
  41. package/dist/scripts/db/patch.d.ts.map +1 -1
  42. package/dist/scripts/db/patch.js +3 -6
  43. package/dist/scripts/db/patch.js.map +1 -1
  44. package/dist/scripts/db/query.d.ts.map +1 -1
  45. package/dist/scripts/db/query.js +3 -6
  46. package/dist/scripts/db/query.js.map +1 -1
  47. package/dist/scripts/db/schema.d.ts.map +1 -1
  48. package/dist/scripts/db/schema.js +3 -6
  49. package/dist/scripts/db/schema.js.map +1 -1
  50. package/dist/scripts/db/sqlite-client.d.ts +15 -0
  51. package/dist/scripts/db/sqlite-client.d.ts.map +1 -0
  52. package/dist/scripts/db/sqlite-client.js +51 -0
  53. package/dist/scripts/db/sqlite-client.js.map +1 -0
  54. package/dist/server/better-auth-instance.js +4 -3
  55. package/dist/server/better-auth-instance.js.map +1 -1
  56. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"query.js","sourceRoot":"","sources":["../../../src/scripts/db/query.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Core script: db-query\n *\n * Run a read-only SQL query against a SQLite or Postgres database.\n *\n * In production mode, temporary views are created to scope data to the\n * current user (AGENT_USER_EMAIL). Tables with an `owner_email` column\n * and core tables (settings, application_state, etc.) are automatically\n * filtered so queries only return the current user's data.\n *\n * Usage:\n * pnpm action db-query --sql \"SELECT * FROM forms WHERE id = ?\" [--args '[\"abc\"]'] [--db path] [--format json] [--limit N]\n */\n\nimport path from \"path\";\nimport { createClient } from \"@libsql/client\";\nimport { getDatabaseUrl, getDatabaseAuthToken } from \"../../db/client.js\";\nimport { parseArgs, fail } from \"../utils.js\";\nimport { assertNoSensitiveFrameworkTables } from \"./safety.js\";\nimport { buildScopingPostgres, buildScopingSqlite } from \"./scoping.js\";\n\nfunction isPostgresUrl(url: string): boolean {\n return url.startsWith(\"postgres://\") || url.startsWith(\"postgresql://\");\n}\n\nfunction parseSqlArgs(raw: string | undefined): unknown[] {\n if (!raw) return [];\n try {\n const parsed = JSON.parse(raw);\n if (Array.isArray(parsed)) return parsed;\n } catch {\n // Fall through to the shared error below.\n }\n fail(\"--args must be a JSON array\");\n}\n\nfunction convertQuestionMarksToPostgresParams(sql: string): string {\n let index = 0;\n let out = \"\";\n let state: \"normal\" | \"single\" | \"double\" | \"line-comment\" | \"block-comment\" =\n \"normal\";\n\n for (let i = 0; i < sql.length; i++) {\n const ch = sql[i];\n const next = sql[i + 1];\n\n if (state === \"line-comment\") {\n out += ch;\n if (ch === \"\\n\") state = \"normal\";\n continue;\n }\n\n if (state === \"block-comment\") {\n out += ch;\n if (ch === \"*\" && next === \"/\") {\n out += next;\n i++;\n state = \"normal\";\n }\n continue;\n }\n\n if (state === \"single\") {\n out += ch;\n if (ch === \"'\" && next === \"'\") {\n out += next;\n i++;\n } else if (ch === \"'\") {\n state = \"normal\";\n }\n continue;\n }\n\n if (state === \"double\") {\n out += ch;\n if (ch === '\"' && next === '\"') {\n out += next;\n i++;\n } else if (ch === '\"') {\n state = \"normal\";\n }\n continue;\n }\n\n if (ch === \"-\" && next === \"-\") {\n out += ch + next;\n i++;\n state = \"line-comment\";\n continue;\n }\n if (ch === \"/\" && next === \"*\") {\n out += ch + next;\n i++;\n state = \"block-comment\";\n continue;\n }\n if (ch === \"'\") {\n out += ch;\n state = \"single\";\n continue;\n }\n if (ch === '\"') {\n out += ch;\n state = \"double\";\n continue;\n }\n if (ch === \"?\") {\n index++;\n out += `$${index}`;\n continue;\n }\n out += ch;\n }\n\n return out;\n}\n\nfunction normalizePostgresSql(sql: string, args: unknown[]): string {\n if (args.length === 0 || /\\$\\d+\\b/.test(sql)) return sql;\n return convertQuestionMarksToPostgresParams(sql);\n}\n\nfunction printTable(\n rows: Record<string, unknown>[],\n finalSql: string,\n format?: string,\n) {\n if (format === \"json\") {\n console.log(\n JSON.stringify({ query: finalSql, rows, count: rows.length }, null, 2),\n );\n return;\n }\n\n console.log(`Query: ${finalSql}`);\n console.log(`Rows: ${rows.length}\\n`);\n\n if (rows.length === 0) {\n console.log(\"(no results)\");\n return;\n }\n\n const keys = Object.keys(rows[0]);\n const widths = keys.map((k) => {\n const maxVal = Math.max(...rows.map((r) => String(r[k] ?? \"NULL\").length));\n return Math.max(k.length, Math.min(maxVal, 60));\n });\n\n const header = keys.map((k, i) => k.padEnd(widths[i])).join(\" | \");\n console.log(header);\n console.log(widths.map((w) => \"-\".repeat(w)).join(\"-+-\"));\n\n for (const row of rows) {\n const line = keys\n .map((k, i) => {\n const val = String(row[k] ?? \"NULL\");\n return val.length > 60\n ? val.slice(0, 57) + \"...\"\n : val.padEnd(widths[i]);\n })\n .join(\" | \");\n console.log(line);\n }\n}\n\nexport default async function dbQuery(args: string[]): Promise<void> {\n const parsed = parseArgs(args);\n\n if (parsed.help === \"true\") {\n console.log(`Usage: pnpm action db-query --sql \"<query>\" [options]\n\nOptions:\n --sql <query> SQL SELECT query to run (required)\n --args <json> JSON array of positional SQL bind parameters\n --db <path> Path to SQLite database (default: data/app.db)\n --format json Output as JSON instead of a table\n --limit N Append LIMIT N if not already present\n --help Show this help message`);\n return;\n }\n\n const sql = parsed.sql;\n if (!sql) {\n fail('--sql is required. Example: --sql \"SELECT * FROM forms\"');\n }\n const sqlArgs = parseSqlArgs(parsed.args);\n\n // Safety: only allow read-only statements.\n // Strip leading SQL comments before checking the prefix.\n const stripped = sql\n .replace(/^\\s*--[^\\n]*\\n/gm, \"\")\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, \"\")\n .trim();\n const upper = stripped.toUpperCase();\n if (\n !upper.startsWith(\"SELECT\") &&\n !upper.startsWith(\"WITH\") &&\n !upper.startsWith(\"EXPLAIN\") &&\n !upper.startsWith(\"PRAGMA\")\n ) {\n fail(\n \"Only SELECT, WITH, EXPLAIN, and PRAGMA queries are allowed. Use db-exec for writes.\",\n );\n }\n assertNoSensitiveFrameworkTables(stripped, \"read\");\n\n // Resolve database URL: --db flag → DATABASE_URL env → default file path\n let url: string;\n if (parsed.db) {\n url = \"file:\" + path.resolve(parsed.db);\n } else if (getDatabaseUrl()) {\n url = getDatabaseUrl();\n } else {\n url = \"file:\" + path.resolve(process.cwd(), \"data\", \"app.db\");\n }\n\n let finalSql = sql;\n if (\n parsed.limit &&\n (upper.startsWith(\"SELECT\") || upper.startsWith(\"WITH\")) &&\n !/\\bLIMIT\\b/i.test(stripped)\n ) {\n const limitVal = parseInt(parsed.limit, 10);\n if (isNaN(limitVal) || limitVal < 1)\n fail(\"--limit must be a positive integer\");\n finalSql = `${sql} LIMIT ${limitVal}`;\n }\n\n // Postgres path\n if (isPostgresUrl(url)) {\n const { default: pg } = await import(\"postgres\");\n const pgSql = pg(url);\n try {\n const pgSqlText = normalizePostgresSql(finalSql, sqlArgs);\n let rows: Record<string, unknown>[] = [];\n await pgSql.begin(async (tx: any) => {\n // Temp views are session state. Keep setup/query/teardown on one\n // transaction-bound backend so pooled Postgres never retains them.\n const scoping = await buildScopingPostgres(tx);\n try {\n for (const stmt of scoping.setup) {\n await tx.unsafe(stmt);\n }\n\n const result =\n sqlArgs.length > 0\n ? await tx.unsafe(pgSqlText, sqlArgs as any[])\n : await tx.unsafe(pgSqlText);\n rows = Array.from(result);\n } finally {\n for (const stmt of scoping.teardown) {\n await tx.unsafe(stmt).catch(() => {});\n }\n }\n });\n const keys = rows.length > 0 ? Object.keys(rows[0]) : [];\n\n printTable(\n rows.length > 0 ? rows : keys.length > 0 ? rows : [],\n pgSqlText,\n parsed.format,\n );\n } finally {\n await pgSql.end();\n }\n return;\n }\n\n // libsql / SQLite path\n const client = createClient({\n url,\n authToken: getDatabaseAuthToken(),\n });\n\n try {\n // Set up user-scoped temp views in production\n const scoping = await buildScopingSqlite(client);\n for (const stmt of scoping.setup) {\n await client.execute(stmt);\n }\n\n const result =\n sqlArgs.length > 0\n ? await client.execute({ sql: finalSql, args: sqlArgs as any[] })\n : await client.execute(finalSql);\n const rows: Record<string, unknown>[] = result.rows.map((row) => {\n const obj: Record<string, unknown> = {};\n for (let i = 0; i < result.columns.length; i++) {\n obj[result.columns[i]] = row[i];\n }\n return obj;\n });\n\n printTable(rows, finalSql, parsed.format);\n\n // Tear down temp views\n for (const stmt of scoping.teardown) {\n await client.execute(stmt).catch(() => {});\n }\n } finally {\n client.close();\n }\n}\n"]}
1
+ {"version":3,"file":"query.js","sourceRoot":"","sources":["../../../src/scripts/db/query.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Core script: db-query\n *\n * Run a read-only SQL query against a SQLite or Postgres database.\n *\n * In production mode, temporary views are created to scope data to the\n * current user (AGENT_USER_EMAIL). Tables with an `owner_email` column\n * and core tables (settings, application_state, etc.) are automatically\n * filtered so queries only return the current user's data.\n *\n * Usage:\n * pnpm action db-query --sql \"SELECT * FROM forms WHERE id = ?\" [--args '[\"abc\"]'] [--db path] [--format json] [--limit N]\n */\n\nimport path from \"path\";\nimport { getDatabaseUrl } from \"../../db/client.js\";\nimport { parseArgs, fail } from \"../utils.js\";\nimport { assertNoSensitiveFrameworkTables } from \"./safety.js\";\nimport { buildScopingPostgres, buildScopingSqlite } from \"./scoping.js\";\nimport { createSqliteScriptClient } from \"./sqlite-client.js\";\n\nfunction isPostgresUrl(url: string): boolean {\n return url.startsWith(\"postgres://\") || url.startsWith(\"postgresql://\");\n}\n\nfunction parseSqlArgs(raw: string | undefined): unknown[] {\n if (!raw) return [];\n try {\n const parsed = JSON.parse(raw);\n if (Array.isArray(parsed)) return parsed;\n } catch {\n // Fall through to the shared error below.\n }\n fail(\"--args must be a JSON array\");\n}\n\nfunction convertQuestionMarksToPostgresParams(sql: string): string {\n let index = 0;\n let out = \"\";\n let state: \"normal\" | \"single\" | \"double\" | \"line-comment\" | \"block-comment\" =\n \"normal\";\n\n for (let i = 0; i < sql.length; i++) {\n const ch = sql[i];\n const next = sql[i + 1];\n\n if (state === \"line-comment\") {\n out += ch;\n if (ch === \"\\n\") state = \"normal\";\n continue;\n }\n\n if (state === \"block-comment\") {\n out += ch;\n if (ch === \"*\" && next === \"/\") {\n out += next;\n i++;\n state = \"normal\";\n }\n continue;\n }\n\n if (state === \"single\") {\n out += ch;\n if (ch === \"'\" && next === \"'\") {\n out += next;\n i++;\n } else if (ch === \"'\") {\n state = \"normal\";\n }\n continue;\n }\n\n if (state === \"double\") {\n out += ch;\n if (ch === '\"' && next === '\"') {\n out += next;\n i++;\n } else if (ch === '\"') {\n state = \"normal\";\n }\n continue;\n }\n\n if (ch === \"-\" && next === \"-\") {\n out += ch + next;\n i++;\n state = \"line-comment\";\n continue;\n }\n if (ch === \"/\" && next === \"*\") {\n out += ch + next;\n i++;\n state = \"block-comment\";\n continue;\n }\n if (ch === \"'\") {\n out += ch;\n state = \"single\";\n continue;\n }\n if (ch === '\"') {\n out += ch;\n state = \"double\";\n continue;\n }\n if (ch === \"?\") {\n index++;\n out += `$${index}`;\n continue;\n }\n out += ch;\n }\n\n return out;\n}\n\nfunction normalizePostgresSql(sql: string, args: unknown[]): string {\n if (args.length === 0 || /\\$\\d+\\b/.test(sql)) return sql;\n return convertQuestionMarksToPostgresParams(sql);\n}\n\nfunction printTable(\n rows: Record<string, unknown>[],\n finalSql: string,\n format?: string,\n) {\n if (format === \"json\") {\n console.log(\n JSON.stringify({ query: finalSql, rows, count: rows.length }, null, 2),\n );\n return;\n }\n\n console.log(`Query: ${finalSql}`);\n console.log(`Rows: ${rows.length}\\n`);\n\n if (rows.length === 0) {\n console.log(\"(no results)\");\n return;\n }\n\n const keys = Object.keys(rows[0]);\n const widths = keys.map((k) => {\n const maxVal = Math.max(...rows.map((r) => String(r[k] ?? \"NULL\").length));\n return Math.max(k.length, Math.min(maxVal, 60));\n });\n\n const header = keys.map((k, i) => k.padEnd(widths[i])).join(\" | \");\n console.log(header);\n console.log(widths.map((w) => \"-\".repeat(w)).join(\"-+-\"));\n\n for (const row of rows) {\n const line = keys\n .map((k, i) => {\n const val = String(row[k] ?? \"NULL\");\n return val.length > 60\n ? val.slice(0, 57) + \"...\"\n : val.padEnd(widths[i]);\n })\n .join(\" | \");\n console.log(line);\n }\n}\n\nexport default async function dbQuery(args: string[]): Promise<void> {\n const parsed = parseArgs(args);\n\n if (parsed.help === \"true\") {\n console.log(`Usage: pnpm action db-query --sql \"<query>\" [options]\n\nOptions:\n --sql <query> SQL SELECT query to run (required)\n --args <json> JSON array of positional SQL bind parameters\n --db <path> Path to SQLite database (default: data/app.db)\n --format json Output as JSON instead of a table\n --limit N Append LIMIT N if not already present\n --help Show this help message`);\n return;\n }\n\n const sql = parsed.sql;\n if (!sql) {\n fail('--sql is required. Example: --sql \"SELECT * FROM forms\"');\n }\n const sqlArgs = parseSqlArgs(parsed.args);\n\n // Safety: only allow read-only statements.\n // Strip leading SQL comments before checking the prefix.\n const stripped = sql\n .replace(/^\\s*--[^\\n]*\\n/gm, \"\")\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, \"\")\n .trim();\n const upper = stripped.toUpperCase();\n if (\n !upper.startsWith(\"SELECT\") &&\n !upper.startsWith(\"WITH\") &&\n !upper.startsWith(\"EXPLAIN\") &&\n !upper.startsWith(\"PRAGMA\")\n ) {\n fail(\n \"Only SELECT, WITH, EXPLAIN, and PRAGMA queries are allowed. Use db-exec for writes.\",\n );\n }\n assertNoSensitiveFrameworkTables(stripped, \"read\");\n\n // Resolve database URL: --db flag → DATABASE_URL env → default file path\n let url: string;\n if (parsed.db) {\n url = \"file:\" + path.resolve(parsed.db);\n } else if (getDatabaseUrl()) {\n url = getDatabaseUrl();\n } else {\n url = \"file:\" + path.resolve(process.cwd(), \"data\", \"app.db\");\n }\n\n let finalSql = sql;\n if (\n parsed.limit &&\n (upper.startsWith(\"SELECT\") || upper.startsWith(\"WITH\")) &&\n !/\\bLIMIT\\b/i.test(stripped)\n ) {\n const limitVal = parseInt(parsed.limit, 10);\n if (isNaN(limitVal) || limitVal < 1)\n fail(\"--limit must be a positive integer\");\n finalSql = `${sql} LIMIT ${limitVal}`;\n }\n\n // Postgres path\n if (isPostgresUrl(url)) {\n const { default: pg } = await import(\"postgres\");\n const pgSql = pg(url);\n try {\n const pgSqlText = normalizePostgresSql(finalSql, sqlArgs);\n let rows: Record<string, unknown>[] = [];\n await pgSql.begin(async (tx: any) => {\n // Temp views are session state. Keep setup/query/teardown on one\n // transaction-bound backend so pooled Postgres never retains them.\n const scoping = await buildScopingPostgres(tx);\n try {\n for (const stmt of scoping.setup) {\n await tx.unsafe(stmt);\n }\n\n const result =\n sqlArgs.length > 0\n ? await tx.unsafe(pgSqlText, sqlArgs as any[])\n : await tx.unsafe(pgSqlText);\n rows = Array.from(result);\n } finally {\n for (const stmt of scoping.teardown) {\n await tx.unsafe(stmt).catch(() => {});\n }\n }\n });\n const keys = rows.length > 0 ? Object.keys(rows[0]) : [];\n\n printTable(\n rows.length > 0 ? rows : keys.length > 0 ? rows : [],\n pgSqlText,\n parsed.format,\n );\n } finally {\n await pgSql.end();\n }\n return;\n }\n\n // libsql / SQLite path\n const client = await createSqliteScriptClient(url);\n\n try {\n // Set up user-scoped temp views in production\n const scoping = await buildScopingSqlite(client);\n for (const stmt of scoping.setup) {\n await client.execute(stmt);\n }\n\n const result =\n sqlArgs.length > 0\n ? await client.execute({ sql: finalSql, args: sqlArgs as any[] })\n : await client.execute(finalSql);\n const rows: Record<string, unknown>[] = result.rows.map((row) => {\n const obj: Record<string, unknown> = {};\n for (let i = 0; i < result.columns.length; i++) {\n obj[result.columns[i]] = row[i];\n }\n return obj;\n });\n\n printTable(rows, finalSql, parsed.format);\n\n // Tear down temp views\n for (const stmt of scoping.teardown) {\n await client.execute(stmt).catch(() => {});\n }\n } finally {\n client.close();\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/scripts/db/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAuNH,wBAA8B,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA0IpE"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/scripts/db/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AA0NH,wBAA8B,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAuIpE"}
@@ -9,9 +9,9 @@
9
9
  * pnpm action db-schema [--db path] [--format json]
10
10
  */
11
11
  import path from "path";
12
- import { createClient } from "@libsql/client";
13
- import { getDatabaseUrl, getDatabaseAuthToken } from "../../db/client.js";
12
+ import { getDatabaseUrl } from "../../db/client.js";
14
13
  import { parseArgs } from "../utils.js";
14
+ import { createSqliteScriptClient, } from "./sqlite-client.js";
15
15
  function isPostgresUrl(url) {
16
16
  return url.startsWith("postgres://") || url.startsWith("postgresql://");
17
17
  }
@@ -197,10 +197,7 @@ Options:
197
197
  return introspectPostgres(url, parsed);
198
198
  }
199
199
  // SQLite / libsql path
200
- const client = createClient({
201
- url,
202
- authToken: getDatabaseAuthToken(),
203
- });
200
+ const client = await createSqliteScriptClient(url);
204
201
  try {
205
202
  const tablesResult = await client.execute(`SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name`);
206
203
  const tables = tablesResult.rows.map((row) => ({
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/scripts/db/schema.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Core script: db-schema\n *\n * Inspects a SQLite or Postgres database and prints all tables, columns, types,\n * constraints, and foreign keys. Gives the agent full visibility\n * into the app's data model.\n *\n * Usage:\n * pnpm action db-schema [--db path] [--format json]\n */\n\nimport path from \"path\";\nimport { createClient, type Client } from \"@libsql/client\";\nimport { getDatabaseUrl, getDatabaseAuthToken } from \"../../db/client.js\";\nimport { parseArgs, fail } from \"../utils.js\";\n\ninterface ColumnInfo {\n name: string;\n type: string;\n notnull: boolean;\n pk: boolean;\n dflt_value: string | null;\n}\n\ninterface ForeignKey {\n from: string;\n table: string;\n to: string;\n}\n\ninterface TableInfo {\n name: string;\n columns: ColumnInfo[];\n foreignKeys: ForeignKey[];\n indexes: { name: string; unique: boolean; columns: string[] }[];\n}\n\nfunction isPostgresUrl(url: string): boolean {\n return url.startsWith(\"postgres://\") || url.startsWith(\"postgresql://\");\n}\n\nfunction databaseLabel(url: string): string {\n if (url.startsWith(\"file:\")) return url.slice(5);\n try {\n const parsed = new URL(url);\n const auth = parsed.username ? `${parsed.username}:***@` : \"\";\n return `${parsed.protocol}//${auth}${parsed.host}${parsed.pathname}`;\n } catch {\n return url.replace(/:\\/\\/([^:@\\s]+):([^@\\s]+)@/, \"://$1:***@\");\n }\n}\n\n/**\n * Execute a PRAGMA query and return the rows as plain objects.\n */\nasync function pragma(\n client: Client,\n pragmaQuery: string,\n): Promise<Record<string, unknown>[]> {\n const result = await client.execute(pragmaQuery);\n return result.rows.map((row) => {\n const obj: Record<string, unknown> = {};\n for (let i = 0; i < result.columns.length; i++) {\n obj[result.columns[i]] = row[i];\n }\n return obj;\n });\n}\n\n// ---------------------------------------------------------------------------\n// Postgres introspection\n// ---------------------------------------------------------------------------\n\nasync function introspectPostgres(\n url: string,\n parsed: Record<string, string>,\n): Promise<void> {\n const { default: pg } = await import(\"postgres\");\n const sql = pg(url);\n\n try {\n // List tables\n const tables: { name: string }[] = await sql`\n SELECT table_name as name\n FROM information_schema.tables\n WHERE table_schema = 'public' AND table_type = 'BASE TABLE'\n ORDER BY table_name\n `;\n\n const tableInfos: TableInfo[] = [];\n\n for (const t of tables) {\n // Columns\n const cols: any[] = await sql`\n SELECT\n column_name as name,\n data_type as type,\n CASE WHEN is_nullable = 'NO' THEN 1 ELSE 0 END as notnull,\n column_default as dflt_value\n FROM information_schema.columns\n WHERE table_name = ${t.name}\n ORDER BY ordinal_position\n `;\n\n // Primary keys\n const pks: any[] = await sql`\n SELECT kcu.column_name\n FROM information_schema.table_constraints tc\n JOIN information_schema.key_column_usage kcu\n ON tc.constraint_name = kcu.constraint_name\n AND tc.table_schema = kcu.table_schema\n WHERE tc.table_name = ${t.name}\n AND tc.constraint_type = 'PRIMARY KEY'\n `;\n const pkSet = new Set(pks.map((p) => p.column_name));\n\n // Foreign keys\n const fks: any[] = await sql`\n SELECT\n kcu.column_name as \"from\",\n ccu.table_name as \"table\",\n ccu.column_name as \"to\"\n FROM information_schema.table_constraints tc\n JOIN information_schema.key_column_usage kcu\n ON tc.constraint_name = kcu.constraint_name\n JOIN information_schema.constraint_column_usage ccu\n ON tc.constraint_name = ccu.constraint_name\n WHERE tc.table_name = ${t.name}\n AND tc.constraint_type = 'FOREIGN KEY'\n `;\n\n // Indexes\n const idxRows: any[] = await sql`\n SELECT indexname as name, indexdef\n FROM pg_indexes\n WHERE tablename = ${t.name} AND schemaname = 'public'\n `;\n const indexes = idxRows.map((idx) => {\n const unique = /\\bUNIQUE\\b/i.test(idx.indexdef);\n // Extract column list from CREATE INDEX ... (col1, col2)\n const colMatch = idx.indexdef.match(/\\(([^)]+)\\)/);\n const columns = colMatch\n ? colMatch[1].split(\",\").map((c: string) => c.trim())\n : [];\n return { name: idx.name, unique, columns };\n });\n\n tableInfos.push({\n name: t.name,\n columns: cols.map((c) => ({\n name: c.name,\n type: c.type || \"ANY\",\n notnull: c.notnull === 1,\n pk: pkSet.has(c.name),\n dflt_value: c.dflt_value as string | null,\n })),\n foreignKeys: fks.map((fk) => ({\n from: fk.from,\n table: fk.table,\n to: fk.to,\n })),\n indexes,\n });\n }\n\n if (parsed.format === \"json\") {\n console.log(\n JSON.stringify(\n { database: databaseLabel(url), tables: tableInfos },\n null,\n 2,\n ),\n );\n return;\n }\n\n // Human-readable output\n console.log(`Database: ${databaseLabel(url)}`);\n console.log(`Tables: ${tableInfos.length}\\n`);\n\n for (const table of tableInfos) {\n console.log(`Table: ${table.name} (${table.columns.length} columns)`);\n\n const fkMap = new Map<string, string>();\n for (const fk of table.foreignKeys) {\n fkMap.set(fk.from, `${fk.table}(${fk.to})`);\n }\n\n const nameWidth = Math.max(...table.columns.map((c) => c.name.length));\n const typeWidth = Math.max(...table.columns.map((c) => c.type.length));\n\n for (const col of table.columns) {\n const parts: string[] = [];\n if (col.pk) parts.push(\"PRIMARY KEY\");\n if (col.notnull && !col.pk) parts.push(\"NOT NULL\");\n if (col.dflt_value !== null) parts.push(`DEFAULT ${col.dflt_value}`);\n const fkRef = fkMap.get(col.name);\n if (fkRef) parts.push(`→ ${fkRef}`);\n\n const constraint = parts.length > 0 ? ` ${parts.join(\", \")}` : \"\";\n console.log(\n ` ${col.name.padEnd(nameWidth)} ${col.type.padEnd(typeWidth)}${constraint}`,\n );\n }\n\n if (table.indexes.length > 0) {\n console.log(` Indexes:`);\n for (const idx of table.indexes) {\n const unique = idx.unique ? \"UNIQUE \" : \"\";\n console.log(` ${unique}${idx.name} (${idx.columns.join(\", \")})`);\n }\n }\n\n console.log();\n }\n } finally {\n await sql.end();\n }\n}\n\n// ---------------------------------------------------------------------------\n// Main entry\n// ---------------------------------------------------------------------------\n\nexport default async function dbSchema(args: string[]): Promise<void> {\n const parsed = parseArgs(args);\n\n if (parsed.help === \"true\") {\n console.log(`Usage: pnpm action db-schema [--db <path>] [--format json]\n\nOptions:\n --db <path> Path to SQLite database (default: data/app.db)\n --format json Output as JSON instead of human-readable text\n --help Show this help message`);\n return;\n }\n\n // Resolve database URL: --db flag → DATABASE_URL env → default file path\n let url: string;\n if (parsed.db) {\n url = \"file:\" + path.resolve(parsed.db);\n } else if (getDatabaseUrl()) {\n url = getDatabaseUrl();\n } else {\n url = \"file:\" + path.resolve(process.cwd(), \"data\", \"app.db\");\n }\n\n // Postgres path\n if (isPostgresUrl(url)) {\n return introspectPostgres(url, parsed);\n }\n\n // SQLite / libsql path\n const client = createClient({\n url,\n authToken: getDatabaseAuthToken(),\n });\n\n try {\n const tablesResult = await client.execute(\n `SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name`,\n );\n const tables = tablesResult.rows.map((row) => ({\n name: row[0] as string,\n }));\n\n const tableInfos: TableInfo[] = [];\n\n for (const t of tables) {\n const escaped = t.name.replace(/\"/g, '\"\"');\n\n const columns = await pragma(client, `PRAGMA table_info(\"${escaped}\")`);\n const fks = await pragma(client, `PRAGMA foreign_key_list(\"${escaped}\")`);\n const idxList = await pragma(client, `PRAGMA index_list(\"${escaped}\")`);\n\n const indexes: { name: string; unique: boolean; columns: string[] }[] =\n [];\n for (const idx of idxList) {\n const idxName = idx.name as string;\n if (idxName.startsWith(\"sqlite_\")) continue;\n const idxInfo = await pragma(\n client,\n `PRAGMA index_info(\"${idxName.replace(/\"/g, '\"\"')}\")`,\n );\n indexes.push({\n name: idxName,\n unique: idx.unique === 1,\n columns: idxInfo.map((c) => c.name as string),\n });\n }\n\n tableInfos.push({\n name: t.name,\n columns: columns.map((c) => ({\n name: c.name as string,\n type: (c.type as string) || \"ANY\",\n notnull: c.notnull === 1,\n pk: c.pk === 1,\n dflt_value: c.dflt_value as string | null,\n })),\n foreignKeys: fks.map((fk) => ({\n from: fk.from as string,\n table: fk.table as string,\n to: fk.to as string,\n })),\n indexes,\n });\n }\n\n if (parsed.format === \"json\") {\n const dbLabel = databaseLabel(url);\n console.log(\n JSON.stringify({ database: dbLabel, tables: tableInfos }, null, 2),\n );\n return;\n }\n\n // Human-readable output\n const dbLabel = databaseLabel(url);\n console.log(`Database: ${dbLabel}`);\n console.log(`Tables: ${tableInfos.length}\\n`);\n\n for (const table of tableInfos) {\n console.log(`Table: ${table.name} (${table.columns.length} columns)`);\n\n // Build FK lookup for annotation\n const fkMap = new Map<string, string>();\n for (const fk of table.foreignKeys) {\n fkMap.set(fk.from, `${fk.table}(${fk.to})`);\n }\n\n // Find max widths for alignment\n const nameWidth = Math.max(...table.columns.map((c) => c.name.length));\n const typeWidth = Math.max(...table.columns.map((c) => c.type.length));\n\n for (const col of table.columns) {\n const parts: string[] = [];\n if (col.pk) parts.push(\"PRIMARY KEY\");\n if (col.notnull && !col.pk) parts.push(\"NOT NULL\");\n if (col.dflt_value !== null) parts.push(`DEFAULT ${col.dflt_value}`);\n const fkRef = fkMap.get(col.name);\n if (fkRef) parts.push(`→ ${fkRef}`);\n\n const constraint = parts.length > 0 ? ` ${parts.join(\", \")}` : \"\";\n console.log(\n ` ${col.name.padEnd(nameWidth)} ${col.type.padEnd(typeWidth)}${constraint}`,\n );\n }\n\n if (table.indexes.length > 0) {\n console.log(` Indexes:`);\n for (const idx of table.indexes) {\n const unique = idx.unique ? \"UNIQUE \" : \"\";\n console.log(` ${unique}${idx.name} (${idx.columns.join(\", \")})`);\n }\n }\n\n console.log();\n }\n } finally {\n client.close();\n }\n}\n"]}
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/scripts/db/schema.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Core script: db-schema\n *\n * Inspects a SQLite or Postgres database and prints all tables, columns, types,\n * constraints, and foreign keys. Gives the agent full visibility\n * into the app's data model.\n *\n * Usage:\n * pnpm action db-schema [--db path] [--format json]\n */\n\nimport path from \"path\";\nimport { getDatabaseUrl } from \"../../db/client.js\";\nimport { parseArgs, fail } from \"../utils.js\";\nimport {\n createSqliteScriptClient,\n type SqliteScriptClient,\n} from \"./sqlite-client.js\";\n\ninterface ColumnInfo {\n name: string;\n type: string;\n notnull: boolean;\n pk: boolean;\n dflt_value: string | null;\n}\n\ninterface ForeignKey {\n from: string;\n table: string;\n to: string;\n}\n\ninterface TableInfo {\n name: string;\n columns: ColumnInfo[];\n foreignKeys: ForeignKey[];\n indexes: { name: string; unique: boolean; columns: string[] }[];\n}\n\nfunction isPostgresUrl(url: string): boolean {\n return url.startsWith(\"postgres://\") || url.startsWith(\"postgresql://\");\n}\n\nfunction databaseLabel(url: string): string {\n if (url.startsWith(\"file:\")) return url.slice(5);\n try {\n const parsed = new URL(url);\n const auth = parsed.username ? `${parsed.username}:***@` : \"\";\n return `${parsed.protocol}//${auth}${parsed.host}${parsed.pathname}`;\n } catch {\n return url.replace(/:\\/\\/([^:@\\s]+):([^@\\s]+)@/, \"://$1:***@\");\n }\n}\n\n/**\n * Execute a PRAGMA query and return the rows as plain objects.\n */\nasync function pragma(\n client: SqliteScriptClient,\n pragmaQuery: string,\n): Promise<Record<string, unknown>[]> {\n const result = await client.execute(pragmaQuery);\n return result.rows.map((row) => {\n const obj: Record<string, unknown> = {};\n for (let i = 0; i < result.columns.length; i++) {\n obj[result.columns[i]] = row[i];\n }\n return obj;\n });\n}\n\n// ---------------------------------------------------------------------------\n// Postgres introspection\n// ---------------------------------------------------------------------------\n\nasync function introspectPostgres(\n url: string,\n parsed: Record<string, string>,\n): Promise<void> {\n const { default: pg } = await import(\"postgres\");\n const sql = pg(url);\n\n try {\n // List tables\n const tables: { name: string }[] = await sql`\n SELECT table_name as name\n FROM information_schema.tables\n WHERE table_schema = 'public' AND table_type = 'BASE TABLE'\n ORDER BY table_name\n `;\n\n const tableInfos: TableInfo[] = [];\n\n for (const t of tables) {\n // Columns\n const cols: any[] = await sql`\n SELECT\n column_name as name,\n data_type as type,\n CASE WHEN is_nullable = 'NO' THEN 1 ELSE 0 END as notnull,\n column_default as dflt_value\n FROM information_schema.columns\n WHERE table_name = ${t.name}\n ORDER BY ordinal_position\n `;\n\n // Primary keys\n const pks: any[] = await sql`\n SELECT kcu.column_name\n FROM information_schema.table_constraints tc\n JOIN information_schema.key_column_usage kcu\n ON tc.constraint_name = kcu.constraint_name\n AND tc.table_schema = kcu.table_schema\n WHERE tc.table_name = ${t.name}\n AND tc.constraint_type = 'PRIMARY KEY'\n `;\n const pkSet = new Set(pks.map((p) => p.column_name));\n\n // Foreign keys\n const fks: any[] = await sql`\n SELECT\n kcu.column_name as \"from\",\n ccu.table_name as \"table\",\n ccu.column_name as \"to\"\n FROM information_schema.table_constraints tc\n JOIN information_schema.key_column_usage kcu\n ON tc.constraint_name = kcu.constraint_name\n JOIN information_schema.constraint_column_usage ccu\n ON tc.constraint_name = ccu.constraint_name\n WHERE tc.table_name = ${t.name}\n AND tc.constraint_type = 'FOREIGN KEY'\n `;\n\n // Indexes\n const idxRows: any[] = await sql`\n SELECT indexname as name, indexdef\n FROM pg_indexes\n WHERE tablename = ${t.name} AND schemaname = 'public'\n `;\n const indexes = idxRows.map((idx) => {\n const unique = /\\bUNIQUE\\b/i.test(idx.indexdef);\n // Extract column list from CREATE INDEX ... (col1, col2)\n const colMatch = idx.indexdef.match(/\\(([^)]+)\\)/);\n const columns = colMatch\n ? colMatch[1].split(\",\").map((c: string) => c.trim())\n : [];\n return { name: idx.name, unique, columns };\n });\n\n tableInfos.push({\n name: t.name,\n columns: cols.map((c) => ({\n name: c.name,\n type: c.type || \"ANY\",\n notnull: c.notnull === 1,\n pk: pkSet.has(c.name),\n dflt_value: c.dflt_value as string | null,\n })),\n foreignKeys: fks.map((fk) => ({\n from: fk.from,\n table: fk.table,\n to: fk.to,\n })),\n indexes,\n });\n }\n\n if (parsed.format === \"json\") {\n console.log(\n JSON.stringify(\n { database: databaseLabel(url), tables: tableInfos },\n null,\n 2,\n ),\n );\n return;\n }\n\n // Human-readable output\n console.log(`Database: ${databaseLabel(url)}`);\n console.log(`Tables: ${tableInfos.length}\\n`);\n\n for (const table of tableInfos) {\n console.log(`Table: ${table.name} (${table.columns.length} columns)`);\n\n const fkMap = new Map<string, string>();\n for (const fk of table.foreignKeys) {\n fkMap.set(fk.from, `${fk.table}(${fk.to})`);\n }\n\n const nameWidth = Math.max(...table.columns.map((c) => c.name.length));\n const typeWidth = Math.max(...table.columns.map((c) => c.type.length));\n\n for (const col of table.columns) {\n const parts: string[] = [];\n if (col.pk) parts.push(\"PRIMARY KEY\");\n if (col.notnull && !col.pk) parts.push(\"NOT NULL\");\n if (col.dflt_value !== null) parts.push(`DEFAULT ${col.dflt_value}`);\n const fkRef = fkMap.get(col.name);\n if (fkRef) parts.push(`→ ${fkRef}`);\n\n const constraint = parts.length > 0 ? ` ${parts.join(\", \")}` : \"\";\n console.log(\n ` ${col.name.padEnd(nameWidth)} ${col.type.padEnd(typeWidth)}${constraint}`,\n );\n }\n\n if (table.indexes.length > 0) {\n console.log(` Indexes:`);\n for (const idx of table.indexes) {\n const unique = idx.unique ? \"UNIQUE \" : \"\";\n console.log(` ${unique}${idx.name} (${idx.columns.join(\", \")})`);\n }\n }\n\n console.log();\n }\n } finally {\n await sql.end();\n }\n}\n\n// ---------------------------------------------------------------------------\n// Main entry\n// ---------------------------------------------------------------------------\n\nexport default async function dbSchema(args: string[]): Promise<void> {\n const parsed = parseArgs(args);\n\n if (parsed.help === \"true\") {\n console.log(`Usage: pnpm action db-schema [--db <path>] [--format json]\n\nOptions:\n --db <path> Path to SQLite database (default: data/app.db)\n --format json Output as JSON instead of human-readable text\n --help Show this help message`);\n return;\n }\n\n // Resolve database URL: --db flag → DATABASE_URL env → default file path\n let url: string;\n if (parsed.db) {\n url = \"file:\" + path.resolve(parsed.db);\n } else if (getDatabaseUrl()) {\n url = getDatabaseUrl();\n } else {\n url = \"file:\" + path.resolve(process.cwd(), \"data\", \"app.db\");\n }\n\n // Postgres path\n if (isPostgresUrl(url)) {\n return introspectPostgres(url, parsed);\n }\n\n // SQLite / libsql path\n const client = await createSqliteScriptClient(url);\n\n try {\n const tablesResult = await client.execute(\n `SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name`,\n );\n const tables = tablesResult.rows.map((row) => ({\n name: row[0] as string,\n }));\n\n const tableInfos: TableInfo[] = [];\n\n for (const t of tables) {\n const escaped = t.name.replace(/\"/g, '\"\"');\n\n const columns = await pragma(client, `PRAGMA table_info(\"${escaped}\")`);\n const fks = await pragma(client, `PRAGMA foreign_key_list(\"${escaped}\")`);\n const idxList = await pragma(client, `PRAGMA index_list(\"${escaped}\")`);\n\n const indexes: { name: string; unique: boolean; columns: string[] }[] =\n [];\n for (const idx of idxList) {\n const idxName = idx.name as string;\n if (idxName.startsWith(\"sqlite_\")) continue;\n const idxInfo = await pragma(\n client,\n `PRAGMA index_info(\"${idxName.replace(/\"/g, '\"\"')}\")`,\n );\n indexes.push({\n name: idxName,\n unique: idx.unique === 1,\n columns: idxInfo.map((c) => c.name as string),\n });\n }\n\n tableInfos.push({\n name: t.name,\n columns: columns.map((c) => ({\n name: c.name as string,\n type: (c.type as string) || \"ANY\",\n notnull: c.notnull === 1,\n pk: c.pk === 1,\n dflt_value: c.dflt_value as string | null,\n })),\n foreignKeys: fks.map((fk) => ({\n from: fk.from as string,\n table: fk.table as string,\n to: fk.to as string,\n })),\n indexes,\n });\n }\n\n if (parsed.format === \"json\") {\n const dbLabel = databaseLabel(url);\n console.log(\n JSON.stringify({ database: dbLabel, tables: tableInfos }, null, 2),\n );\n return;\n }\n\n // Human-readable output\n const dbLabel = databaseLabel(url);\n console.log(`Database: ${dbLabel}`);\n console.log(`Tables: ${tableInfos.length}\\n`);\n\n for (const table of tableInfos) {\n console.log(`Table: ${table.name} (${table.columns.length} columns)`);\n\n // Build FK lookup for annotation\n const fkMap = new Map<string, string>();\n for (const fk of table.foreignKeys) {\n fkMap.set(fk.from, `${fk.table}(${fk.to})`);\n }\n\n // Find max widths for alignment\n const nameWidth = Math.max(...table.columns.map((c) => c.name.length));\n const typeWidth = Math.max(...table.columns.map((c) => c.type.length));\n\n for (const col of table.columns) {\n const parts: string[] = [];\n if (col.pk) parts.push(\"PRIMARY KEY\");\n if (col.notnull && !col.pk) parts.push(\"NOT NULL\");\n if (col.dflt_value !== null) parts.push(`DEFAULT ${col.dflt_value}`);\n const fkRef = fkMap.get(col.name);\n if (fkRef) parts.push(`→ ${fkRef}`);\n\n const constraint = parts.length > 0 ? ` ${parts.join(\", \")}` : \"\";\n console.log(\n ` ${col.name.padEnd(nameWidth)} ${col.type.padEnd(typeWidth)}${constraint}`,\n );\n }\n\n if (table.indexes.length > 0) {\n console.log(` Indexes:`);\n for (const idx of table.indexes) {\n const unique = idx.unique ? \"UNIQUE \" : \"\";\n console.log(` ${unique}${idx.name} (${idx.columns.join(\", \")})`);\n }\n }\n\n console.log();\n }\n } finally {\n client.close();\n }\n}\n"]}
@@ -0,0 +1,15 @@
1
+ export interface SqliteScriptResult {
2
+ rows: any[];
3
+ columns: string[];
4
+ rowsAffected: number;
5
+ lastInsertRowid?: bigint | number;
6
+ }
7
+ export interface SqliteScriptClient {
8
+ execute(stmtOrSql: string | {
9
+ sql: string;
10
+ args?: any[];
11
+ }): Promise<SqliteScriptResult>;
12
+ close(): void | Promise<void>;
13
+ }
14
+ export declare function createSqliteScriptClient(url: string): Promise<SqliteScriptClient>;
15
+ //# sourceMappingURL=sqlite-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite-client.d.ts","sourceRoot":"","sources":["../../../src/scripts/db/sqlite-client.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,GAAG,EAAE,CAAC;IACZ,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACnC;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,CACL,SAAS,EAAE,MAAM,GAAG;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAA;KAAE,GAChD,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAC/B,KAAK,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/B;AAcD,wBAAsB,wBAAwB,CAC5C,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,kBAAkB,CAAC,CA0C7B"}
@@ -0,0 +1,51 @@
1
+ import { getDatabaseAuthToken, isLocalSqliteUrl, prepareLocalSqliteUrl, sqliteFilenameFromUrl, } from "../../db/client.js";
2
+ function sqliteRowsToLibsqlShape(rows) {
3
+ const records = rows;
4
+ const columns = records.length > 0 ? Object.keys(records[0]) : [];
5
+ return {
6
+ rows: records.map((row) => {
7
+ const values = columns.map((column) => row[column]);
8
+ return Object.assign(values, row);
9
+ }),
10
+ columns,
11
+ };
12
+ }
13
+ export async function createSqliteScriptClient(url) {
14
+ if (isLocalSqliteUrl(url)) {
15
+ const sqliteUrl = await prepareLocalSqliteUrl(url.startsWith("file:") ? url : `file:${url}`);
16
+ const { default: Database } = await import("better-sqlite3");
17
+ const sqlite = new Database(sqliteFilenameFromUrl(sqliteUrl));
18
+ sqlite.pragma("busy_timeout = 10000");
19
+ sqlite.pragma("journal_mode = WAL");
20
+ return {
21
+ async execute(stmtOrSql) {
22
+ const sql = typeof stmtOrSql === "string" ? stmtOrSql : stmtOrSql.sql;
23
+ const args = typeof stmtOrSql === "string" ? [] : (stmtOrSql.args ?? []);
24
+ const stmt = sqlite.prepare(sql);
25
+ if (stmt.reader) {
26
+ return {
27
+ ...sqliteRowsToLibsqlShape(stmt.all(...args)),
28
+ rowsAffected: 0,
29
+ };
30
+ }
31
+ const result = stmt.run(...args);
32
+ return {
33
+ rows: [],
34
+ columns: [],
35
+ rowsAffected: result.changes ?? 0,
36
+ lastInsertRowid: result.lastInsertRowid,
37
+ };
38
+ },
39
+ close() {
40
+ sqlite.close();
41
+ },
42
+ };
43
+ }
44
+ const { createClient } = await import("@libsql/client/web");
45
+ const client = createClient({
46
+ url,
47
+ authToken: getDatabaseAuthToken(),
48
+ });
49
+ return client;
50
+ }
51
+ //# sourceMappingURL=sqlite-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite-client.js","sourceRoot":"","sources":["../../../src/scripts/db/sqlite-client.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,oBAAoB,CAAC;AAgB5B,SAAS,uBAAuB,CAAC,IAAe;IAC9C,MAAM,OAAO,GAAG,IAAiC,CAAC;IAClD,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAClE,OAAO;QACL,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;YACxB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAU,CAAC;YAC7D,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACpC,CAAC,CAAC;QACF,OAAO;KACR,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,GAAW;IAEX,IAAI,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1B,MAAM,SAAS,GAAG,MAAM,qBAAqB,CAC3C,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,GAAG,EAAE,CAC9C,CAAC;QACF,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC;QAC7D,MAAM,MAAM,GAAG,IAAI,QAAQ,CAAC,qBAAqB,CAAC,SAAS,CAAC,CAAC,CAAC;QAC9D,MAAM,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC;QACtC,MAAM,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;QAEpC,OAAO;YACL,KAAK,CAAC,OAAO,CAAC,SAAS;gBACrB,MAAM,GAAG,GAAG,OAAO,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC;gBACtE,MAAM,IAAI,GACR,OAAO,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;gBAC9D,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;gBACjC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;oBAChB,OAAO;wBACL,GAAG,uBAAuB,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;wBAC7C,YAAY,EAAE,CAAC;qBAChB,CAAC;gBACJ,CAAC;gBACD,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;gBACjC,OAAO;oBACL,IAAI,EAAE,EAAE;oBACR,OAAO,EAAE,EAAE;oBACX,YAAY,EAAE,MAAM,CAAC,OAAO,IAAI,CAAC;oBACjC,eAAe,EAAE,MAAM,CAAC,eAAe;iBACxC,CAAC;YACJ,CAAC;YACD,KAAK;gBACH,MAAM,CAAC,KAAK,EAAE,CAAC;YACjB,CAAC;SACF,CAAC;IACJ,CAAC;IAED,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAC5D,MAAM,MAAM,GAAG,YAAY,CAAC;QAC1B,GAAG;QACH,SAAS,EAAE,oBAAoB,EAAE;KAClC,CAAC,CAAC;IACH,OAAO,MAAuC,CAAC;AACjD,CAAC","sourcesContent":["import {\n getDatabaseAuthToken,\n isLocalSqliteUrl,\n prepareLocalSqliteUrl,\n sqliteFilenameFromUrl,\n} from \"../../db/client.js\";\n\nexport interface SqliteScriptResult {\n rows: any[];\n columns: string[];\n rowsAffected: number;\n lastInsertRowid?: bigint | number;\n}\n\nexport interface SqliteScriptClient {\n execute(\n stmtOrSql: string | { sql: string; args?: any[] },\n ): Promise<SqliteScriptResult>;\n close(): void | Promise<void>;\n}\n\nfunction sqliteRowsToLibsqlShape(rows: unknown[]) {\n const records = rows as Record<string, unknown>[];\n const columns = records.length > 0 ? Object.keys(records[0]) : [];\n return {\n rows: records.map((row) => {\n const values = columns.map((column) => row[column]) as any[];\n return Object.assign(values, row);\n }),\n columns,\n };\n}\n\nexport async function createSqliteScriptClient(\n url: string,\n): Promise<SqliteScriptClient> {\n if (isLocalSqliteUrl(url)) {\n const sqliteUrl = await prepareLocalSqliteUrl(\n url.startsWith(\"file:\") ? url : `file:${url}`,\n );\n const { default: Database } = await import(\"better-sqlite3\");\n const sqlite = new Database(sqliteFilenameFromUrl(sqliteUrl));\n sqlite.pragma(\"busy_timeout = 10000\");\n sqlite.pragma(\"journal_mode = WAL\");\n\n return {\n async execute(stmtOrSql) {\n const sql = typeof stmtOrSql === \"string\" ? stmtOrSql : stmtOrSql.sql;\n const args =\n typeof stmtOrSql === \"string\" ? [] : (stmtOrSql.args ?? []);\n const stmt = sqlite.prepare(sql);\n if (stmt.reader) {\n return {\n ...sqliteRowsToLibsqlShape(stmt.all(...args)),\n rowsAffected: 0,\n };\n }\n const result = stmt.run(...args);\n return {\n rows: [],\n columns: [],\n rowsAffected: result.changes ?? 0,\n lastInsertRowid: result.lastInsertRowid,\n };\n },\n close() {\n sqlite.close();\n },\n };\n }\n\n const { createClient } = await import(\"@libsql/client/web\");\n const client = createClient({\n url,\n authToken: getDatabaseAuthToken(),\n });\n return client as unknown as SqliteScriptClient;\n}\n"]}
@@ -727,10 +727,11 @@ async function buildDatabaseConfig(dialect) {
727
727
  schema: sqliteAuthSchema,
728
728
  });
729
729
  }
730
- // Remote libsql (Turso)
731
- const { createClient } = await import("@libsql/client");
730
+ // Remote libsql (Turso). Use the web client to avoid serverless bundles
731
+ // depending on libsql's platform-specific native packages.
732
+ const { createClient } = await import("@libsql/client/web");
732
733
  const client = createClient({ url, authToken: getDatabaseAuthToken() });
733
- const { drizzle } = await import("drizzle-orm/libsql");
734
+ const { drizzle } = await import("drizzle-orm/libsql/web");
734
735
  const db = drizzle(client, { schema: sqliteAuthSchema });
735
736
  const { drizzleAdapter } = await import("better-auth/adapters/drizzle");
736
737
  return drizzleAdapter(db, {