@framers/sql-storage-adapter 0.7.7 → 0.7.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.
Files changed (54) hide show
  1. package/README.md +48 -5
  2. package/dist/adapters/betterSqliteAdapter.d.ts +6 -0
  3. package/dist/adapters/betterSqliteAdapter.d.ts.map +1 -1
  4. package/dist/adapters/betterSqliteAdapter.js +9 -0
  5. package/dist/adapters/betterSqliteAdapter.js.map +1 -1
  6. package/dist/adapters/indexedDbAdapter.d.ts +11 -0
  7. package/dist/adapters/indexedDbAdapter.d.ts.map +1 -1
  8. package/dist/adapters/indexedDbAdapter.js +22 -0
  9. package/dist/adapters/indexedDbAdapter.js.map +1 -1
  10. package/dist/adapters/postgresAdapter.d.ts +10 -1
  11. package/dist/adapters/postgresAdapter.d.ts.map +1 -1
  12. package/dist/adapters/postgresAdapter.js +81 -4
  13. package/dist/adapters/postgresAdapter.js.map +1 -1
  14. package/dist/adapters/sqlJsAdapter.d.ts +9 -0
  15. package/dist/adapters/sqlJsAdapter.d.ts.map +1 -1
  16. package/dist/adapters/sqlJsAdapter.js +16 -0
  17. package/dist/adapters/sqlJsAdapter.js.map +1 -1
  18. package/dist/cjs/adapters/betterSqliteAdapter.d.ts +6 -0
  19. package/dist/cjs/adapters/betterSqliteAdapter.js +9 -0
  20. package/dist/cjs/adapters/indexedDbAdapter.d.ts +11 -0
  21. package/dist/cjs/adapters/indexedDbAdapter.js +21 -0
  22. package/dist/cjs/adapters/postgresAdapter.d.ts +10 -1
  23. package/dist/cjs/adapters/postgresAdapter.js +66 -4
  24. package/dist/cjs/adapters/sqlJsAdapter.d.ts +9 -0
  25. package/dist/cjs/adapters/sqlJsAdapter.js +15 -0
  26. package/dist/cjs/core/contracts/index.d.ts +26 -0
  27. package/dist/cjs/core/portable.d.ts +1 -0
  28. package/dist/cjs/core/portable.js +2 -0
  29. package/dist/cjs/features/migrations/ensureColumnExists.d.ts +14 -0
  30. package/dist/cjs/features/migrations/ensureColumnExists.js +54 -0
  31. package/dist/cjs/index.d.ts +1 -0
  32. package/dist/cjs/index.js +2 -0
  33. package/dist/cjs/shared/sqlFunctions.d.ts +5 -0
  34. package/dist/cjs/shared/sqlFunctions.js +33 -0
  35. package/dist/core/contracts/index.d.ts +26 -0
  36. package/dist/core/contracts/index.d.ts.map +1 -1
  37. package/dist/core/contracts/index.js.map +1 -1
  38. package/dist/core/portable.d.ts +1 -0
  39. package/dist/core/portable.d.ts.map +1 -1
  40. package/dist/core/portable.js +1 -0
  41. package/dist/core/portable.js.map +1 -1
  42. package/dist/features/migrations/ensureColumnExists.d.ts +14 -0
  43. package/dist/features/migrations/ensureColumnExists.d.ts.map +1 -0
  44. package/dist/features/migrations/ensureColumnExists.js +40 -0
  45. package/dist/features/migrations/ensureColumnExists.js.map +1 -0
  46. package/dist/index.d.ts +1 -0
  47. package/dist/index.d.ts.map +1 -1
  48. package/dist/index.js +1 -0
  49. package/dist/index.js.map +1 -1
  50. package/dist/shared/sqlFunctions.d.ts +5 -0
  51. package/dist/shared/sqlFunctions.d.ts.map +1 -0
  52. package/dist/shared/sqlFunctions.js +9 -0
  53. package/dist/shared/sqlFunctions.js.map +1 -0
  54. package/package.json +2 -6
@@ -232,6 +232,34 @@ const unqualifiedCreateExtension = (statement) => {
232
232
  return name.identifier;
233
233
  };
234
234
  const asError = (value) => value instanceof Error ? value : new Error(String(value));
