@profullstack/libsql-pg 0.1.0 → 0.1.2

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/index.d.ts ADDED
@@ -0,0 +1,73 @@
1
+ // Type declarations for @profullstack/libsql-pg. The runtime mirrors @libsql/client;
2
+ // values are typed loosely on purpose so a drop-in swap compiles.
3
+ export type InValue = null | string | number | bigint | boolean | Uint8Array | Date;
4
+ export type InArgs = InValue[] | Record<string, InValue>;
5
+ export type InStatement = string | { sql: string; args?: InArgs };
6
+ export interface Row { [column: string]: any; [index: number]: any; length: number }
7
+ export interface ResultSet {
8
+ columns: string[];
9
+ columnTypes: string[];
10
+ rows: Row[];
11
+ rowsAffected: number;
12
+ lastInsertRowid: bigint | undefined;
13
+ }
14
+ export type TransactionMode = 'write' | 'read' | 'deferred';
15
+ export interface Transaction {
16
+ execute(stmt: InStatement): Promise<ResultSet>;
17
+ batch(stmts: InStatement[]): Promise<ResultSet[]>;
18
+ executeMultiple(sql: string): Promise<void>;
19
+ commit(): Promise<void>;
20
+ rollback(): Promise<void>;
21
+ close(): void;
22
+ readonly closed: boolean;
23
+ }
24
+ export interface Client {
25
+ execute(stmt: InStatement): Promise<ResultSet>;
26
+ batch(stmts: InStatement[], mode?: TransactionMode): Promise<ResultSet[]>;
27
+ transaction(mode?: TransactionMode): Promise<Transaction>;
28
+ executeMultiple(sql: string): Promise<void>;
29
+ sync(): Promise<void>;
30
+ close(): void;
31
+ readonly closed: boolean;
32
+ readonly protocol: 'postgres';
33
+ }
34
+ export interface Config {
35
+ url: string;
36
+ authToken?: string;
37
+ syncUrl?: string;
38
+ dialect?: 'sqlite' | 'postgres';
39
+ pool?: { max?: number; idleTimeoutMillis?: number; connectionTimeoutMillis?: number };
40
+ ssl?: any;
41
+ }
42
+ export function createClient(config: Config): Client;
43
+ export function connectionSettings(url: string, explicit?: Record<string, any>): Record<string, any>;
44
+ export function rewriteSql(sql: string, opts?: Record<string, any>): string;
45
+ export function rewriteStatement(sql: string, opts?: Record<string, any>): { sql: string; [k: string]: any };
46
+ export function createRewriter(opts?: Record<string, any>): (sql: string) => { sql: string; [k: string]: any };
47
+ export function rewriteFunctions(sql: string): string;
48
+ export function insertTarget(sql: string): { table: string; columns: string[] } | null;
49
+ export function jsonPathToArray(path: string): string;
50
+ export function unsupportedIdioms(sql: string): string[];
51
+ export function convertSchema(sql: string, opts?: Record<string, any>): string;
52
+ export function convertStatement(stmt: string, ctx: any, opts?: Record<string, any>): string | null;
53
+ export function convertDdl(sql: string): string;
54
+ export function mapType(declared: string, opts?: Record<string, any>): string;
55
+ export function positional(sql: string, args?: InValue[]): { sql: string; values: InValue[] };
56
+ export function named(sql: string, args: Record<string, InValue>): { sql: string; values: InValue[] };
57
+ export function bind(stmt: InStatement): { sql: string; values: InValue[] };
58
+ export function prepare(stmt: InStatement, opts?: Record<string, any>): { sql: string; values: InValue[] };
59
+ export function translateError(err: any, info?: Record<string, any>): Error;
60
+ export function ftsError(table: string, sql: string): Error;
61
+ export function toResultSet(res: any, opts?: Record<string, any>): ResultSet;
62
+ export function makeRow(columns: string[], values: any[]): Row;
63
+ export function emptyResultSet(): ResultSet;
64
+ export function copyDatabase(opts: Record<string, any>): Promise<any>;
65
+ export function verifyCopy(opts: Record<string, any>): Promise<any>;
66
+ export function orderTables(tables: any[]): any[];
67
+ export function referencedTables(sql: string): string[];
68
+ export function userTables(master: any[]): any[];
69
+ export function coerce(value: any, dataType: string): any;
70
+ export function insertSql(table: string, cols: string[]): string;
71
+ export function splitStatements(sql: string): string[];
72
+ export function codeMask(sql: string): string;
73
+ export function stripComments(sql: string): string;
package/index.js CHANGED
@@ -5,4 +5,4 @@ export { positional, named, bind, prepare } from './src/bind.js';
5
5
  export { translateError, ftsError } from './src/errors.js';
