@framers/sql-storage-adapter 0.7.3 → 0.7.5

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 (45) hide show
  1. package/README.md +45 -13
  2. package/dist/cjs/core/contracts/features.js +4 -2
  3. package/dist/cjs/core/contracts/fts.d.ts +20 -8
  4. package/dist/cjs/core/portable.d.ts +2 -0
  5. package/dist/cjs/core/portable.js +5 -0
  6. package/dist/cjs/features/auth/authJsAdapter.d.ts +110 -0
  7. package/dist/cjs/features/auth/authJsAdapter.js +251 -0
  8. package/dist/cjs/fts/PostgresFts.d.ts +14 -13
  9. package/dist/cjs/fts/PostgresFts.js +61 -33
  10. package/dist/cjs/fts/SqliteFts4.d.ts +28 -0
  11. package/dist/cjs/fts/SqliteFts4.js +67 -0
  12. package/dist/cjs/fts/SqliteFts5.d.ts +1 -0
  13. package/dist/cjs/fts/SqliteFts5.js +3 -0
  14. package/dist/cjs/index.d.ts +2 -0
  15. package/dist/cjs/index.js +5 -0
  16. package/dist/core/contracts/features.d.ts.map +1 -1
  17. package/dist/core/contracts/features.js +6 -2
  18. package/dist/core/contracts/features.js.map +1 -1
  19. package/dist/core/contracts/fts.d.ts +20 -8
  20. package/dist/core/contracts/fts.d.ts.map +1 -1
  21. package/dist/core/portable.d.ts +2 -0
  22. package/dist/core/portable.d.ts.map +1 -1
  23. package/dist/core/portable.js +2 -0
  24. package/dist/core/portable.js.map +1 -1
  25. package/dist/features/auth/authJsAdapter.d.ts +110 -0
  26. package/dist/features/auth/authJsAdapter.d.ts.map +1 -0
  27. package/dist/features/auth/authJsAdapter.js +248 -0
  28. package/dist/features/auth/authJsAdapter.js.map +1 -0
  29. package/dist/fts/PostgresFts.d.ts +14 -13
  30. package/dist/fts/PostgresFts.d.ts.map +1 -1
  31. package/dist/fts/PostgresFts.js +83 -39
  32. package/dist/fts/PostgresFts.js.map +1 -1
  33. package/dist/fts/SqliteFts4.d.ts +28 -0
  34. package/dist/fts/SqliteFts4.d.ts.map +1 -0
  35. package/dist/fts/SqliteFts4.js +56 -0
  36. package/dist/fts/SqliteFts4.js.map +1 -0
  37. package/dist/fts/SqliteFts5.d.ts +1 -0
  38. package/dist/fts/SqliteFts5.d.ts.map +1 -1
  39. package/dist/fts/SqliteFts5.js +3 -0
  40. package/dist/fts/SqliteFts5.js.map +1 -1
  41. package/dist/index.d.ts +2 -0
  42. package/dist/index.d.ts.map +1 -1
  43. package/dist/index.js +2 -0
  44. package/dist/index.js.map +1 -1
  45. package/package.json +11 -1
@@ -20,57 +20,85 @@ __export(PostgresFts_exports, {
20
20
  PostgresFts: () => PostgresFts
21
21
  });
22
22
  module.exports = __toCommonJS(PostgresFts_exports);