235
+ const BATCH_SAVEPOINT = "storage_adapter_batch";
236
+ const runBatchSteps = async (trx, operations) => {
237
+ const results = [];
238
+ const errors = [];
239
+ for (const [index, operation] of operations.entries()) {
240
+ await trx.exec(`SAVEPOINT ${BATCH_SAVEPOINT}`);
241
+ let result;
242
+ try {
243
+ result = await trx.run(operation.statement, operation.parameters);
244
+ } catch (error) {
245
+ await trx.exec(`ROLLBACK TO SAVEPOINT ${BATCH_SAVEPOINT}`);
246
+ await trx.exec(`RELEASE SAVEPOINT ${BATCH_SAVEPOINT}`);
247
+ errors.push({ index, error: asError(error) });
248
+ continue;
249
+ }
250
+ await trx.exec(`RELEASE SAVEPOINT ${BATCH_SAVEPOINT}`);
251
+ results.push(result);
252
+ }
253
+ return { successful: results.length, failed: errors.length, results, errors };
254
+ };
255
+ const batchInOwnTransaction = async (transaction, operations) => {
256
+ try {
257
+ return await transaction((trx) => runBatchSteps(trx, operations));
258
+ } catch (error) {
259
+ return { successful: 0, failed: operations.length, errors: [{ index: -1, error: asError(error) }] };
260
+ }
261
+ };
262
+ const TRANSACTION_ALREADY_OPEN = "A transaction is already open on this connection. Run its statements through the handle its callback receives.";
235
263
  const keepRollbackError = (error, rollbackError) => {
236
264
  if (typeof error !== "object" || error === null || !Object.isExtensible(error))
237
265
  return;
@@ -469,6 +497,17 @@ class PostgresTransactionAdapter {
469
497
  return this.afterEnd.transaction(fn);
470
498
  return fn(this);
471
499
  }
500
+ /**
501
+ * Runs the operations inside this transaction, each under a savepoint, going
502
+ * on past one that fails; the ones that succeed commit or roll back with the
503
+ * transaction. After the transaction has ended, the batch runs in a
504
+ * transaction of its own where afterEnd runs it.
505
+ */
506
+ async batch(operations) {
507
+ if (this.ended)
508
+ return batchInOwnTransaction((fn) => this.afterEnd.transaction(fn), operations);
509
+ return runBatchSteps(this, operations);
510
+ }
472
511
  async close() {
473
512
  }
474
513
  /** @internal runTransaction() calls this when the transaction has ended. */
@@ -536,9 +575,8 @@ class PostgresConnectionAdapter {
536
575
  async transaction(fn, options) {
537
576
  const begin = beginStatement(options);
538
577
  const client = this.live();
539
- if (this.transactionOpen) {
540
- throw new Error("A transaction is already open on this connection. Run its statements through the handle its callback receives.");
541
- }
578
+ if (this.transactionOpen)
579
+ throw new Error(TRANSACTION_ALREADY_OPEN);
542
580
  this.transactionOpen = true;
543
581
  try {
544
582
  return await runTransaction(client, begin, fn, this.capabilities, this.segment, this, this.onBroken);
@@ -546,6 +584,16 @@ class PostgresConnectionAdapter {
546
584
  this.transactionOpen = false;
547
585
  }
548
586
  }
587
+ /**
588
+ * Runs the operations in one transaction on this connection, as the
589
+ * adapter's batch() does on the pool.
590
+ */
591
+ async batch(operations) {
592
+ this.live();
593
+ if (this.transactionOpen)
594
+ throw new Error(TRANSACTION_ALREADY_OPEN);
595
+ return batchInOwnTransaction((fn) => this.transaction(fn), operations);
596
+ }
549
597
  async close() {
550
598
  }
551
599
  /** @internal withConnection() calls this when the callback ends. */
@@ -575,8 +623,10 @@ class PostgresAdapter {
575
623
  // Native JSON/JSONB support
576
624
  "arrays",
577
625
  // Native array data types
578
- "prepared"
626
+ "prepared",
579
627
  // Prepared statements for security/performance
628
+ "batch"
629
+ // batch(): one transaction, a savepoint per operation
580
630
  ]);
581
631
  this.pool = null;
582
632
  this.pgModule = null;
@@ -827,6 +877,18 @@ class PostgresAdapter {
827
877
  client.release(releaseError ?? connection.brokenBy ?? watch.failure());
828
878
  }
829
879
  }
880
+ /**
881
+ * Runs the operations in one transaction, going on past one that fails, as
882
+ * the better-sqlite3 adapter's batch does. Each operation runs under a
883
+ * savepoint, since a failed statement aborts a PostgreSQL transaction; a
884
+ * failure rolls back to it and is reported with its index in `errors`. The
885
+ * operations that succeed commit together. When the transaction itself
886
+ * fails, nothing commits and the error is reported at index -1.
887
+ */
888
+ async batch(operations) {
889
+ this.requirePool();
890
+ return batchInOwnTransaction((fn) => this.transaction(fn), operations);
891
+ }
830
892
  /**
831
893
  * The pool's counts, or null when the adapter is not open. A pool of the
832
894
  * caller's that does not count its connections, as pg's Pool does, reads 0.
@@ -1,5 +1,6 @@
1
1
  import type { SqlJsConfig } from 'sql.js';
2
2
  import type { StorageAdapter, StorageCapability, StorageOpenOptions, StorageParameters, StorageRunResult } from '../core/contracts/index.js';
3
+ import { type SqlFunction, type SqlFunctionOptions } from '../shared/sqlFunctions.js';
3
4
  /** sql.js's own configuration (`locateFile` and the rest), and the adapter's segment. */
4
5
  export type SqlJsAdapterOptions = SqlJsConfig & {
5
6
  /**
@@ -20,6 +21,8 @@ export declare class SqlJsAdapter implements StorageAdapter {
20
21
  private filePath?;
21
22
  /** Foreign-key enforcement as open() was asked for it (undefined: the engine default); sql.js forgets the PRAGMA when export() reopens the connection. */
22
23
  private foreignKeys;
24
+ /** The functions registerFunction made callable from SQL, registered again after each reopening. */
25
+ private readonly sqlFunctions;
23
26
  private readonly runSerializedTransaction;
24
27
  /**
25
28
  * Open transaction depth. > 0 means a SQLite-level transaction is in
@@ -52,6 +55,12 @@ export declare class SqlJsAdapter implements StorageAdapter {
52
55
  private ensureOpen;
53
56
  /** Applies the connection settings open() was asked for: sql.js loses them whenever export() reopens the connection. */
54
57
  private applyConnectionSettings;
58
+ /**
59
+ * Makes a JavaScript function callable from SQL under `name`. It is
60
+ * registered again whenever sql.js reopens the connection (each save to a
61
+ * file), which drops the functions it had.
62
+ */
63
+ registerFunction(name: string, fn: SqlFunction, _options?: SqlFunctionOptions): void;
55
64
  private persistIfNeeded;
56
65
  }
57
66
  /**
@@ -36,6 +36,7 @@ var import_fs = __toESM(require("fs"));
36
36
  var import_path = __toESM(require("path"));
37
37
  var import_parameterUtils = require("../shared/parameterUtils.js");
38
38
  var import_sqlPlaceholders = require("../shared/sqlPlaceholders.js");
39
+ var import_sqlFunctions = require("../shared/sqlFunctions.js");
39
40
  var import_serializedTransaction = require("../shared/serializedTransaction.js");
40
41
  var import_segment = require("../shared/segment.js");
41
42
  const normaliseRowId = (value) => {
@@ -59,6 +60,7 @@ class SqlJsAdapter {
59
60
  this.kind = "sqljs";
60
61
  this.SQL = null;
61
62
  this.db = null;
63
+ this.sqlFunctions = /* @__PURE__ */ new Map();
62
64
  this.runSerializedTransaction = (0, import_serializedTransaction.createSerializedTransactionRunner)();
63
65
  this.transactionDepth = 0;
64
66
  const { segment, ...sqlJsConfig } = adapterOptions;
@@ -227,6 +229,19 @@ class SqlJsAdapter {
227
229
  if (this.foreignKeys !== void 0) {
228
230
  this.db.run(`PRAGMA foreign_keys = ${this.foreignKeys ? "ON" : "OFF"};`);
229
231
  }
232
+ for (const [name, fn] of this.sqlFunctions) {
233
+ this.db.create_function(name, fn);
234
+ }
235
+ }
236
+ /**
237
+ * Makes a JavaScript function callable from SQL under `name`. It is
238
+ * registered again whenever sql.js reopens the connection (each save to a
239
+ * file), which drops the functions it had.
240
+ */
241
+ registerFunction(name, fn, _options = {}) {
242
+ this.sqlFunctions.set((0, import_sqlFunctions.checkFunctionName)(name), fn);
243
+ if (this.db)
244
+ this.db.create_function(name, fn);
230
245
  }
231
246
  async persistIfNeeded() {
232
247
  if (!this.filePath || !hasFsAccess()) {
@@ -220,6 +220,32 @@ export interface StorageAdapter {
220
220
  * @throws {Error} If adapter doesn't support prepared statements
221
221
  */
222
222
  prepare?<T = unknown>(statement: string): PreparedStatement<T>;
223
+ /**
224
+ * Makes a JavaScript function callable from SQL under `name` (if supported:
225
+ * the better-sqlite3, sql.js and IndexedDB adapters). The function takes as
226
+ * many arguments as it declares (`fn.length`).
227
+ *
228
+ * @param name - An identifier: letters, digits and underscores
229
+ * @param fn - The function; SQL values arrive as its arguments
230
+ * @param options - `deterministic` (better-sqlite3)
231
+ * @throws {Error} If the name is not an identifier
232
+ * @example
233
+ * db.registerFunction?.('slugify', (title) => String(title).toLowerCase(), { deterministic: true });
234
+ * const rows = await db.all('SELECT slugify(title) AS slug FROM posts');
235
+ */
236
+ registerFunction?(name: string, fn: SqlFunction, options?: SqlFunctionOptions): void;
237
+ }
238
+ /** A JavaScript function SQL can call (see `StorageAdapter.registerFunction`). */
239
+ export type SqlFunction = (...args: unknown[]) => unknown;
240
+ /** Options for `StorageAdapter.registerFunction`. */
241
+ export interface SqlFunctionOptions {
242
+ /**
243
+ * The function returns the same result for the same arguments, which SQLite
244
+ * requires of a function in an expression index, a partial index or a
245
+ * generated column. better-sqlite3 takes it; sql.js registers every function
246
+ * as non-deterministic.
247
+ */
248
+ deterministic?: boolean;
223
249
  }
224
250
  /**
225
251
  * Prepared statement interface for repeated query execution.
@@ -21,6 +21,7 @@ export { isUniqueViolation } from '../shared/errors.js';
21
21
  export { withHooks } from '../shared/withHooks.js';
22
22
  export { setStorageLogger, getStorageLogger, type StorageLogger } from '../shared/logger.js';
23
23
  export * from '../features/migrations/schemaMigrations.js';
24
+ export * from '../features/migrations/ensureColumnExists.js';
24
25
  export * from '../features/auth/authJsAdapter.js';
25
26
  export * from '../shared/parameterUtils.js';
26
27
  //# sourceMappingURL=portable.d.ts.map
@@ -49,6 +49,7 @@ var import_errors = require("../shared/errors.js");
49
49
  var import_withHooks = require("../shared/withHooks.js");
50
50
  var import_logger = require("../shared/logger.js");
51
51
  __reExport(portable_exports, require("../features/migrations/schemaMigrations.js"), module.exports);
52
+ __reExport(portable_exports, require("../features/migrations/ensureColumnExists.js"), module.exports);
52
53
  __reExport(portable_exports, require("../features/auth/authJsAdapter.js"), module.exports);
53
54
  __reExport(portable_exports, require("../shared/parameterUtils.js"), module.exports);
54
55
  // Annotate the CommonJS export names for ESM import in node:
@@ -69,6 +70,7 @@ __reExport(portable_exports, require("../shared/parameterUtils.js"), module.expo
69
70
  withHooks,
70
71
  ...require("../types/index.js"),
71
72
  ...require("../features/migrations/schemaMigrations.js"),
73
+ ...require("../features/migrations/ensureColumnExists.js"),
72
74
  ...require("../features/auth/authJsAdapter.js"),
73
75
  ...require("../shared/parameterUtils.js")
74
76
  });
@@ -0,0 +1,14 @@
1
+ import type { StorageAdapter } from '../../core/contracts/index.js';
2
+ /**
3
+ * Adds `column` to `table` with `definition` (its type and constraints, as
4
+ * SQL: `TEXT NOT NULL DEFAULT 'none'`) when the table lacks it, on PostgreSQL
5
+ * or SQLite. Resolves true when it added the column and false when the table
6
+ * had it. The table may be schema-qualified on PostgreSQL (`app.notes`).
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * await ensureColumnExists(db, 'notes', 'archived_at', d.columnType('timestamp'));
11
+ * ```
12
+ */
13
+ export declare function ensureColumnExists(db: StorageAdapter, table: string, column: string, definition: string): Promise<boolean>;
14
+ //# sourceMappingURL=ensureColumnExists.d.ts.map
@@ -0,0 +1,54 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+ var ensureColumnExists_exports = {};
19
+ __export(ensureColumnExists_exports, {
20
+ ensureColumnExists: () => ensureColumnExists
21
+ });
22
+ module.exports = __toCommonJS(ensureColumnExists_exports);
23
+ var import_features = require("../../core/contracts/features.js");
24
+ const IDENTIFIER = /^[A-Za-z_][A-Za-z0-9_]*$/;
25
+ const checkIdentifier = (what, value) => {
26
+ if (typeof value !== "string" || !IDENTIFIER.test(value)) {
27
+ throw new Error(`The ${what} must be an SQL identifier (letters, digits and underscores); got ${JSON.stringify(value)}.`);
28
+ }
29
+ return value;
30
+ };
31
+ async function ensureColumnExists(db, table, column, definition) {
32
+ const dialect = (0, import_features.createStorageFeatures)(db).dialect.name;
33
+ const parts = typeof table === "string" ? table.split(".") : [table];
34
+ const schema = dialect === "postgres" && parts.length === 2 ? checkIdentifier("schema", parts[0]) : null;
35
+ const name = checkIdentifier("table name", schema ? parts[1] : table);
36
+ checkIdentifier("column name", column);
37
+ if (dialect === "postgres") {
38
+ const found = await db.get(`SELECT 1 AS found FROM information_schema.columns
39
+ WHERE table_schema = COALESCE(?, current_schema()) AND table_name = lower(?) AND column_name = lower(?)`, [schema ? schema.toLowerCase() : null, name, column]);
40
+ if (found)
41
+ return false;
42
+ await db.exec(`ALTER TABLE ${schema ? `${schema}.` : ""}${name} ADD COLUMN IF NOT EXISTS ${column} ${definition}`);
43
+ return true;
44
+ }
45
+ const columns = await db.all("SELECT name FROM pragma_table_info(?)", [name]);
46
+ if (columns.some((existing) => existing.name.toLowerCase() === column.toLowerCase()))
47
+ return false;
48
+ await db.exec(`ALTER TABLE ${name} ADD COLUMN ${column} ${definition}`);
49
+ return true;
50
+ }
51
+ // Annotate the CommonJS export names for ESM import in node:
52
+ 0 && (module.exports = {
53
+ ensureColumnExists
54
+ });
@@ -13,6 +13,7 @@ export * from './features/migrations/dataExport.js';
13
13
  export * from './features/migrations/dataImport.js';
14
14
  export * from './features/migrations/migration.js';
15
15
  export * from './features/migrations/schemaMigrations.js';
16
+ export * from './features/migrations/ensureColumnExists.js';
16
17
  export * from './features/auth/authJsAdapter.js';
17
18
  export * from './features/sync/syncManager.js';
18
19
  export * from './shared/parameterUtils.js';
package/dist/cjs/index.js CHANGED
@@ -52,6 +52,7 @@ __reExport(dist_exports, require("./features/migrations/dataExport.js"), module.
52
52
  __reExport(dist_exports, require("./features/migrations/dataImport.js"), module.exports);
53
53
  __reExport(dist_exports, require("./features/migrations/migration.js"), module.exports);
54
54
  __reExport(dist_exports, require("./features/migrations/schemaMigrations.js"), module.exports);
55
+ __reExport(dist_exports, require("./features/migrations/ensureColumnExists.js"), module.exports);
55
56
  __reExport(dist_exports, require("./features/auth/authJsAdapter.js"), module.exports);
56
57
  __reExport(dist_exports, require("./features/sync/syncManager.js"), module.exports);
57
58
  __reExport(dist_exports, require("./shared/parameterUtils.js"), module.exports);
@@ -103,6 +104,7 @@ var import_logger = require("./shared/logger.js");
103
104
  ...require("./features/migrations/dataImport.js"),
104
105
  ...require("./features/migrations/migration.js"),
105
106
  ...require("./features/migrations/schemaMigrations.js"),
107
+ ...require("./features/migrations/ensureColumnExists.js"),
106
108
  ...require("./features/auth/authJsAdapter.js"),
107
109
  ...require("./features/sync/syncManager.js"),
108
110
  ...require("./shared/parameterUtils.js")
@@ -0,0 +1,5 @@
1
+ import type { SqlFunction, SqlFunctionOptions } from '../core/contracts/index.js';
2
+ export type { SqlFunction, SqlFunctionOptions };
3
+ /** Checks a SQL function name. */
4
+ export declare const checkFunctionName: (name: string) => string;
5
+ //# sourceMappingURL=sqlFunctions.d.ts.map
@@ -0,0 +1,33 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+ var sqlFunctions_exports = {};
19
+ __export(sqlFunctions_exports, {
20
+ checkFunctionName: () => checkFunctionName
21
+ });
22
+ module.exports = __toCommonJS(sqlFunctions_exports);
23
+ const FUNCTION_NAME = /^[A-Za-z_][A-Za-z0-9_]*$/;
24
+ const checkFunctionName = (name) => {
25
+ if (typeof name !== "string" || !FUNCTION_NAME.test(name)) {
26
+ throw new Error(`A SQL function name must be an identifier (letters, digits and underscores); got ${JSON.stringify(name)}.`);
27
+ }
28
+ return name;
29
+ };
30
+ // Annotate the CommonJS export names for ESM import in node:
31
+ 0 && (module.exports = {
32
+ checkFunctionName
33
+ });
@@ -220,6 +220,32 @@ export interface StorageAdapter {
220
220
  * @throws {Error} If adapter doesn't support prepared statements
221
221
  */
222
222
  prepare?<T = unknown>(statement: string): PreparedStatement<T>;
223
+ /**
224
+ * Makes a JavaScript function callable from SQL under `name` (if supported:
225
+ * the better-sqlite3, sql.js and IndexedDB adapters). The function takes as
226
+ * many arguments as it declares (`fn.length`).
227
+ *
228
+ * @param name - An identifier: letters, digits and underscores
229
+ * @param fn - The function; SQL values arrive as its arguments
230
+ * @param options - `deterministic` (better-sqlite3)
231
+ * @throws {Error} If the name is not an identifier
232
+ * @example
233
+ * db.registerFunction?.('slugify', (title) => String(title).toLowerCase(), { deterministic: true });
234
+ * const rows = await db.all('SELECT slugify(title) AS slug FROM posts');
235
+ */
236
+ registerFunction?(name: string, fn: SqlFunction, options?: SqlFunctionOptions): void;
237
+ }
238
+ /** A JavaScript function SQL can call (see `StorageAdapter.registerFunction`). */
239
+ export type SqlFunction = (...args: unknown[]) => unknown;
240
+ /** Options for `StorageAdapter.registerFunction`. */
241
+ export interface SqlFunctionOptions {
242
+ /**
243
+ * The function returns the same result for the same arguments, which SQLite
244
+ * requires of a function in an expression index, a partial index or a
245
+ * generated column. better-sqlite3 takes it; sql.js registers every function
246
+ * as non-deterministic.
247
+ */
248
+ deterministic?: boolean;
223
249
  }
224
250
  /**
225
251
  * Prepared statement interface for repeated query execution.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/contracts/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/contracts/index.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/contracts/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAsQH;;GAEG;AACH,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IAC/C,YAAY,OAAe,EAAW,SAAoB,EAAE;QAC1D,KAAK,CAAC,OAAO,CAAC,CAAC;QADqB,WAAM,GAAN,MAAM,CAAgB;QAE1D,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;IACvC,CAAC;CACF;AAED,+EAA+E;AAC/E,wCAAwC;AACxC,+EAA+E;AAE/E;;;GAGG;AACH,cAAc,eAAe,CAAC;AAE9B;;;GAGG;AACH,cAAc,SAAS,CAAC;AAQxB,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/contracts/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAmSH;;GAEG;AACH,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IAC/C,YAAY,OAAe,EAAW,SAAoB,EAAE;QAC1D,KAAK,CAAC,OAAO,CAAC,CAAC;QADqB,WAAM,GAAN,MAAM,CAAgB;QAE1D,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;IACvC,CAAC;CACF;AAED,+EAA+E;AAC/E,wCAAwC;AACxC,+EAA+E;AAE/E;;;GAGG;AACH,cAAc,eAAe,CAAC;AAE9B;;;GAGG;AACH,cAAc,SAAS,CAAC;AAQxB,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC"}
@@ -21,6 +21,7 @@ export { isUniqueViolation } from '../shared/errors.js';
21
21
  export { withHooks } from '../shared/withHooks.js';
22
22
  export { setStorageLogger, getStorageLogger, type StorageLogger } from '../shared/logger.js';
23
23
  export * from '../features/migrations/schemaMigrations.js';
24
+ export * from '../features/migrations/ensureColumnExists.js';
24
25
  export * from '../features/auth/authJsAdapter.js';
25
26
  export * from '../shared/parameterUtils.js';
26
27
  //# sourceMappingURL=portable.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"portable.d.ts","sourceRoot":"","sources":["../../src/core/portable.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,cAAc,UAAU,CAAC;AACzB,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC1F,cAAc,yCAAyC,CAAC;AACxD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,0BAA0B,CAAC"}
1
+ {"version":3,"file":"portable.d.ts","sourceRoot":"","sources":["../../src/core/portable.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,cAAc,UAAU,CAAC;AACzB,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC1F,cAAc,yCAAyC,CAAC;AACxD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,gCAAgC,CAAC;AAC/C,cAAc,0BAA0B,CAAC"}
@@ -21,6 +21,7 @@ export { isUniqueViolation } from '../shared/errors.js';
21
21
  export { withHooks } from '../shared/withHooks.js';
22
22
  export { setStorageLogger, getStorageLogger } from '../shared/logger.js';
23
23
  export * from '../features/migrations/schemaMigrations.js';
24
+ export * from '../features/migrations/ensureColumnExists.js';
24
25
  export * from '../features/auth/authJsAdapter.js';
25
26
  export * from '../shared/parameterUtils.js';
26
27
  //# sourceMappingURL=portable.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"portable.js","sourceRoot":"","sources":["../../src/core/portable.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,cAAc,UAAU,CAAC;AACzB,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAsB,MAAM,kBAAkB,CAAC;AAC1F,cAAc,yCAAyC,CAAC;AACxD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,0BAA0B,CAAC"}
1
+ {"version":3,"file":"portable.js","sourceRoot":"","sources":["../../src/core/portable.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,cAAc,UAAU,CAAC;AACzB,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAsB,MAAM,kBAAkB,CAAC;AAC1F,cAAc,yCAAyC,CAAC;AACxD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,gCAAgC,CAAC;AAC/C,cAAc,0BAA0B,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { StorageAdapter } from '../../core/contracts/index.js';
2
+ /**
3
+ * Adds `column` to `table` with `definition` (its type and constraints, as
4
+ * SQL: `TEXT NOT NULL DEFAULT 'none'`) when the table lacks it, on PostgreSQL
5
+ * or SQLite. Resolves true when it added the column and false when the table
6
+ * had it. The table may be schema-qualified on PostgreSQL (`app.notes`).
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * await ensureColumnExists(db, 'notes', 'archived_at', d.columnType('timestamp'));
11
+ * ```
12
+ */
13
+ export declare function ensureColumnExists(db: StorageAdapter, table: string, column: string, definition: string): Promise<boolean>;
14
+ //# sourceMappingURL=ensureColumnExists.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ensureColumnExists.d.ts","sourceRoot":"","sources":["../../../src/features/migrations/ensureColumnExists.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAY3D;;;;;;;;;;GAUG;AACH,wBAAsB,kBAAkB,CAAC,EAAE,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAsBhI"}
@@ -0,0 +1,40 @@
1
+ import { createStorageFeatures } from '../../core/contracts/features.js';
2
+ const IDENTIFIER = /^[A-Za-z_][A-Za-z0-9_]*$/;
3
+ const checkIdentifier = (what, value) => {
4
+ if (typeof value !== 'string' || !IDENTIFIER.test(value)) {
5
+ throw new Error(`The ${what} must be an SQL identifier (letters, digits and underscores); got ${JSON.stringify(value)}.`);
6
+ }
7
+ return value;
8
+ };
9
+ /**
10
+ * Adds `column` to `table` with `definition` (its type and constraints, as
11
+ * SQL: `TEXT NOT NULL DEFAULT 'none'`) when the table lacks it, on PostgreSQL
12
+ * or SQLite. Resolves true when it added the column and false when the table
13
+ * had it. The table may be schema-qualified on PostgreSQL (`app.notes`).
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * await ensureColumnExists(db, 'notes', 'archived_at', d.columnType('timestamp'));
18
+ * ```
19
+ */
20
+ export async function ensureColumnExists(db, table, column, definition) {
21
+ const dialect = createStorageFeatures(db).dialect.name;
22
+ const parts = typeof table === 'string' ? table.split('.') : [table];
23
+ const schema = dialect === 'postgres' && parts.length === 2 ? checkIdentifier('schema', parts[0]) : null;
24
+ const name = checkIdentifier('table name', schema ? parts[1] : table);
25
+ checkIdentifier('column name', column);
26
+ if (dialect === 'postgres') {
27
+ const found = await db.get(`SELECT 1 AS found FROM information_schema.columns
28
+ WHERE table_schema = COALESCE(?, current_schema()) AND table_name = lower(?) AND column_name = lower(?)`, [schema ? schema.toLowerCase() : null, name, column]);
29
+ if (found)
30
+ return false;
31
+ await db.exec(`ALTER TABLE ${schema ? `${schema}.` : ''}${name} ADD COLUMN IF NOT EXISTS ${column} ${definition}`);
32
+ return true;
33
+ }
34
+ const columns = await db.all('SELECT name FROM pragma_table_info(?)', [name]);
35
+ if (columns.some((existing) => existing.name.toLowerCase() === column.toLowerCase()))
36
+ return false;
37
+ await db.exec(`ALTER TABLE ${name} ADD COLUMN ${column} ${definition}`);
38
+ return true;
39
+ }
40
+ //# sourceMappingURL=ensureColumnExists.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ensureColumnExists.js","sourceRoot":"","sources":["../../../src/features/migrations/ensureColumnExists.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAEtE,MAAM,UAAU,GAAG,0BAA0B,CAAC;AAE9C,MAAM,eAAe,GAAG,CAAC,IAAY,EAAE,KAAa,EAAU,EAAE;IAC9D,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACzD,MAAM,IAAI,KAAK,CAAC,OAAO,IAAI,qEAAqE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC5H,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,EAAkB,EAAE,KAAa,EAAE,MAAc,EAAE,UAAkB;IAC5G,MAAM,OAAO,GAAG,qBAAqB,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC;IACvD,MAAM,KAAK,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACrE,MAAM,MAAM,GAAG,OAAO,KAAK,UAAU,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACzG,MAAM,IAAI,GAAG,eAAe,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACtE,eAAe,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;IAEvC,IAAI,OAAO,KAAK,UAAU,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,GAAG,CACxB;+GACyG,EACzG,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CACrD,CAAC;QACF,IAAI,KAAK;YAAE,OAAO,KAAK,CAAC;QACxB,MAAM,EAAE,CAAC,IAAI,CAAC,eAAe,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,6BAA6B,MAAM,IAAI,UAAU,EAAE,CAAC,CAAC;QACnH,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,GAAG,CAAmB,uCAAuC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IAChG,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC,WAAW,EAAE,CAAC;QAAE,OAAO,KAAK,CAAC;IACnG,MAAM,EAAE,CAAC,IAAI,CAAC,eAAe,IAAI,eAAe,MAAM,IAAI,UAAU,EAAE,CAAC,CAAC;IACxE,OAAO,IAAI,CAAC;AACd,CAAC"}
package/dist/index.d.ts CHANGED
@@ -13,6 +13,7 @@ export * from './features/migrations/dataExport.js';
13
13
  export * from './features/migrations/dataImport.js';
14
14
  export * from './features/migrations/migration.js';
15
15
  export * from './features/migrations/schemaMigrations.js';
16
+ export * from './features/migrations/ensureColumnExists.js';
16
17
  export * from './features/auth/authJsAdapter.js';
17
18
  export * from './features/sync/syncManager.js';
18
19
  export * from './shared/parameterUtils.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,SAAS,CAAC;AAGxB,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAGhC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,yBAAyB,CAAC;AACxC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,mCAAmC,CAAC;AAClD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,qBAAqB,CAAC;AACpC,cAAc,+BAA+B,CAAC;AAQ9C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,kCAAkC,CAAC;AACjD,cAAc,kCAAkC,CAAC;AACjD,cAAc,iCAAiC,CAAC;AAChD,cAAc,wCAAwC,CAAC;AACvD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6BAA6B,CAAC;AAM5C,cAAc,yBAAyB,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAMjF,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,SAAS,CAAC;AAGxB,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAGhC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,yBAAyB,CAAC;AACxC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,mCAAmC,CAAC;AAClD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,qBAAqB,CAAC;AACpC,cAAc,+BAA+B,CAAC;AAQ9C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,kCAAkC,CAAC;AACjD,cAAc,kCAAkC,CAAC;AACjD,cAAc,iCAAiC,CAAC;AAChD,cAAc,wCAAwC,CAAC;AACvD,cAAc,0CAA0C,CAAC;AACzD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6BAA6B,CAAC;AAM5C,cAAc,yBAAyB,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAMjF,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
package/dist/index.js CHANGED
@@ -21,6 +21,7 @@ export * from './features/migrations/dataExport.js';
21
21
  export * from './features/migrations/dataImport.js';
22
22
  export * from './features/migrations/migration.js';
23
23
  export * from './features/migrations/schemaMigrations.js';
24
+ export * from './features/migrations/ensureColumnExists.js';
24
25
  export * from './features/auth/authJsAdapter.js';
25
26
  export * from './features/sync/syncManager.js';
26
27
  // Note: Cross-platform sync is available via separate entry point for cleaner imports.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,cAAc,SAAS,CAAC;AAExB,8EAA8E;AAC9E,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAEhC,+EAA+E;AAC/E,cAAc,gCAAgC,CAAC;AAC/C,cAAc,yBAAyB,CAAC;AACxC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,mCAAmC,CAAC;AAClD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,qBAAqB,CAAC;AACpC,cAAc,+BAA+B,CAAC;AAE9C,wEAAwE;AACxE,yDAAyD;AACzD,2HAA2H;AAC3H,mEAAmE;AAEnE,+EAA+E;AAC/E,cAAc,+BAA+B,CAAC;AAC9C,cAAc,kCAAkC,CAAC;AACjD,cAAc,kCAAkC,CAAC;AACjD,cAAc,iCAAiC,CAAC;AAChD,cAAc,wCAAwC,CAAC;AACvD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6BAA6B,CAAC;AAE5C,uFAAuF;AACvF,sFAAsF;AAEtF,+EAA+E;AAC/E,cAAc,yBAAyB,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEjF,6FAA6F;AAC7F,uGAAuG;AAEvG,iFAAiF;AACjF,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAsB,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,cAAc,SAAS,CAAC;AAExB,8EAA8E;AAC9E,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAEhC,+EAA+E;AAC/E,cAAc,gCAAgC,CAAC;AAC/C,cAAc,yBAAyB,CAAC;AACxC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,mCAAmC,CAAC;AAClD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,qBAAqB,CAAC;AACpC,cAAc,+BAA+B,CAAC;AAE9C,wEAAwE;AACxE,yDAAyD;AACzD,2HAA2H;AAC3H,mEAAmE;AAEnE,+EAA+E;AAC/E,cAAc,+BAA+B,CAAC;AAC9C,cAAc,kCAAkC,CAAC;AACjD,cAAc,kCAAkC,CAAC;AACjD,cAAc,iCAAiC,CAAC;AAChD,cAAc,wCAAwC,CAAC;AACvD,cAAc,0CAA0C,CAAC;AACzD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6BAA6B,CAAC;AAE5C,uFAAuF;AACvF,sFAAsF;AAEtF,+EAA+E;AAC/E,cAAc,yBAAyB,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEjF,6FAA6F;AAC7F,uGAAuG;AAEvG,iFAAiF;AACjF,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAsB,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { SqlFunction, SqlFunctionOptions } from '../core/contracts/index.js';
2
+ export type { SqlFunction, SqlFunctionOptions };
3
+ /** Checks a SQL function name. */
4
+ export declare const checkFunctionName: (name: string) => string;
5
+ //# sourceMappingURL=sqlFunctions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlFunctions.d.ts","sourceRoot":"","sources":["../../src/shared/sqlFunctions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEzE,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,CAAC;AAIhD,kCAAkC;AAClC,eAAO,MAAM,iBAAiB,SAAU,MAAM,KAAG,MAKhD,CAAC"}
@@ -0,0 +1,9 @@
1
+ const FUNCTION_NAME = /^[A-Za-z_][A-Za-z0-9_]*$/;
2
+ /** Checks a SQL function name. */
3
+ export const checkFunctionName = (name) => {
4
+ if (typeof name !== 'string' || !FUNCTION_NAME.test(name)) {
5
+ throw new Error(`A SQL function name must be an identifier (letters, digits and underscores); got ${JSON.stringify(name)}.`);
6
+ }
7
+ return name;
8
+ };
9
+ //# sourceMappingURL=sqlFunctions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlFunctions.js","sourceRoot":"","sources":["../../src/shared/sqlFunctions.ts"],"names":[],"mappings":"AAIA,MAAM,aAAa,GAAG,0BAA0B,CAAC;AAEjD,kCAAkC;AAClC,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,IAAY,EAAU,EAAE;IACxD,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1D,MAAM,IAAI,KAAK,CAAC,oFAAoF,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/H,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@framers/sql-storage-adapter",
3
- "version": "0.7.7",
3
+ "version": "0.7.8",
4
4
  "description": "Robust cross-platform SQL storage abstraction with automatic fallbacks and runtime detection",
5
5
  "type": "module",
6
6
  "main": "dist/cjs/index.js",
@@ -264,8 +264,7 @@
264
264
  "@aws-sdk/client-s3": "^3.0.0",
265
265
  "@capacitor-community/sqlite": "^6.0.0 || ^7.0.0 || ^8.0.0",
266
266
  "better-sqlite3": "^12.0.0 || ^13.0.0",
267
- "electron": ">=20.0.0",
268
- "pg": "^8.13.1"
267
+ "electron": ">=20.0.0"
269
268
  },
270
269
  "peerDependenciesMeta": {
271
270
  "@aws-sdk/client-s3": {
@@ -279,9 +278,6 @@
279
278
  },
280
279
  "electron": {
281
280
  "optional": true
282
- },
283
- "pg": {
284
- "optional": true
285
281
  }
286
282
  }
287
283
  }