6
6
  export { toResultSet, makeRow, emptyResultSet } from './src/result.js';
7
7
  export { copyDatabase, verifyCopy, orderTables, referencedTables, userTables, coerce, insertSql } from './src/copy.js';
8
- export { splitStatements, codeMask } from './src/sqlparse.js';
8
+ export { splitStatements, codeMask, stripComments } from './src/sqlparse.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@profullstack/libsql-pg",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "type": "module",
5
5
  "description": "Drop-in replacement for @libsql/client that talks to Postgres, plus the tools to move a Turso/libSQL database into it: the same execute/batch/transaction surface, SQLite idioms rewritten on the way through, a schema converter and a row copier.",
6
6
  "keywords": [
@@ -57,6 +57,7 @@
57
57
  "access": "public"
58
58
  },
59
59
  "dependencies": {
60
+ "@profullstack/libsql-pg": "^0.1.1",
60
61
  "pg": "^8.13.0"
61
62
  },
62
63
  "peerDependencies": {
@@ -68,6 +69,9 @@
68
69
  }
69
70
  },
70
71
  "devDependencies": {
72
+ "@libsql/client": "^0.15.15"
73
+ },
74
+ "optionalDependencies": {
71
75
  "@libsql/client": "^0.15.0"
72
76
  }
73
77
  }
package/src/cli.js CHANGED
@@ -79,7 +79,7 @@ export async function main(argv, io = {}) {
79
79
  });
80
80
  if (typeof flags.out === 'string') {
81
81
  await writeFile(flags.out, converted);
82
- err(`wrote ${flags.out} (${converted.split('\n').filter((l) => /TODO/.test(l)).length} TODO line(s))\n`);
82
+ err(`wrote ${flags.out} (${converted.split('\n').filter((l) => /TODO/.test(l) && !/Review every TODO/.test(l)).length} TODO line(s))\n`);
83
83
  } else out(converted);
84
84
  return 0;
85
85
  }
package/src/schema.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { rewriteFunctions, rewriteStatement } from './rewrite.js';
2
- import { codeMask, matchParen, quoteIdent, replaceCode, splitStatements, splitTopLevel, unquote } from './sqlparse.js';
2
+ import { codeMask, matchParen, quoteIdent, replaceCode, splitStatements, splitTopLevel, stripComments, unquote } from './sqlparse.js';
3
3
 
4
4
  /**
5
5
  * SQLite DDL to Postgres DDL.
@@ -523,7 +523,7 @@ export function convertSchema(sql, opts = {}) {
523
523
  /** @type {ConvertContext} */
524
524
  const ctx = { tables: new Map(), usesPgcrypto: false, notes: [] };
525
525
  const out = [];
526
- for (const stmt of splitStatements(sql)) {
526
+ for (const stmt of splitStatements(stripComments(sql))) {
527
527
  const converted = convertStatement(stmt, ctx, opts);
528
528
  if (converted !== null) out.push(converted);
529
529
  }
package/src/sqlparse.js CHANGED
@@ -281,3 +281,40 @@ export function literalValue(text) {
281
281
  if (!/^'.*'$/s.test(t)) return null;
282
282
  return t.slice(1, -1).replace(/''/g, "'");
283
283
  }
284
+
285
+
286
+ /**
287
+ * Drop `-- ...` and `/* ... *\/` comments outside string literals and quoted
288
+ * identifiers. Column definitions with a trailing comment otherwise parse the
289
+ * comment as a column named `--`.
290
+ * @param {string} sql
291
+ */
292
+ export function stripComments(sql) {
293
+ let out = '';
294
+ let i = 0;
295
+ const len = sql.length;
296
+ while (i < len) {
297
+ const c = sql[i];
298
+ if (c === "'" || c === '"' || c === '`') {
299
+ let j = i + 1;
300
+ while (j < len) {
301
+ if (sql[j] === c) {
302
+ if (c === "'" && sql[j + 1] === "'") { j += 2; continue; }
303
+ break;
304
+ }
305
+ j++;
306
+ }
307
+ out += sql.slice(i, Math.min(j + 1, len));
308
+ i = j + 1;
309
+ } else if (c === '-' && sql[i + 1] === '-') {
310
+ while (i < len && sql[i] !== '\n') i++;
311
+ } else if (c === '/' && sql[i + 1] === '*') {
312
+ const end = sql.indexOf('*/', i + 2);
313
+ i = end === -1 ? len : end + 2;
314
+ } else {
315
+ out += c;
316
+ i++;
317
+ }
318
+ }
319
+ return out;
320
+ }