23
+ const INDEXES = /* @__PURE__ */ new Map();
24
+ const WEIGHTS = /* @__PURE__ */ new Set(["A", "B", "C", "D"]);
23
25
  class PostgresFts {
24
- constructor() {
25
- this._contentTable = "";
26
- this._columns = [];
27
- this._lang = "english";
28
- }
29
26
  createIndex(config) {
30
- const ct = config.contentTable ?? config.table;
31
- this._contentTable = ct;
32
- this._columns = config.columns;
33
- const colConcat = config.columns.map((c) => `COALESCE(${c}, '')`).join(" || ' ' || ");
34
- const lang = this._tokenizerToLang(config.tokenizer);
35
- this._lang = lang;
27
+ const index = {
28
+ contentTable: config.contentTable ?? config.table,
29
+ columns: config.columns,
30
+ lang: tokenizerToLang(config.tokenizer),
31
+ weights: checkWeights(config.columns, config.weights)
32
+ };
33
+ INDEXES.set(config.table, index);
34
+ const ct = index.contentTable;
36
35
  return [
37
36
  `ALTER TABLE ${ct} ADD COLUMN IF NOT EXISTS _tsv tsvector`,
38
37
  `CREATE INDEX IF NOT EXISTS idx_${config.table}_tsv ON ${ct} USING GIN(_tsv)`,
39
- `UPDATE ${ct} SET _tsv = to_tsvector('${lang}', ${colConcat}) WHERE _tsv IS NULL`
38
+ `UPDATE ${ct} SET _tsv = ${tsvector(index, index.columns.map((column) => `COALESCE(${column}, '')`))} WHERE _tsv IS NULL`
40
39
  ].join(";\n");
41
40
  }
42
- matchClause(_indexName, queryPlaceholder) {
43
- return `_tsv @@ plainto_tsquery('${this._lang}', ${queryPlaceholder})`;
41
+ matchClause(indexName, queryPlaceholder) {
42
+ return `_tsv @@ websearch_to_tsquery('${langOf(indexName)}', ${queryPlaceholder})`;
44
43
  }
45
- rankExpression(_indexName, queryPlaceholder) {
44
+ rankExpression(indexName, queryPlaceholder) {
46
45
  const qp = queryPlaceholder ?? "$1";
47
- return `ts_rank(_tsv, plainto_tsquery('${this._lang}', ${qp}))`;
46
+ return `ts_rank(_tsv, websearch_to_tsquery('${langOf(indexName)}', ${qp}))`;
47
+ }
48
+ relevanceOrder(indexName, queryPlaceholder) {
49
+ return `${this.rankExpression(indexName, queryPlaceholder)} DESC`;
48
50
  }
49
- rebuildCommand(_indexName) {
50
- const ct = this._contentTable;
51
- const colConcat = this._columns.map((c) => `COALESCE(${c}, '')`).join(" || ' ' || ");
52
- return `UPDATE ${ct} SET _tsv = to_tsvector('${this._lang}', ${colConcat})`;
51
+ rebuildCommand(indexName) {
52
+ const index = described(indexName);
53
+ return `UPDATE ${index.contentTable} SET _tsv = ${tsvector(index, index.columns.map((column) => `COALESCE(${column}, '')`))}`;
53
54
  }
54
- syncInsert(_indexName, _rowIdExpr, columns) {
55
- const ct = this._contentTable;
56
- const colConcat = columns.map((_, index) => `COALESCE($${index + 2}, '')`).join(" || ' ' || ");
57
- return `UPDATE ${ct} SET _tsv = to_tsvector('${this._lang}', ${colConcat}) WHERE id = $1`;
55
+ syncInsert(indexName, _rowIdExpr, columns) {
56
+ const index = described(indexName);
57
+ const values = columns.map((_, i) => `COALESCE($${i + 2}, '')`);
58
+ return `UPDATE ${index.contentTable} SET _tsv = ${tsvector({ ...index, columns }, values)} WHERE id = $1`;
58
59
  }
59
60
  sanitizeQuery(input) {
60
- return input;
61
+ return input.replace(/[*()":^~{}[\]\\-]/g, " ").split(/\s+/).filter((word) => word.length > 0 && word.toLowerCase() !== "or").map((word) => `"${word}"`).join(" or ");
61
62
  }
62
63
  joinClause(contentTable, contentAlias, _ftsAlias, _indexName) {
63
64
  return `${contentTable} ${contentAlias}`;
64
65
  }
65
- /** Map FTS5-style tokenizer strings to Postgres text search configurations. */
66
- _tokenizerToLang(tokenizer) {
67
- if (!tokenizer)
68
- return "english";
69
- if (tokenizer.includes("porter"))
70
- return "english";
71
- return "simple";
72
- }
73
66
  }
67
+ const tokenizerToLang = (tokenizer) => {
68
+ if (!tokenizer)
69
+ return "english";
70
+ if (tokenizer.includes("porter"))
71
+ return "english";
72
+ return "simple";
73
+ };
74
+ const checkWeights = (columns, weights) => {
75
+ if (!weights)
76
+ return void 0;
77
+ for (const [column, weight] of Object.entries(weights)) {
78
+ if (!columns.includes(column))
79
+ throw new Error(`weights names ${JSON.stringify(column)}, which is not one of the indexed columns.`);
80
+ if (!WEIGHTS.has(weight))
81
+ throw new Error(`The weight of ${column} must be 'A', 'B', 'C' or 'D'; got ${JSON.stringify(weight)}.`);
82
+ }
83
+ return weights;
84
+ };
85
+ const tsvector = (index, values) => {
86
+ if (!index.weights)
87
+ return `to_tsvector('${index.lang}', ${values.join(" || ' ' || ")})`;
88
+ return values.map((value, i) => {
89
+ const weight = index.weights[index.columns[i]];
90
+ const vector = `to_tsvector('${index.lang}', ${value})`;
91
+ return weight ? `setweight(${vector}, '${weight}')` : vector;
92
+ }).join(" || ");
93
+ };
94
+ const described = (indexName) => {
95
+ const index = INDEXES.get(indexName);
96
+ if (!index) {
97
+ throw new Error(`No PostgreSQL full-text index named ${JSON.stringify(indexName)} has been described in this process: run its createIndex() first (it is idempotent).`);
98
+ }
99
+ return index;
100
+ };
101
+ const langOf = (indexName) => INDEXES.get(indexName)?.lang ?? "english";
74
102
  // Annotate the CommonJS export names for ESM import in node:
75
103
  0 && (module.exports = {
76
104
  PostgresFts
@@ -0,0 +1,28 @@
1
+ import type { IFullTextSearch } from '../core/contracts/fts.js';
2
+ /**
3
+ * SQLite FTS4 full-text search, for sql.js and the IndexedDB adapter: the
4
+ * stock sql.js build compiles SQLite with FTS3 and FTS4 and without FTS5.
5
+ *
6
+ * Uses FTS4 virtual tables with external content, the porter, unicode61 or
7
+ * simple tokenizer, and rowid joins to the content table. FTS4 has no rank
8
+ * column; relevanceOrder orders by the length of `offsets()`, which grows with
9
+ * the number of matching terms, so the best match comes first.
10
+ */
11
+ export declare class SqliteFts4 implements IFullTextSearch {
12
+ createIndex(config: {
13
+ table: string;
14
+ columns: string[];
15
+ contentTable?: string;
16
+ tokenizer?: string;
17
+ }): string;
18
+ matchClause(indexName: string, queryPlaceholder: string): string;
19
+ rankExpression(indexName: string, _queryPlaceholder?: string): string;
20
+ relevanceOrder(indexName: string, _queryPlaceholder?: string): string;
21
+ rebuildCommand(indexName: string): string;
22
+ syncInsert(indexName: string, rowIdExpr: string, columns: string[]): string;
23
+ sanitizeQuery(input: string): string;
24
+ joinClause(contentTable: string, contentAlias: string, ftsAlias: string, indexName: string): string;
25
+ /** An FTS5-style tokenizer string as an FTS4 tokenizer name. */
26
+ private tokenizer;
27
+ }
28
+ //# sourceMappingURL=SqliteFts4.d.ts.map
@@ -0,0 +1,67 @@
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 SqliteFts4_exports = {};
19
+ __export(SqliteFts4_exports, {
20
+ SqliteFts4: () => SqliteFts4
21
+ });
22
+ module.exports = __toCommonJS(SqliteFts4_exports);
23
+ class SqliteFts4 {
24
+ createIndex(config) {
25
+ const parts = [...config.columns];
26
+ if (config.contentTable)
27
+ parts.push(`content="${config.contentTable}"`);
28
+ parts.push(`tokenize=${this.tokenizer(config.tokenizer)}`);
29
+ return `CREATE VIRTUAL TABLE IF NOT EXISTS ${config.table} USING fts4(${parts.join(", ")})`;
30
+ }
31
+ matchClause(indexName, queryPlaceholder) {
32
+ return `${indexName} MATCH ${queryPlaceholder}`;
33
+ }
34
+ rankExpression(indexName, _queryPlaceholder) {
35
+ return `length(offsets(${indexName}))`;
36
+ }
37
+ relevanceOrder(indexName, _queryPlaceholder) {
38
+ return `length(offsets(${indexName})) DESC`;
39
+ }
40
+ rebuildCommand(indexName) {
41
+ return `INSERT INTO ${indexName}(${indexName}) VALUES('rebuild')`;
42
+ }
43
+ syncInsert(indexName, rowIdExpr, columns) {
44
+ const placeholders = columns.map(() => "?").join(", ");
45
+ return `INSERT INTO ${indexName} (docid, ${columns.join(", ")}) VALUES (${rowIdExpr}, ${placeholders})`;
46
+ }
47
+ sanitizeQuery(input) {
48
+ return input.replace(/[*()":^~{}[\]\\]/g, "").split(/\s+/).filter((word) => word.length > 0).map((word) => `"${word}"`).join(" OR ");
49
+ }
50
+ joinClause(contentTable, contentAlias, ftsAlias, indexName) {
51
+ return `${indexName} ${ftsAlias} JOIN ${contentTable} ${contentAlias} ON ${contentAlias}.rowid = ${ftsAlias}.docid`;
52
+ }
53
+ /** An FTS5-style tokenizer string as an FTS4 tokenizer name. */
54
+ tokenizer(tokenizer) {
55
+ if (!tokenizer)
56
+ return "unicode61";
57
+ if (tokenizer.includes("porter"))
58
+ return "porter";
59
+ if (tokenizer.includes("unicode61"))
60
+ return "unicode61";
61
+ return "simple";
62
+ }
63
+ }
64
+ // Annotate the CommonJS export names for ESM import in node:
65
+ 0 && (module.exports = {
66
+ SqliteFts4
67
+ });
@@ -14,6 +14,7 @@ export declare class SqliteFts5 implements IFullTextSearch {
14
14
  }): string;
15
15
  matchClause(indexName: string, queryPlaceholder: string): string;
16
16
  rankExpression(indexName: string, _queryPlaceholder?: string): string;
17
+ relevanceOrder(indexName: string, _queryPlaceholder?: string): string;
17
18
  rebuildCommand(indexName: string): string;
18
19
  syncInsert(indexName: string, rowIdExpr: string, columns: string[]): string;
19
20
  sanitizeQuery(input: string): string;
@@ -38,6 +38,9 @@ class SqliteFts5 {
38
38
  rankExpression(indexName, _queryPlaceholder) {
39
39
  return `${indexName}.rank`;
40
40
  }
41
+ relevanceOrder(indexName, _queryPlaceholder) {
42
+ return `${indexName}.rank`;
43
+ }
41
44
  rebuildCommand(indexName) {
42
45
  return `INSERT INTO ${indexName}(${indexName}) VALUES('rebuild')`;
43
46
  }
@@ -13,12 +13,14 @@ 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/auth/authJsAdapter.js';
16
17
  export * from './features/sync/syncManager.js';
17
18
  export * from './shared/parameterUtils.js';
18
19
  export { segmentFilePath, segmentName, validateSegment } from './shared/segment.js';
19
20
  export { SqliteDialect } from './dialects/SqliteDialect.js';
20
21
  export { PostgresDialect } from './dialects/PostgresDialect.js';
21
22
  export { SqliteFts5 } from './fts/SqliteFts5.js';
23
+ export { SqliteFts4 } from './fts/SqliteFts4.js';
22
24
  export { PostgresFts } from './fts/PostgresFts.js';
23
25
  export { NodeBlobCodec } from './codecs/NodeBlobCodec.js';
24
26
  export { BrowserBlobCodec } from './codecs/BrowserBlobCodec.js';
package/dist/cjs/index.js CHANGED
@@ -25,6 +25,7 @@ __export(dist_exports, {
25
25
  PostgresFts: () => import_PostgresFts.PostgresFts,
26
26
  SqliteDialect: () => import_SqliteDialect.SqliteDialect,
27
27
  SqliteFileExporter: () => import_SqliteFileExporter.SqliteFileExporter,
28
+ SqliteFts4: () => import_SqliteFts4.SqliteFts4,
28
29
  SqliteFts5: () => import_SqliteFts5.SqliteFts5,
29
30
  createStorageFeatures: () => import_features.createStorageFeatures,
30
31
  getStorageLogger: () => import_logger.getStorageLogger,
@@ -50,12 +51,14 @@ __reExport(dist_exports, require("./features/migrations/dataExport.js"), module.
50
51
  __reExport(dist_exports, require("./features/migrations/dataImport.js"), module.exports);
51
52
  __reExport(dist_exports, require("./features/migrations/migration.js"), module.exports);
52
53
  __reExport(dist_exports, require("./features/migrations/schemaMigrations.js"), module.exports);
54
+ __reExport(dist_exports, require("./features/auth/authJsAdapter.js"), module.exports);
53
55
  __reExport(dist_exports, require("./features/sync/syncManager.js"), module.exports);
54
56
  __reExport(dist_exports, require("./shared/parameterUtils.js"), module.exports);
55
57
  var import_segment = require("./shared/segment.js");
56
58
  var import_SqliteDialect = require("./dialects/SqliteDialect.js");
57
59
  var import_PostgresDialect = require("./dialects/PostgresDialect.js");
58
60
  var import_SqliteFts5 = require("./fts/SqliteFts5.js");
61
+ var import_SqliteFts4 = require("./fts/SqliteFts4.js");
59
62
  var import_PostgresFts = require("./fts/PostgresFts.js");
60
63
  var import_NodeBlobCodec = require("./codecs/NodeBlobCodec.js");
61
64
  var import_BrowserBlobCodec = require("./codecs/BrowserBlobCodec.js");
@@ -73,6 +76,7 @@ var import_logger = require("./shared/logger.js");
73
76
  PostgresFts,
74
77
  SqliteDialect,
75
78
  SqliteFileExporter,
79
+ SqliteFts4,
76
80
  SqliteFts5,
77
81
  createStorageFeatures,
78
82
  getStorageLogger,
@@ -96,6 +100,7 @@ var import_logger = require("./shared/logger.js");
96
100
  ...require("./features/migrations/dataImport.js"),
97
101
  ...require("./features/migrations/migration.js"),
98
102
  ...require("./features/migrations/schemaMigrations.js"),
103
+ ...require("./features/auth/authJsAdapter.js"),
99
104
  ...require("./features/sync/syncManager.js"),
100
105
  ...require("./shared/parameterUtils.js")
101
106
  });
@@ -1 +1 @@
1
- {"version":3,"file":"features.d.ts","sourceRoot":"","sources":["../../../src/core/contracts/features.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAmCjD;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;IAC7B,QAAQ,CAAC,GAAG,EAAE,eAAe,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAC;CACtC;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,cAAc,GAAG,eAAe,CAa9E"}
1
+ {"version":3,"file":"features.d.ts","sourceRoot":"","sources":["../../../src/core/contracts/features.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAoCjD;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;IAC7B,QAAQ,CAAC,GAAG,EAAE,eAAe,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAC;CACtC;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,cAAc,GAAG,eAAe,CAgB9E"}
@@ -1,6 +1,7 @@
1
1
  import { SqliteDialect } from '../../dialects/SqliteDialect.js';
2
2
  import { PostgresDialect } from '../../dialects/PostgresDialect.js';
3
3
  import { SqliteFts5 } from '../../fts/SqliteFts5.js';
4
+ import { SqliteFts4 } from '../../fts/SqliteFts4.js';
4
5
  import { PostgresFts } from '../../fts/PostgresFts.js';
5
6
  import { NodeBlobCodec } from '../../codecs/NodeBlobCodec.js';
6
7
  import { BrowserBlobCodec } from '../../codecs/BrowserBlobCodec.js';
@@ -29,12 +30,15 @@ function extractPostgresConnectionString(adapter) {
29
30
  * dialect, FTS, BLOB codec, and exporter implementations.
30
31
  */
31
32
  export function createStorageFeatures(adapter) {
32
- const isPostgres = adapter.kind === 'postgres';
33
+ // The Supabase adapter runs PostgreSQL too.
34
+ const isPostgres = adapter.kind === 'postgres' || adapter.kind === 'supabase-postgres';
35
+ // sql.js, and the IndexedDB adapter over it, have FTS3 and FTS4 and no FTS5.
36
+ const hasFts5 = adapter.kind !== 'sqljs' && adapter.kind !== 'indexeddb';
33
37
  const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';
34
38
  const postgresConnectionString = isPostgres ? extractPostgresConnectionString(adapter) : undefined;
35
39
  return {
36
40
  dialect: isPostgres ? new PostgresDialect() : new SqliteDialect(),
37
- fts: isPostgres ? new PostgresFts() : new SqliteFts5(),
41
+ fts: isPostgres ? new PostgresFts() : hasFts5 ? new SqliteFts5() : new SqliteFts4(),
38
42
  blobCodec: isBrowser ? new BrowserBlobCodec() : new NodeBlobCodec(),
39
43
  exporter: isPostgres
40
44
  ? new PostgresExporter(postgresConnectionString)
@@ -1 +1 @@
1
- {"version":3,"file":"features.js","sourceRoot":"","sources":["../../../src/core/contracts/features.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAC3E,OAAO,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AAYvE,SAAS,+BAA+B,CAAC,OAAuB;IAC9D,MAAM,OAAO,GAAI,OAAqE,CAAC,OAAO,CAAC;IAC/F,IAAI,CAAC,OAAO;QAAE,OAAO,SAAS,CAAC;IAC/B,IAAI,OAAO,CAAC,gBAAgB;QAAE,OAAO,OAAO,CAAC,gBAAgB,CAAC;IAC9D,IAAI,CAAC,OAAO,CAAC,QAAQ;QAAE,OAAO,SAAS,CAAC;IAExC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,WAAW,CAAC;IACzC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC;IAClC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAClE,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,kBAAkB,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACpF,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,QAAQ,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/C,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,CAAC;IACvD,OAAO,gBAAgB,IAAI,GAAG,IAAI,IAAI,IAAI,IAAI,OAAO,CAAC,QAAQ,GAAG,QAAQ,EAAE,CAAC;AAC9E,CAAC;AAeD;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,OAAuB;IAC3D,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,KAAK,UAAU,CAAC;IAC/C,MAAM,SAAS,GAAG,OAAO,MAAM,KAAK,WAAW,IAAI,OAAO,MAAM,CAAC,QAAQ,KAAK,WAAW,CAAC;IAC1F,MAAM,wBAAwB,GAAG,UAAU,CAAC,CAAC,CAAC,+BAA+B,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAEnG,OAAO;QACL,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,IAAI,eAAe,EAAE,CAAC,CAAC,CAAC,IAAI,aAAa,EAAE;QACjE,GAAG,EAAE,UAAU,CAAC,CAAC,CAAC,IAAI,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI,UAAU,EAAE;QACtD,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,gBAAgB,EAAE,CAAC,CAAC,CAAC,IAAI,aAAa,EAAE;QACnE,QAAQ,EAAE,UAAU;YAClB,CAAC,CAAC,IAAI,gBAAgB,CAAC,wBAAwB,CAAC;YAChD,CAAC,CAAC,IAAI,kBAAkB,CAAC,OAAO,CAAC;KACpC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"features.js","sourceRoot":"","sources":["../../../src/core/contracts/features.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,9 @@
1
1
  /**
2
2
  * Full-text search abstraction.
3
3
  *
4
- * SQLite implementations use FTS5 virtual tables.
5
- * Postgres implementations use tsvector columns with GIN indexes.
4
+ * better-sqlite3 uses FTS5 virtual tables; sql.js and IndexedDB use FTS4, which
5
+ * their stock sql.js build has (it has no FTS5). Postgres implementations use
6
+ * tsvector columns with GIN indexes.
6
7
  * Methods return SQL strings — no database calls.
7
8
  */
8
9
  export interface IFullTextSearch {
@@ -13,25 +14,36 @@ export interface IFullTextSearch {
13
14
  * @param config.columns - Columns to index.
14
15
  * @param config.contentTable - Source table (for external-content FTS5).
15
16
  * @param config.tokenizer - Tokenizer config (e.g. 'porter ascii').
17
+ * @param config.weights - PostgreSQL: a weight per column (A highest, D lowest) for ranking. The SQLite engines rank without it.
16
18
  */
17
19
  createIndex(config: {
18
20
  table: string;
19
21
  columns: string[];
20
22
  contentTable?: string;
21
23
  tokenizer?: string;
24
+ weights?: Record<string, 'A' | 'B' | 'C' | 'D'>;
22
25
  }): string;
23
26
  /**
24
27
  * Generate a WHERE clause fragment for full-text matching.
25
28
  * SQLite: `memory_traces_fts MATCH ?`
26
- * Postgres: `memory_traces._tsv @@ plainto_tsquery('english', $1)`
29
+ * Postgres: `_tsv @@ websearch_to_tsquery('english', $1)`, in the index's own language
27
30
  */
28
31
  matchClause(indexName: string, queryPlaceholder: string): string;
29
32
  /**
30
- * Generate an ORDER BY rank expression.
31
- * SQLite: `memory_traces_fts.rank`
32
- * Postgres: `ts_rank(memory_traces._tsv, plainto_tsquery('english', $1))`
33
+ * A rank value, in each engine's own direction.
34
+ * SQLite FTS5: `memory_traces_fts.rank` (lower is better)
35
+ * SQLite FTS4: `length(offsets(memory_traces_fts))` (higher is better)
36
+ * Postgres: `ts_rank(_tsv, websearch_to_tsquery('english', $1))` (higher is better)
37
+ * Use relevanceOrder to order the same way on every engine.
33
38
  */
34
39
  rankExpression(indexName: string, queryPlaceholder?: string): string;
40
+ /**
41
+ * An ORDER BY fragment that puts the best match first on every engine.
42
+ * SQLite FTS5: `memory_traces_fts.rank`
43
+ * SQLite FTS4: `length(offsets(memory_traces_fts)) DESC`
44
+ * Postgres: `ts_rank(_tsv, websearch_to_tsquery('english', $1)) DESC`
45
+ */
46
+ relevanceOrder(indexName: string, queryPlaceholder?: string): string;
35
47
  /**
36
48
  * Generate the rebuild/reindex command.
37
49
  * SQLite: `INSERT INTO fts_table(fts_table) VALUES('rebuild')`
@@ -46,8 +58,8 @@ export interface IFullTextSearch {
46
58
  syncInsert(indexName: string, rowIdExpr: string, columns: string[]): string;
47
59
  /**
48
60
  * Sanitize natural-language input into a safe search query.
49
- * SQLite: wraps words in quotes, strips FTS5 operators.
50
- * Postgres: pass-through (plainto_tsquery handles it).
61
+ * Every engine: the words, quoted, joined with OR, with the operators of
62
+ * the query syntax stripped, so it matches the same rows everywhere.
51
63
  */
52
64
  sanitizeQuery(input: string): string;
53
65
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"fts.d.ts","sourceRoot":"","sources":["../../../src/core/contracts/fts.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,WAAW,eAAe;IAC9B;;;;;;;OAOG;IACH,WAAW,CAAC,MAAM,EAAE;QAClB,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,EAAE,CAAC;QAClB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,GAAG,MAAM,CAAC;IAEX;;;;OAIG;IACH,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,GAAG,MAAM,CAAC;IAEjE;;;;OAIG;IACH,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAErE;;;;OAIG;IACH,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;IAE1C;;;;OAIG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;IAE5E;;;;OAIG;IACH,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IAErC;;;;;;;;;;OAUG;IACH,UAAU,CAAC,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;CACrG"}
1
+ {"version":3,"file":"fts.d.ts","sourceRoot":"","sources":["../../../src/core/contracts/fts.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,WAAW,eAAe;IAC9B;;;;;;;;OAQG;IACH,WAAW,CAAC,MAAM,EAAE;QAClB,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,EAAE,CAAC;QAClB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC;KACjD,GAAG,MAAM,CAAC;IAEX;;;;OAIG;IACH,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,GAAG,MAAM,CAAC;IAEjE;;;;;;OAMG;IACH,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAErE;;;;;OAKG;IACH,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAErE;;;;OAIG;IACH,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;IAE1C;;;;OAIG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;IAE5E;;;;OAIG;IACH,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IAErC;;;;;;;;;;OAUG;IACH,UAAU,CAAC,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;CACrG"}
@@ -10,6 +10,7 @@ export * from '../types/index.js';
10
10
  export { SqliteDialect } from '../dialects/SqliteDialect.js';
11
11
  export { PostgresDialect } from '../dialects/PostgresDialect.js';
12
12
  export { SqliteFts5 } from '../fts/SqliteFts5.js';
13
+ export { SqliteFts4 } from '../fts/SqliteFts4.js';
13
14
  export { PostgresFts } from '../fts/PostgresFts.js';
14
15
  export { NodeBlobCodec } from '../codecs/NodeBlobCodec.js';
15
16
  export { BrowserBlobCodec } from '../codecs/BrowserBlobCodec.js';
@@ -19,5 +20,6 @@ export { createStorageFeatures } from './contracts/features.js';
19
20
  export { isUniqueViolation } from '../shared/errors.js';
20
21
  export { setStorageLogger, getStorageLogger, type StorageLogger } from '../shared/logger.js';
21
22
  export * from '../features/migrations/schemaMigrations.js';
23
+ export * from '../features/auth/authJsAdapter.js';
22
24
  export * from '../shared/parameterUtils.js';
23
25
  //# 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,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,gBAAgB,EAAE,gBAAgB,EAAE,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC1F,cAAc,yCAAyC,CAAC;AACxD,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,gBAAgB,EAAE,gBAAgB,EAAE,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC1F,cAAc,yCAAyC,CAAC;AACxD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,0BAA0B,CAAC"}
@@ -10,6 +10,7 @@ export * from '../types/index.js';
10
10
  export { SqliteDialect } from '../dialects/SqliteDialect.js';
11
11
  export { PostgresDialect } from '../dialects/PostgresDialect.js';
12
12
  export { SqliteFts5 } from '../fts/SqliteFts5.js';
13
+ export { SqliteFts4 } from '../fts/SqliteFts4.js';
13
14
  export { PostgresFts } from '../fts/PostgresFts.js';
14
15
  export { NodeBlobCodec } from '../codecs/NodeBlobCodec.js';
15
16
  export { BrowserBlobCodec } from '../codecs/BrowserBlobCodec.js';
@@ -19,5 +20,6 @@ export { createStorageFeatures } from './contracts/features.js';
19
20
  export { isUniqueViolation } from '../shared/errors.js';
20
21
  export { setStorageLogger, getStorageLogger } from '../shared/logger.js';
21
22
  export * from '../features/migrations/schemaMigrations.js';
23
+ export * from '../features/auth/authJsAdapter.js';
22
24
  export * from '../shared/parameterUtils.js';
23
25
  //# 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,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,gBAAgB,EAAE,gBAAgB,EAAsB,MAAM,kBAAkB,CAAC;AAC1F,cAAc,yCAAyC,CAAC;AACxD,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,gBAAgB,EAAE,gBAAgB,EAAsB,MAAM,kBAAkB,CAAC;AAC1F,cAAc,yCAAyC,CAAC;AACxD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,0BAA0B,CAAC"}
@@ -0,0 +1,110 @@
1
+ /**
2
+ * An Auth.js database adapter over StorageAdapter: users, accounts, sessions
3
+ * and verification tokens kept through this library on PostgreSQL and SQLite
4
+ * alike, so a product's own Auth.js (NextAuth v5, `@auth/core`) stores its
5
+ * auth data where the rest of its data lives.
6
+ *
7
+ * The object `createAuthJsAdapter()` returns has the shape of `Adapter` from
8
+ * `@auth/core/adapters`, without a dependency on it: pass it as `adapter` to
9
+ * `NextAuth()` or `Auth()`. WebAuthn authenticators are not stored.
10
+ *
11
+ * @module
12
+ */
13
+ import type { StorageAdapter } from '../../core/contracts/index.js';
14
+ /** A user as Auth.js reads it (`AdapterUser`). */
15
+ export interface AuthJsUser {
16
+ id: string;
17
+ email: string;
18
+ emailVerified: Date | null;
19
+ name?: string | null;
20
+ image?: string | null;
21
+ }
22
+ /**
23
+ * An account as Auth.js reads it (`AdapterAccount`). A type, not an
24
+ * interface, so it fits Auth.js's account, which allows more token fields.
25
+ * Fields the provider did not give are left out.
26
+ */
27
+ export type AuthJsAccount = {
28
+ userId: string;
29
+ type: 'oauth' | 'oidc' | 'email' | 'webauthn';
30
+ provider: string;
31
+ providerAccountId: string;
32
+ refresh_token?: string;
33
+ access_token?: string;
34
+ expires_at?: number;
35
+ token_type?: Lowercase<string>;
36
+ scope?: string;
37
+ id_token?: string;
38
+ session_state?: string;
39
+ };
40
+ /** A session as Auth.js reads it (`AdapterSession`). */
41
+ export interface AuthJsSession {
42
+ sessionToken: string;
43
+ userId: string;
44
+ expires: Date;
45
+ }
46
+ /** A verification token as Auth.js reads it (`VerificationToken`). */
47
+ export interface AuthJsVerificationToken {
48
+ identifier: string;
49
+ token: string;
50
+ expires: Date;
51
+ }
52
+ /** The methods of Auth.js's `Adapter` this adapter implements. */
53
+ export interface AuthJsAdapter {
54
+ createUser(user: Omit<AuthJsUser, 'id'> & {
55
+ id?: string;
56
+ }): Promise<AuthJsUser>;
57
+ getUser(id: string): Promise<AuthJsUser | null>;
58
+ getUserByEmail(email: string): Promise<AuthJsUser | null>;
59
+ getUserByAccount(account: Pick<AuthJsAccount, 'provider' | 'providerAccountId'>): Promise<AuthJsUser | null>;
60
+ updateUser(user: Partial<AuthJsUser> & Pick<AuthJsUser, 'id'>): Promise<AuthJsUser>;
61
+ deleteUser(userId: string): Promise<AuthJsUser | null>;
62
+ linkAccount(account: AuthJsAccount): Promise<AuthJsAccount>;
63
+ unlinkAccount(account: Pick<AuthJsAccount, 'provider' | 'providerAccountId'>): Promise<void>;
64
+ getAccount(providerAccountId: string, provider: string): Promise<AuthJsAccount | null>;
65
+ createSession(session: AuthJsSession): Promise<AuthJsSession>;
66
+ getSessionAndUser(sessionToken: string): Promise<{
67
+ session: AuthJsSession;
68
+ user: AuthJsUser;
69
+ } | null>;
70
+ updateSession(session: Partial<AuthJsSession> & Pick<AuthJsSession, 'sessionToken'>): Promise<AuthJsSession | null>;
71
+ deleteSession(sessionToken: string): Promise<void>;
72
+ createVerificationToken(token: AuthJsVerificationToken): Promise<AuthJsVerificationToken>;
73
+ useVerificationToken(params: {
74
+ identifier: string;
75
+ token: string;
76
+ }): Promise<AuthJsVerificationToken | null>;
77
+ }
78
+ /** Where the adapter keeps its tables, and how it makes ids. */
79
+ export interface AuthJsAdapterOptions {
80
+ /** Put before each table name: `<prefix>users`, `<prefix>accounts`, `<prefix>sessions`, `<prefix>verification_tokens`. Default `auth_`. */
81
+ tablePrefix?: string;
82
+ /** Makes a user or account id when Auth.js passes none. Default: `crypto.randomUUID()`. */
83
+ generateId?: () => string;
84
+ }
85
+ /**
86
+ * The statements that create the adapter's tables and indexes on `db`'s
87
+ * engine, each `IF NOT EXISTS`, for a migration file or for
88
+ * ensureAuthJsTables.
89
+ */
90
+ export declare function authJsTablesSql(db: StorageAdapter, options?: AuthJsAdapterOptions): string[];
91
+ /** Creates the adapter's tables and indexes on `db` when they are missing. */
92
+ export declare function ensureAuthJsTables(db: StorageAdapter, options?: AuthJsAdapterOptions): Promise<void>;
93
+ /**
94
+ * An Auth.js database adapter that keeps users, accounts, sessions and
95
+ * verification tokens in `db`, on PostgreSQL or SQLite. Create the tables
96
+ * first with ensureAuthJsTables (or authJsTablesSql in a migration).
97
+ *
98
+ * @example
99
+ * ```typescript
100
+ * import NextAuth from 'next-auth';
101
+ * import { createDatabase } from '@framers/sql-storage-adapter';
102
+ * import { createAuthJsAdapter, ensureAuthJsTables } from '@framers/sql-storage-adapter/authjs';
103
+ *
104
+ * const db = await createDatabase({ url: process.env.DATABASE_URL, strict: true });
105
+ * await ensureAuthJsTables(db);
106
+ * export const { handlers, auth } = NextAuth({ adapter: createAuthJsAdapter(db), providers: [] });
107
+ * ```
108
+ */
109
+ export declare function createAuthJsAdapter(db: StorageAdapter, options?: AuthJsAdapterOptions): AuthJsAdapter;
110
+ //# sourceMappingURL=authJsAdapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authJsAdapter.d.ts","sourceRoot":"","sources":["../../../src/features/auth/authJsAdapter.ts"],"names":[],"mappings":"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"}