litedbmodel 2.0.0 → 2.0.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.
Files changed (163) hide show
  1. package/dist/scp/authoring-sql.d.ts +78 -0
  2. package/dist/scp/authoring-sql.d.ts.map +1 -1
  3. package/dist/scp/authoring-sql.js +110 -2
  4. package/dist/scp/authoring-sql.js.map +1 -1
  5. package/dist/scp/catalog.d.ts +5 -2
  6. package/dist/scp/catalog.d.ts.map +1 -1
  7. package/dist/scp/catalog.js +32 -1
  8. package/dist/scp/catalog.js.map +1 -1
  9. package/dist/scp/codegen.d.ts +143 -85
  10. package/dist/scp/codegen.d.ts.map +1 -1
  11. package/dist/scp/codegen.js +374 -90
  12. package/dist/scp/codegen.js.map +1 -1
  13. package/dist/scp/coltype.d.ts +41 -0
  14. package/dist/scp/coltype.d.ts.map +1 -0
  15. package/dist/scp/coltype.js +188 -0
  16. package/dist/scp/coltype.js.map +1 -0
  17. package/dist/scp/dialect.d.ts +12 -3
  18. package/dist/scp/dialect.d.ts.map +1 -1
  19. package/dist/scp/dialect.js +12 -3
  20. package/dist/scp/dialect.js.map +1 -1
  21. package/dist/scp/find-filter-guard.d.ts +68 -0
  22. package/dist/scp/find-filter-guard.d.ts.map +1 -0
  23. package/dist/scp/find-filter-guard.js +88 -0
  24. package/dist/scp/find-filter-guard.js.map +1 -0
  25. package/dist/scp/fragment/assemble.d.ts +61 -0
  26. package/dist/scp/fragment/assemble.d.ts.map +1 -0
  27. package/dist/scp/fragment/assemble.js +156 -0
  28. package/dist/scp/fragment/assemble.js.map +1 -0
  29. package/dist/scp/fragment/compile-pg.d.ts +107 -0
  30. package/dist/scp/fragment/compile-pg.d.ts.map +1 -0
  31. package/dist/scp/fragment/compile-pg.js +142 -0
  32. package/dist/scp/fragment/compile-pg.js.map +1 -0
  33. package/dist/scp/fragment/index.d.ts +16 -0
  34. package/dist/scp/fragment/index.d.ts.map +1 -0
  35. package/dist/scp/fragment/index.js +34 -0
  36. package/dist/scp/fragment/index.js.map +1 -0
  37. package/dist/scp/fragment/model.d.ts +119 -0
  38. package/dist/scp/fragment/model.d.ts.map +1 -0
  39. package/dist/scp/fragment/model.js +66 -0
  40. package/dist/scp/fragment/model.js.map +1 -0
  41. package/dist/scp/fragment/pg-array-type.d.ts +13 -0
  42. package/dist/scp/fragment/pg-array-type.d.ts.map +1 -0
  43. package/dist/scp/fragment/pg-array-type.js +34 -0
  44. package/dist/scp/fragment/pg-array-type.js.map +1 -0
  45. package/dist/scp/guard.d.ts +2 -6
  46. package/dist/scp/guard.d.ts.map +1 -1
  47. package/dist/scp/guard.js +19 -22
  48. package/dist/scp/guard.js.map +1 -1
  49. package/dist/scp/index.cjs +18695 -3921
  50. package/dist/scp/index.d.ts +41 -24
  51. package/dist/scp/index.d.ts.map +1 -1
  52. package/dist/scp/index.js +134 -49
  53. package/dist/scp/index.js.map +1 -1
  54. package/dist/scp/index.mjs +4830 -1432
  55. package/dist/scp/makesql/authoring-compile.d.ts +90 -0
  56. package/dist/scp/makesql/authoring-compile.d.ts.map +1 -0
  57. package/dist/scp/makesql/authoring-compile.js +494 -0
  58. package/dist/scp/makesql/authoring-compile.js.map +1 -0
  59. package/dist/scp/makesql/compile-crud.d.ts +133 -0
  60. package/dist/scp/makesql/compile-crud.d.ts.map +1 -0
  61. package/dist/scp/makesql/compile-crud.js +288 -0
  62. package/dist/scp/makesql/compile-crud.js.map +1 -0
  63. package/dist/scp/makesql/compile-relation.d.ts +157 -0
  64. package/dist/scp/makesql/compile-relation.d.ts.map +1 -0
  65. package/dist/scp/makesql/compile-relation.js +425 -0
  66. package/dist/scp/makesql/compile-relation.js.map +1 -0
  67. package/dist/scp/makesql/compile-select.d.ts +52 -0
  68. package/dist/scp/makesql/compile-select.d.ts.map +1 -0
  69. package/dist/scp/makesql/compile-select.js +58 -0
  70. package/dist/scp/makesql/compile-select.js.map +1 -0
  71. package/dist/scp/makesql/compile.d.ts +63 -0
  72. package/dist/scp/makesql/compile.d.ts.map +1 -0
  73. package/dist/scp/makesql/compile.js +99 -0
  74. package/dist/scp/makesql/compile.js.map +1 -0
  75. package/dist/scp/makesql/handler.d.ts +58 -0
  76. package/dist/scp/makesql/handler.d.ts.map +1 -0
  77. package/dist/scp/makesql/handler.js +113 -0
  78. package/dist/scp/makesql/handler.js.map +1 -0
  79. package/dist/scp/makesql/index.d.ts +33 -0
  80. package/dist/scp/makesql/index.d.ts.map +1 -0
  81. package/dist/scp/makesql/index.js +114 -0
  82. package/dist/scp/makesql/index.js.map +1 -0
  83. package/dist/scp/makesql/ir.d.ts +42 -0
  84. package/dist/scp/makesql/ir.d.ts.map +1 -0
  85. package/dist/scp/makesql/ir.js +66 -0
  86. package/dist/scp/makesql/ir.js.map +1 -0
  87. package/dist/scp/makesql/json-array.d.ts +84 -0
  88. package/dist/scp/makesql/json-array.d.ts.map +1 -0
  89. package/dist/scp/makesql/json-array.js +118 -0
  90. package/dist/scp/makesql/json-array.js.map +1 -0
  91. package/dist/scp/makesql/json-batch.d.ts +102 -0
  92. package/dist/scp/makesql/json-batch.d.ts.map +1 -0
  93. package/dist/scp/makesql/json-batch.js +269 -0
  94. package/dist/scp/makesql/json-batch.js.map +1 -0
  95. package/dist/scp/makesql/makesql.d.ts +99 -0
  96. package/dist/scp/makesql/makesql.d.ts.map +1 -0
  97. package/dist/scp/makesql/makesql.js +122 -0
  98. package/dist/scp/makesql/makesql.js.map +1 -0
  99. package/dist/scp/makesql/outtype.d.ts +44 -0
  100. package/dist/scp/makesql/outtype.d.ts.map +1 -0
  101. package/dist/scp/makesql/outtype.js +197 -0
  102. package/dist/scp/makesql/outtype.js.map +1 -0
  103. package/dist/scp/makesql/pool-executor.d.ts +47 -0
  104. package/dist/scp/makesql/pool-executor.d.ts.map +1 -0
  105. package/dist/scp/makesql/pool-executor.js +50 -0
  106. package/dist/scp/makesql/pool-executor.js.map +1 -0
  107. package/dist/scp/makesql/static-bundle.d.ts +187 -0
  108. package/dist/scp/makesql/static-bundle.d.ts.map +1 -0
  109. package/dist/scp/makesql/static-bundle.js +1113 -0
  110. package/dist/scp/makesql/static-bundle.js.map +1 -0
  111. package/dist/scp/makesql/tx.d.ts +216 -0
  112. package/dist/scp/makesql/tx.d.ts.map +1 -0
  113. package/dist/scp/makesql/tx.js +788 -0
  114. package/dist/scp/makesql/tx.js.map +1 -0
  115. package/dist/scp/makesql/writeouttype.d.ts +66 -0
  116. package/dist/scp/makesql/writeouttype.d.ts.map +1 -0
  117. package/dist/scp/makesql/writeouttype.js +195 -0
  118. package/dist/scp/makesql/writeouttype.js.map +1 -0
  119. package/dist/scp/relation.d.ts +86 -74
  120. package/dist/scp/relation.d.ts.map +1 -1
  121. package/dist/scp/relation.js +186 -120
  122. package/dist/scp/relation.js.map +1 -1
  123. package/dist/scp/runtime.d.ts +158 -211
  124. package/dist/scp/runtime.d.ts.map +1 -1
  125. package/dist/scp/runtime.js +250 -515
  126. package/dist/scp/runtime.js.map +1 -1
  127. package/dist/scp/typed-object.d.ts +12 -1
  128. package/dist/scp/typed-object.d.ts.map +1 -1
  129. package/dist/scp/typed-object.js +25 -4
  130. package/dist/scp/typed-object.js.map +1 -1
  131. package/docs/proposal/litedbmodel-v2-scp-architecture.md +51 -0
  132. package/docs/proposal/v0-coverage-matrix.md +157 -0
  133. package/docs/proposal/v2-completeness-plan.md +90 -0
  134. package/docs/proposal/v2-sql-parity-checklist.md +162 -0
  135. package/package.json +3 -3
  136. package/dist/scp/bridge.d.ts +0 -64
  137. package/dist/scp/bridge.d.ts.map +0 -1
  138. package/dist/scp/bridge.js +0 -329
  139. package/dist/scp/bridge.js.map +0 -1
  140. package/dist/scp/compile-dialect.d.ts +0 -39
  141. package/dist/scp/compile-dialect.d.ts.map +0 -1
  142. package/dist/scp/compile-dialect.js +0 -62
  143. package/dist/scp/compile-dialect.js.map +0 -1
  144. package/dist/scp/compile-sqlite.d.ts +0 -114
  145. package/dist/scp/compile-sqlite.d.ts.map +0 -1
  146. package/dist/scp/compile-sqlite.js +0 -149
  147. package/dist/scp/compile-sqlite.js.map +0 -1
  148. package/dist/scp/ir.d.ts +0 -92
  149. package/dist/scp/ir.d.ts.map +0 -1
  150. package/dist/scp/ir.js +0 -28
  151. package/dist/scp/ir.js.map +0 -1
  152. package/dist/scp/render.d.ts +0 -40
  153. package/dist/scp/render.d.ts.map +0 -1
  154. package/dist/scp/render.js +0 -170
  155. package/dist/scp/render.js.map +0 -1
  156. package/dist/scp/write-plan.d.ts +0 -161
  157. package/dist/scp/write-plan.d.ts.map +0 -1
  158. package/dist/scp/write-plan.js +0 -528
  159. package/dist/scp/write-plan.js.map +0 -1
  160. package/dist/scp/write-runtime.d.ts +0 -80
  161. package/dist/scp/write-runtime.d.ts.map +0 -1
  162. package/dist/scp/write-runtime.js +0 -167
  163. package/dist/scp/write-runtime.js.map +0 -1
@@ -0,0 +1,188 @@
1
+ "use strict";
2
+ /**
3
+ * litedbmodel v2 型システム(SCP アーキ spec §4.1): SQL 型 → bc outType スカラの正規変換。
4
+ *
5
+ * litedbmodel は SQL バックエンド consumer なので **SQL 型を型の SoT** とする(TS の `number` は
6
+ * INTEGER/REAL を区別できないため型の権威にしない)。typed codegen(bc typed-raw 脱box)の `outType`
7
+ * 注記はこの変換で決まる。**曖昧/未知は error(no-assume・no-fallback)** — 既定値へ潰さない。
8
+ *
9
+ * 返すのは bc の scalar 型名(`typed.ts` の scalar union `"string"|"int"|"float"|"bool"|"null"`)。
10
+ * 行/リレーションの構造型(`obj`/`arr`/`opt`)は列型ではなくクエリ由来なので本変換の対象外。
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.sqlTypeToBcScalar = sqlTypeToBcScalar;
14
+ exports.parseSchemaColumnTypes = parseSchemaColumnTypes;
15
+ exports.schemaColumnTypeResolver = schemaColumnTypeResolver;
16
+ /**
17
+ * SQL 型(DDL のトークン。`DECIMAL(10,2)` 等の括弧やサイズは無視)→ bc outType スカラ。
18
+ * spec §4.1 の正規表に一致。未知/曖昧は throw(fail-closed)。
19
+ */
20
+ function sqlTypeToBcScalar(sqlType) {
21
+ // 括弧のサイズ/精度・`UNSIGNED` 等の修飾を落として基底型名で判定。
22
+ const t = sqlType
23
+ .trim()
24
+ .toUpperCase()
25
+ .replace(/\(.*\)/, '')
26
+ .replace(/\b(UNSIGNED|ZEROFILL|PRECISION)\b/g, '')
27
+ .replace(/\s+/g, ' ')
28
+ .trim();
29
+ switch (t) {
30
+ // int は既定 64bit(i64)。INTEGER も BIGINT も int(bigint を別型にしない — サイズ制限は列制約で表現)。
31
+ case 'INTEGER':
32
+ case 'INT':
33
+ case 'BIGINT':
34
+ case 'SMALLINT':
35
+ case 'TINYINT':
36
+ case 'MEDIUMINT':
37
+ case 'INT2':
38
+ case 'INT4':
39
+ case 'INT8':
40
+ return 'int';
41
+ // int と real は明確に分離。
42
+ case 'REAL':
43
+ case 'FLOAT':
44
+ case 'DOUBLE':
45
+ case 'FLOAT4':
46
+ case 'FLOAT8':
47
+ return 'float';
48
+ // decimal は精度保持のため文字列表現。
49
+ case 'DECIMAL':
50
+ case 'NUMERIC':
51
+ case 'MONEY':
52
+ return 'string';
53
+ case 'TEXT':
54
+ case 'VARCHAR':
55
+ case 'CHAR':
56
+ case 'CHARACTER':
57
+ case 'CHARACTER VARYING':
58
+ case 'CLOB':
59
+ case 'UUID':
60
+ return 'string';
61
+ case 'BOOLEAN':
62
+ case 'BOOL':
63
+ return 'bool';
64
+ // date/timestamp は一旦 string(spec §4.1 owner 決定)。bc に date scalar が無く(behavior-contracts#84
65
+ // は defer)、DB は行ごとに別 TZ を保存しないので、文字列表現で往復させる。将来 bc date 型導入時に最適化。
66
+ case 'DATE':
67
+ case 'TIMESTAMP':
68
+ case 'TIMESTAMPTZ':
69
+ case 'DATETIME':
70
+ case 'TIME':
71
+ return 'string';
72
+ // JSON 列の表現は JSON テキスト=文字列(TS のみ利便で object へ de/serialize。列を typed obj 化しない)。
73
+ case 'JSON':
74
+ case 'JSONB':
75
+ return 'string';
76
+ default:
77
+ throw new Error(`litedbmodel type system (spec §4.1): no bc outType mapping for SQL type '${sqlType}' ` +
78
+ `(normalized '${t}'). Add it to the §4.1 table or fix the column — ambiguous/unknown types ` +
79
+ `are a hard error (no-assume, no-fallback), never defaulted.`);
80
+ }
81
+ }
82
+ /**
83
+ * Parse a list of `CREATE TABLE` DDL statements into a `table → (column → SQL type)` map. This is
84
+ * the spec §4.1 SoT: the physical SQL type of each column, from which `sqlTypeToBcScalar` derives
85
+ * the bc `outType` scalar for typed codegen. Only the base column definitions are read; table-level
86
+ * constraints (`PRIMARY KEY (…)`, `FOREIGN KEY …`, `UNIQUE (…)`, `CHECK …`) are skipped. A column's
87
+ * type is its first token after the name (e.g. `id INTEGER PRIMARY KEY` → `INTEGER`). Column names
88
+ * quoted with `"`/`` ` ``/`[]` are unquoted. Non-`CREATE TABLE` statements (INSERT seed rows, etc.)
89
+ * are ignored, so a mixed schema+seed list is accepted as-is.
90
+ */
91
+ function parseSchemaColumnTypes(ddl) {
92
+ const tables = new Map();
93
+ const CREATE = /^\s*CREATE\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?([A-Za-z0-9_."`[\]]+)\s*\(([\s\S]*)\)\s*;?\s*$/i;
94
+ const unquote = (s) => s.replace(/^["`[]|["`\]]$/g, '');
95
+ // Column/constraint list keywords that start a TABLE-LEVEL constraint (not a column definition).
96
+ const TABLE_CONSTRAINT = /^(PRIMARY|FOREIGN|UNIQUE|CHECK|CONSTRAINT|KEY|INDEX)\b/i;
97
+ for (const stmt of ddl) {
98
+ const m = CREATE.exec(stmt);
99
+ if (m === null)
100
+ continue; // not a CREATE TABLE (seed INSERT / pragma / etc.) — skip
101
+ const table = unquote(m[1].trim());
102
+ const cols = new Map();
103
+ for (const entry of splitTopLevel(m[2])) {
104
+ const line = entry.trim();
105
+ if (line.length === 0)
106
+ continue;
107
+ if (TABLE_CONSTRAINT.test(line))
108
+ continue; // table-level constraint, not a column
109
+ // `<name> <TYPE...> [constraints]` — the type is the token(s) up to the first constraint
110
+ // keyword or the end. `parseColumnDef` returns `{ name, sqlType }` or undefined (unparseable).
111
+ const parsed = parseColumnDef(line);
112
+ if (parsed === undefined)
113
+ continue;
114
+ cols.set(parsed.name, parsed.sqlType);
115
+ }
116
+ tables.set(table, cols);
117
+ }
118
+ return tables;
119
+ }
120
+ /** Split a CREATE TABLE column list on TOP-LEVEL commas (commas inside `(…)`, e.g. `DECIMAL(10,2)`, stay). */
121
+ function splitTopLevel(body) {
122
+ const parts = [];
123
+ let depth = 0;
124
+ let cur = '';
125
+ for (const ch of body) {
126
+ if (ch === '(')
127
+ depth++;
128
+ else if (ch === ')')
129
+ depth--;
130
+ if (ch === ',' && depth === 0) {
131
+ parts.push(cur);
132
+ cur = '';
133
+ }
134
+ else
135
+ cur += ch;
136
+ }
137
+ if (cur.trim().length > 0)
138
+ parts.push(cur);
139
+ return parts;
140
+ }
141
+ /** The SQL-type keywords that may form a multi-word type (so `CHARACTER VARYING`, `DOUBLE PRECISION` stay whole). */
142
+ const TYPE_CONTINUATION = /^(VARYING|PRECISION)$/i;
143
+ /** Parse one `<name> <TYPE...>` column definition into `{ name, sqlType }`. Undefined when unparseable. */
144
+ function parseColumnDef(line) {
145
+ const unquote = (s) => s.replace(/^["`[]|["`\]]$/g, '');
146
+ const nameMatch = /^([A-Za-z0-9_."`[\]]+)\s+(.*)$/.exec(line);
147
+ if (nameMatch === null)
148
+ return undefined;
149
+ const name = unquote(nameMatch[1]);
150
+ const rest = nameMatch[2].trim();
151
+ // The type is the leading token plus any `(...)` size/precision, plus a continuation word
152
+ // (`CHARACTER VARYING`, `DOUBLE PRECISION`). Everything after is column constraints.
153
+ const typeMatch = /^([A-Za-z0-9_]+(?:\s*\([^)]*\))?)\s*(.*)$/.exec(rest);
154
+ if (typeMatch === null)
155
+ return undefined;
156
+ let sqlType = typeMatch[1].trim();
157
+ const after = typeMatch[2].trim();
158
+ const nextWord = /^([A-Za-z]+)/.exec(after);
159
+ if (nextWord !== null && TYPE_CONTINUATION.test(nextWord[1]))
160
+ sqlType = `${sqlType} ${nextWord[1]}`;
161
+ if (sqlType.length === 0)
162
+ return undefined;
163
+ return { name, sqlType };
164
+ }
165
+ /**
166
+ * Build a {@link ColumnTypeResolver} from CREATE TABLE DDL (spec §4.1 SoT). The resolver throws
167
+ * (no default) for any `table.column` the DDL does not declare — an unknown column is a hard error
168
+ * (no-assume, no-fallback), so a codegen `outType` derivation can never silently box an untyped row.
169
+ */
170
+ function schemaColumnTypeResolver(ddl) {
171
+ const tables = parseSchemaColumnTypes(ddl);
172
+ return (table, column) => {
173
+ const cols = tables.get(table);
174
+ if (cols === undefined) {
175
+ throw new Error(`litedbmodel type system (spec §4.1): no schema for table '${table}' — cannot type its ` +
176
+ `SELECT projection for typed codegen. The DDL (schema.sql SoT) must declare the table ` +
177
+ `(known: ${[...tables.keys()].join(', ') || '<none>'}). No-assume, no-fallback.`);
178
+ }
179
+ const sqlType = cols.get(column);
180
+ if (sqlType === undefined) {
181
+ throw new Error(`litedbmodel type system (spec §4.1): column '${column}' not declared on table '${table}' ` +
182
+ `(known columns: ${[...cols.keys()].join(', ')}). A projected column with no schema type ` +
183
+ `cannot be typed for de-boxed codegen. No-assume, no-fallback.`);
184
+ }
185
+ return sqlType;
186
+ };
187
+ }
188
+ //# sourceMappingURL=coltype.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coltype.js","sourceRoot":"","sources":["../../src/scp/coltype.ts"],"names":[],"mappings":"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"}
@@ -25,10 +25,19 @@
25
25
  * final left-to-right one-pass AFTER the SQL text is fully assembled (spec §8 — the
26
26
  * number-reassignment problem is designed out because the pass runs once over the final
27
27
  * flat text). SQLite/MySQL keep `?`.
28
+ * - **Per-column value cast (PG)**: a written column with a declared `sqlCast` type emits
29
+ * `?::<sqlCast>` on Postgres — in an INSERT `VALUES (…)` tuple (`PostgresSqlBuilder`:289-296)
30
+ * AND an UPDATE `SET c = ?::<sqlCast>` (`DBModel._update`:1058-1063) — via the dialect cast
31
+ * formatter (`formatterFor`), skipping `timestamp`/`date`. MySQL/SQLite emit a bare `?` (the
32
+ * cast formatter is identity there). This is resolved at compile (the write path targets a
33
+ * single dialect), applied in `compile-crud.compileUpdateSingle` and `tx.compileWriteNode`.
28
34
  *
29
- * Everything else (SELECT/UPDATE/DELETE skeletons, `col = ?`, `col IN (?, …)` expansion, the
30
- * fragment tree, RETURNING for SQLite/Postgres) is identical text across dialects, so it is
31
- * NOT part of the strategy — only the genuine divergences live here.
35
+ * Everything else (SELECT/UPDATE/DELETE skeletons, a NON-cast `col = ?`, `col IN (?, …)` expansion,
36
+ * the fragment tree, RETURNING for SQLite/Postgres) is identical text across dialects, so it is
37
+ * NOT part of the strategy — only the genuine divergences (including the PG per-column cast above)
38
+ * live here. NB: `col = ?` / `VALUES (?)` is identical across dialects ONLY for a column with no
39
+ * `sqlCast`; a PG cast column is the `?::<sqlCast>` divergence just described (this was previously
40
+ * mis-documented as unconditionally identical).
32
41
  *
33
42
  * ## DB behavior differences beyond SQL text (spec §13) — closeable-by-convention line
34
43
  *
@@ -1 +1 @@
1
- {"version":3,"file":"dialect.d.ts","sourceRoot":"","sources":["../../src/scp/dialect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,uFAAuF;AACvF,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,UAAU,GAAG,OAAO,CAAC;AAE1D,0FAA0F;AAC1F,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG;IAAE,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAC;AAEtF;;;;GAIG;AACH,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAE3B;;;;;;;;;OASG;IACH,oBAAoB,CAAC,eAAe,EAAE,SAAS,MAAM,EAAE,EAAE,MAAM,EAAE,cAAc,GAAG,MAAM,CAAC;IAEzF;;;;;OAKG;IACH,UAAU,CAAC,MAAM,EAAE,cAAc,GAAG,SAAS,GAAG,MAAM,CAAC;IAEvD;;;;OAIG;IACH,QAAQ,CAAC,sBAAsB,EAAE,OAAO,CAAC;IAEzC;;;;;;;;;;;;;;;OAeG;IACH,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,MAAM,EAAE,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAAC;IAErF;;;;;OAKG;IACH,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;IAE1C;;;;;OAKG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,GAAG,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;CAClF;AAID;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAYxD;AAwCD;;;;GAIG;AACH,eAAO,MAAM,MAAM,EAAE,OAoBnB,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,QAAQ,EAAE,OAkBrB,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,KAAK,EAAE,OA0BlB,CAAC;AASH,6FAA6F;AAC7F,wBAAgB,UAAU,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAMrD"}
1
+ {"version":3,"file":"dialect.d.ts","sourceRoot":"","sources":["../../src/scp/dialect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AAEH,uFAAuF;AACvF,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,UAAU,GAAG,OAAO,CAAC;AAE1D,0FAA0F;AAC1F,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG;IAAE,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAC;AAEtF;;;;GAIG;AACH,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAE3B;;;;;;;;;OASG;IACH,oBAAoB,CAAC,eAAe,EAAE,SAAS,MAAM,EAAE,EAAE,MAAM,EAAE,cAAc,GAAG,MAAM,CAAC;IAEzF;;;;;OAKG;IACH,UAAU,CAAC,MAAM,EAAE,cAAc,GAAG,SAAS,GAAG,MAAM,CAAC;IAEvD;;;;OAIG;IACH,QAAQ,CAAC,sBAAsB,EAAE,OAAO,CAAC;IAEzC;;;;;;;;;;;;;;;OAeG;IACH,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,MAAM,EAAE,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAAC;IAErF;;;;;OAKG;IACH,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;IAE1C;;;;;OAKG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,GAAG,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;CAClF;AAID;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAYxD;AAwCD;;;;GAIG;AACH,eAAO,MAAM,MAAM,EAAE,OAoBnB,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,QAAQ,EAAE,OAkBrB,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,KAAK,EAAE,OA0BlB,CAAC;AASH,6FAA6F;AAC7F,wBAAgB,UAAU,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAMrD"}
@@ -26,10 +26,19 @@
26
26
  * final left-to-right one-pass AFTER the SQL text is fully assembled (spec §8 — the
27
27
  * number-reassignment problem is designed out because the pass runs once over the final
28
28
  * flat text). SQLite/MySQL keep `?`.
29
+ * - **Per-column value cast (PG)**: a written column with a declared `sqlCast` type emits
30
+ * `?::<sqlCast>` on Postgres — in an INSERT `VALUES (…)` tuple (`PostgresSqlBuilder`:289-296)
31
+ * AND an UPDATE `SET c = ?::<sqlCast>` (`DBModel._update`:1058-1063) — via the dialect cast
32
+ * formatter (`formatterFor`), skipping `timestamp`/`date`. MySQL/SQLite emit a bare `?` (the
33
+ * cast formatter is identity there). This is resolved at compile (the write path targets a
34
+ * single dialect), applied in `compile-crud.compileUpdateSingle` and `tx.compileWriteNode`.
29
35
  *
30
- * Everything else (SELECT/UPDATE/DELETE skeletons, `col = ?`, `col IN (?, …)` expansion, the
31
- * fragment tree, RETURNING for SQLite/Postgres) is identical text across dialects, so it is
32
- * NOT part of the strategy — only the genuine divergences live here.
36
+ * Everything else (SELECT/UPDATE/DELETE skeletons, a NON-cast `col = ?`, `col IN (?, …)` expansion,
37
+ * the fragment tree, RETURNING for SQLite/Postgres) is identical text across dialects, so it is
38
+ * NOT part of the strategy — only the genuine divergences (including the PG per-column cast above)
39
+ * live here. NB: `col = ?` / `VALUES (?)` is identical across dialects ONLY for a column with no
40
+ * `sqlCast`; a PG cast column is the `?::<sqlCast>` divergence just described (this was previously
41
+ * mis-documented as unconditionally identical).
33
42
  *
34
43
  * ## DB behavior differences beyond SQL text (spec §13) — closeable-by-convention line
35
44
  *
@@ -1 +1 @@
1
- {"version":3,"file":"dialect.js","sourceRoot":"","sources":["../../src/scp/dialect.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dialect.js","sourceRoot":"","sources":["../../src/scp/dialect.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;;;AAwFH,oDAYC;AAsID,gCAMC;AAlKD,iFAAiF;AAEjF;;;;;;;GAOG;AACH,SAAgB,oBAAoB,CAAC,GAAW;IAC9C,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,KAAK,MAAM,EAAE,IAAI,GAAG,EAAE,CAAC;QACrB,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;YACf,CAAC,IAAI,CAAC,CAAC;YACP,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC;QACjB,CAAC;aAAM,CAAC;YACN,GAAG,IAAI,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,mFAAmF;AAEnF;;;;;GAKG;AACH,SAAS,gBAAgB,CACvB,eAAkC,EAClC,MAAsB,EACtB,WAAoC;IAEpC,MAAM,MAAM,GAAG,eAAe,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IACpF,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QACxB,OAAO,eAAe,MAAM,aAAa,CAAC;IAC5C,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACzE,OAAO,eAAe,MAAM,kBAAkB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;AAClE,CAAC;AAED;;;GAGG;AACH,SAAS,eAAe,CACtB,KAAa,EACb,OAA0B,EAC1B,YAAoB,EACpB,IAA0C;IAE1C,MAAM,IAAI,GAAG,IAAI,KAAK,cAAc,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,aAAa,CAAC;IAC5E,MAAM,IAAI,GAAG,IAAI,KAAK,mBAAmB,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3E,OAAO,GAAG,IAAI,IAAI,KAAK,KAAK,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,YAAY,IAAI,IAAI,EAAE,CAAC;AACpF,CAAC;AAED,kFAAkF;AAElF;;;;GAIG;AACU,QAAA,MAAM,GAAY,MAAM,CAAC,MAAM,CAAC;IAC3C,IAAI,EAAE,QAAQ;IACd,sBAAsB,EAAE,KAAK;IAC7B,UAAU,CAAC,MAAkC;QAC3C,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,aAAa,CAAC;IACvE,CAAC;IACD,oBAAoB,CAAC,eAAkC,EAAE,MAAsB;QAC7E,sFAAsF;QACtF,IAAI,MAAM,KAAK,QAAQ;YAAE,OAAO,EAAE,CAAC;QACnC,OAAO,gBAAgB,CAAC,eAAe,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;IAC3E,CAAC;IACD,WAAW,CAAC,KAAa,EAAE,OAA0B,EAAE,YAAoB;QACzE,OAAO,eAAe,CAAC,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,mBAAmB,CAAC,CAAC;IAC5E,CAAC;IACD,oBAAoB,CAAC,GAAW;QAC9B,OAAO,GAAG,CAAC;IACb,CAAC;IACD,YAAY,CAAC,IAAY,EAAE,GAAmB,EAAE,KAAuB;QACrE,OAAO,GAAG,IAAI,IAAI,GAAG,UAAU,KAAK,EAAE,CAAC;IACzC,CAAC;CACF,CAAC,CAAC;AAEH;;;;GAIG;AACU,QAAA,QAAQ,GAAY,MAAM,CAAC,MAAM,CAAC;IAC7C,IAAI,EAAE,UAAU;IAChB,sBAAsB,EAAE,IAAI;IAC5B,UAAU,CAAC,OAAmC;QAC5C,OAAO,aAAa,CAAC;IACvB,CAAC;IACD,oBAAoB,CAAC,eAAkC,EAAE,MAAsB;QAC7E,OAAO,gBAAgB,CAAC,eAAe,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;IAC3E,CAAC;IACD,WAAW,CAAC,KAAa,EAAE,OAA0B,EAAE,YAAoB;QACzE,OAAO,eAAe,CAAC,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,mBAAmB,CAAC,CAAC;IAC5E,CAAC;IACD,oBAAoB,CAAC,GAAW;QAC9B,OAAO,oBAAoB,CAAC,GAAG,CAAC,CAAC;IACnC,CAAC;IACD,YAAY,CAAC,IAAY,EAAE,GAAmB,EAAE,KAAuB;QACrE,OAAO,GAAG,IAAI,IAAI,GAAG,UAAU,KAAK,EAAE,CAAC;IACzC,CAAC;CACF,CAAC,CAAC;AAEH;;;;;GAKG;AACU,QAAA,KAAK,GAAY,MAAM,CAAC,MAAM,CAAC;IAC1C,IAAI,EAAE,OAAO;IACb,sBAAsB,EAAE,KAAK;IAC7B,UAAU,CAAC,MAAkC;QAC3C,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,aAAa,CAAC;IACpE,CAAC;IACD,oBAAoB,CAAC,gBAAmC,EAAE,MAAsB;QAC9E,IAAI,MAAM,KAAK,QAAQ;YAAE,OAAO,EAAE,CAAC,CAAC,sCAAsC;QAC1E,MAAM,IAAI,GAAG,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;QACpE,OAAO,4BAA4B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;IACvD,CAAC;IACD,WAAW,CAAC,KAAa,EAAE,OAA0B,EAAE,YAAoB;QACzE,OAAO,eAAe,CAAC,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,cAAc,CAAC,CAAC;IACvE,CAAC;IACD,oBAAoB,CAAC,GAAW;QAC9B,OAAO,GAAG,CAAC;IACb,CAAC;IACD,YAAY,CAAC,IAAY,EAAE,GAAmB,EAAE,KAAuB;QACrE,gEAAgE;QAChE,sFAAsF;QACtF,qFAAqF;QACrF,mFAAmF;QACnF,mFAAmF;QACnF,MAAM,OAAO,GAAG,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;QACnD,OAAO,GAAG,IAAI,YAAY,OAAO,KAAK,IAAI,IAAI,GAAG,EAAE,CAAC;IACtD,CAAC;CACF,CAAC,CAAC;AAEH,0FAA0F;AAC1F,MAAM,QAAQ,GAAiC,MAAM,CAAC,MAAM,CAAC;IAC3D,MAAM,EAAE,cAAM;IACd,QAAQ,EAAE,gBAAQ;IAClB,KAAK,EAAE,aAAK;CACb,CAAC,CAAC;AAEH,6FAA6F;AAC7F,SAAgB,UAAU,CAAC,IAAiB;IAC1C,MAAM,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IACzB,IAAI,CAAC,KAAK,SAAS,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,iCAAiC,MAAM,CAAC,IAAI,CAAC,aAAa,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACjH,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * litedbmodel v2 SCP — FIND_FILTER fail-closed authoring guard (#47 Finding B / plan R8).
3
+ *
4
+ * `FIND_FILTER` is a v1 PER-MODEL implicit predicate (a soft-delete / tenant scope) that
5
+ * v1 MERGES into the WHERE of every internal `find()`/`count()` before compiling
6
+ * (`DBModel._buildSelectSQL` / `_count`: `normalizedCond.add(condsToRecord(FIND_FILTER))`).
7
+ * It is not a distinct SQL construct — it manifests purely as extra WHERE fragments.
8
+ *
9
+ * The SCP compile path (`L.Select({ where })` → `compileReadGraph` → `renderReadPrimary`)
10
+ * is AUTHORED from an explicit `where`; it has NO `DBModel` class context, so it CANNOT
11
+ * auto-apply a model's `FIND_FILTER` (there is no model reference at compile time, and no
12
+ * production seam routes a `DBModel` into the SCP compile — grep: `FIND_FILTER` appears only
13
+ * in `DBModel`/`decorators`/`types`, never under `src/scp/`). Auto-apply is therefore
14
+ * impossible without model context the SCP compile does not have.
15
+ *
16
+ * Resolution = the plan's variant chosen fail-closed: a model that DECLARES a `FIND_FILTER`
17
+ * MUST have its scope predicates folded into the authored `L.Select({ where })`; if the
18
+ * author routes such a model through SCP WITHOUT the scope keys, this guard throws loudly
19
+ * ({@link FindFilterLeakError}) rather than silently dropping the filter (which would leak
20
+ * soft-deleted / cross-tenant rows — a correctness bug, not a cosmetic one). When the scope
21
+ * keys ARE present the guard is a no-op (byte-identical to v1's merged WHERE — proven in
22
+ * `test/scp/find-filter-noop.test.ts`).
23
+ */
24
+ import { type Conds } from '../Column';
25
+ /** A `DBModel`-shaped source: the only field this guard reads is the optional `FIND_FILTER`. */
26
+ export interface FindFilterSource {
27
+ /** The per-model implicit scope predicate (v1 `DBModel.FIND_FILTER`), or null/undefined. */
28
+ readonly FIND_FILTER?: Conds | null;
29
+ /** Class name for diagnostics (present on every `DBModel` subclass). */
30
+ readonly name?: string;
31
+ }
32
+ /**
33
+ * A model declaring a `FIND_FILTER` was compiled via the SCP path without its scope
34
+ * predicates present in the authored WHERE — the filter would silently leak. Thrown
35
+ * fail-closed at compile time; never swallowed.
36
+ */
37
+ export declare class FindFilterLeakError extends Error {
38
+ /** The declaring model's class name (diagnostics). */
39
+ readonly modelName: string;
40
+ /** The FIND_FILTER scope keys that are MISSING from the authored WHERE. */
41
+ readonly missingKeys: readonly string[];
42
+ constructor(
43
+ /** The declaring model's class name (diagnostics). */
44
+ modelName: string,
45
+ /** The FIND_FILTER scope keys that are MISSING from the authored WHERE. */
46
+ missingKeys: readonly string[]);
47
+ }
48
+ /**
49
+ * Extract the top-level predicate KEYS a `FIND_FILTER` folds into a WHERE. Uses the SAME
50
+ * `condsToRecord` v1 runs when merging (`DBModel._buildSelectSQL`:597) so the key set is
51
+ * exactly what v1 would add to `normalizedCond`. `__or__` (grouped OR) is kept as a key so a
52
+ * scoped OR-group also demands explicit authoring (fail-closed; never silently satisfied).
53
+ */
54
+ export declare function findFilterKeys(filter: Conds | null | undefined): string[];
55
+ /**
56
+ * Fail-closed guard: assert a model's `FIND_FILTER` scope keys are all present in the
57
+ * authored WHERE key set BEFORE an SCP compile of that model. No FIND_FILTER → no-op. When
58
+ * present, EVERY scope key must appear in `authoredWhereKeys`; any missing key throws
59
+ * {@link FindFilterLeakError}. The caller passes the top-level keys of the object it hands to
60
+ * `L.Select({ where })` (the same shape `condsToRecord` yields), so the check compares
61
+ * like-for-like against v1's merged predicate.
62
+ *
63
+ * @param model a `DBModel`-shaped source that MAY declare `FIND_FILTER`.
64
+ * @param authoredWhereKeys the top-level WHERE keys the SCP author expressed for this model.
65
+ * @throws FindFilterLeakError when a declared scope key is absent from the authored WHERE.
66
+ */
67
+ export declare function assertFindFilterFolded(model: FindFilterSource, authoredWhereKeys: Iterable<string>): void;
68
+ //# sourceMappingURL=find-filter-guard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"find-filter-guard.d.ts","sourceRoot":"","sources":["../../src/scp/find-filter-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAiB,KAAK,KAAK,EAAE,MAAM,WAAW,CAAC;AAEtD,gGAAgG;AAChG,MAAM,WAAW,gBAAgB;IAC/B,4FAA4F;IAC5F,QAAQ,CAAC,WAAW,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC;IACpC,wEAAwE;IACxE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;GAIG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;IAE1C,sDAAsD;IACtD,QAAQ,CAAC,SAAS,EAAE,MAAM;IAC1B,2EAA2E;IAC3E,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE;;IAHvC,sDAAsD;IAC7C,SAAS,EAAE,MAAM;IAC1B,2EAA2E;IAClE,WAAW,EAAE,SAAS,MAAM,EAAE;CAY1C;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,KAAK,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,EAAE,CAGzE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,gBAAgB,EACvB,iBAAiB,EAAE,QAAQ,CAAC,MAAM,CAAC,GAClC,IAAI,CAQN"}
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ /**
3
+ * litedbmodel v2 SCP — FIND_FILTER fail-closed authoring guard (#47 Finding B / plan R8).
4
+ *
5
+ * `FIND_FILTER` is a v1 PER-MODEL implicit predicate (a soft-delete / tenant scope) that
6
+ * v1 MERGES into the WHERE of every internal `find()`/`count()` before compiling
7
+ * (`DBModel._buildSelectSQL` / `_count`: `normalizedCond.add(condsToRecord(FIND_FILTER))`).
8
+ * It is not a distinct SQL construct — it manifests purely as extra WHERE fragments.
9
+ *
10
+ * The SCP compile path (`L.Select({ where })` → `compileReadGraph` → `renderReadPrimary`)
11
+ * is AUTHORED from an explicit `where`; it has NO `DBModel` class context, so it CANNOT
12
+ * auto-apply a model's `FIND_FILTER` (there is no model reference at compile time, and no
13
+ * production seam routes a `DBModel` into the SCP compile — grep: `FIND_FILTER` appears only
14
+ * in `DBModel`/`decorators`/`types`, never under `src/scp/`). Auto-apply is therefore
15
+ * impossible without model context the SCP compile does not have.
16
+ *
17
+ * Resolution = the plan's variant chosen fail-closed: a model that DECLARES a `FIND_FILTER`
18
+ * MUST have its scope predicates folded into the authored `L.Select({ where })`; if the
19
+ * author routes such a model through SCP WITHOUT the scope keys, this guard throws loudly
20
+ * ({@link FindFilterLeakError}) rather than silently dropping the filter (which would leak
21
+ * soft-deleted / cross-tenant rows — a correctness bug, not a cosmetic one). When the scope
22
+ * keys ARE present the guard is a no-op (byte-identical to v1's merged WHERE — proven in
23
+ * `test/scp/find-filter-noop.test.ts`).
24
+ */
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.FindFilterLeakError = void 0;
27
+ exports.findFilterKeys = findFilterKeys;
28
+ exports.assertFindFilterFolded = assertFindFilterFolded;
29
+ const Column_1 = require("../Column");
30
+ /**
31
+ * A model declaring a `FIND_FILTER` was compiled via the SCP path without its scope
32
+ * predicates present in the authored WHERE — the filter would silently leak. Thrown
33
+ * fail-closed at compile time; never swallowed.
34
+ */
35
+ class FindFilterLeakError extends Error {
36
+ modelName;
37
+ missingKeys;
38
+ constructor(
39
+ /** The declaring model's class name (diagnostics). */
40
+ modelName,
41
+ /** The FIND_FILTER scope keys that are MISSING from the authored WHERE. */
42
+ missingKeys) {
43
+ super(`FIND_FILTER leak: model '${modelName}' declares an implicit scope predicate on ` +
44
+ `[${missingKeys.join(', ')}] that is NOT present in the SCP-authored WHERE. The SCP ` +
45
+ `compile cannot auto-apply FIND_FILTER (no model context at compile time), so the ` +
46
+ `scope predicate would be silently dropped (soft-delete / tenant scope leak). Fold ` +
47
+ `the FIND_FILTER predicates into the authored L.Select({ where }) explicitly ` +
48
+ `(e.g. whereEq/whereIsNull on ${missingKeys.join(', ')}).`);
49
+ this.modelName = modelName;
50
+ this.missingKeys = missingKeys;
51
+ this.name = 'FindFilterLeakError';
52
+ }
53
+ }
54
+ exports.FindFilterLeakError = FindFilterLeakError;
55
+ /**
56
+ * Extract the top-level predicate KEYS a `FIND_FILTER` folds into a WHERE. Uses the SAME
57
+ * `condsToRecord` v1 runs when merging (`DBModel._buildSelectSQL`:597) so the key set is
58
+ * exactly what v1 would add to `normalizedCond`. `__or__` (grouped OR) is kept as a key so a
59
+ * scoped OR-group also demands explicit authoring (fail-closed; never silently satisfied).
60
+ */
61
+ function findFilterKeys(filter) {
62
+ if (!filter || filter.length === 0)
63
+ return [];
64
+ return Object.keys((0, Column_1.condsToRecord)(filter));
65
+ }
66
+ /**
67
+ * Fail-closed guard: assert a model's `FIND_FILTER` scope keys are all present in the
68
+ * authored WHERE key set BEFORE an SCP compile of that model. No FIND_FILTER → no-op. When
69
+ * present, EVERY scope key must appear in `authoredWhereKeys`; any missing key throws
70
+ * {@link FindFilterLeakError}. The caller passes the top-level keys of the object it hands to
71
+ * `L.Select({ where })` (the same shape `condsToRecord` yields), so the check compares
72
+ * like-for-like against v1's merged predicate.
73
+ *
74
+ * @param model a `DBModel`-shaped source that MAY declare `FIND_FILTER`.
75
+ * @param authoredWhereKeys the top-level WHERE keys the SCP author expressed for this model.
76
+ * @throws FindFilterLeakError when a declared scope key is absent from the authored WHERE.
77
+ */
78
+ function assertFindFilterFolded(model, authoredWhereKeys) {
79
+ const required = findFilterKeys(model.FIND_FILTER);
80
+ if (required.length === 0)
81
+ return; // No implicit scope → nothing to fold → no-op.
82
+ const present = new Set(authoredWhereKeys);
83
+ const missing = required.filter((k) => !present.has(k));
84
+ if (missing.length > 0) {
85
+ throw new FindFilterLeakError(model.name ?? '<anonymous model>', missing);
86
+ }
87
+ }
88
+ //# sourceMappingURL=find-filter-guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"find-filter-guard.js","sourceRoot":"","sources":["../../src/scp/find-filter-guard.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;;;AA0CH,wCAGC;AAcD,wDAWC;AApED,sCAAsD;AAUtD;;;;GAIG;AACH,MAAa,mBAAoB,SAAQ,KAAK;IAGjC;IAEA;IAJX;IACE,sDAAsD;IAC7C,SAAiB;IAC1B,2EAA2E;IAClE,WAA8B;QAEvC,KAAK,CACH,4BAA4B,SAAS,4CAA4C;YAC/E,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,2DAA2D;YACrF,mFAAmF;YACnF,oFAAoF;YACpF,8EAA8E;YAC9E,gCAAgC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAC7D,CAAC;QAXO,cAAS,GAAT,SAAS,CAAQ;QAEjB,gBAAW,GAAX,WAAW,CAAmB;QAUvC,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;IACpC,CAAC;CACF;AAjBD,kDAiBC;AAED;;;;;GAKG;AACH,SAAgB,cAAc,CAAC,MAAgC;IAC7D,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAC9C,OAAO,MAAM,CAAC,IAAI,CAAC,IAAA,sBAAa,EAAC,MAAM,CAAC,CAAC,CAAC;AAC5C,CAAC;AAED;;;;;;;;;;;GAWG;AACH,SAAgB,sBAAsB,CACpC,KAAuB,EACvB,iBAAmC;IAEnC,MAAM,QAAQ,GAAG,cAAc,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IACnD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,+CAA+C;IAClF,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,iBAAiB,CAAC,CAAC;IAC3C,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACxD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,mBAAmB,CAAC,KAAK,CAAC,IAAI,IAAI,mBAAmB,EAAE,OAAO,CAAC,CAAC;IAC5E,CAAC;AACH,CAAC"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * litedbmodel v2 SCP — fragment RUNTIME (assemble + bind).
3
+ *
4
+ * This is the thin runtime a bundle drives. It does exactly three things:
5
+ *
6
+ * 1. ASSEMBLE — walk the ordered fragment list; drop any fragment whose `skip`
7
+ * is satisfied; concatenate the present fragments' `sql`, and their `params`
8
+ * in order. Nested-fragment params splice their own `sql` at the `?` and
9
+ * contribute their own params in order.
10
+ * 2. EVALUATE — turn each value-spec param into a concrete bound value using the
11
+ * runtime `input` (and upstream `wire` results).
12
+ * 3. RENDER — the produced `{ sql, params }` uses `?`; a dialect step turns `?`
13
+ * into `$N` for PostgreSQL (identical to the original driver's naive replace).
14
+ *
15
+ * NO SQL structure is generated here. The `sql` text is already complete; the
16
+ * runtime only splices nested-fragment text and fills `?`.
17
+ */
18
+ import { type Fragment, type Node, type WhereGroup, type ValueSpec, type PresenceCondition } from './model';
19
+ /** Runtime binding scope: FLAT — input keys and wire results are top-level roots. */
20
+ export interface Scope {
21
+ input: Record<string, unknown>;
22
+ wire?: Record<string, Record<string, unknown>>;
23
+ }
24
+ /** Is a fragment's `skip` satisfied (⇒ omit the fragment)? */
25
+ export declare function isSkipped(cond: PresenceCondition | undefined, scope: Scope): boolean;
26
+ /** Evaluate a value-spec to its bound value against the runtime scope. */
27
+ export declare function evalValueSpec(spec: ValueSpec, scope: Scope): unknown;
28
+ /**
29
+ * Assemble a single fragment: interleave its literal `sql` (split on `?`) with the
30
+ * rendered text of each param, concatenating params in order.
31
+ */
32
+ export declare function assembleFragment(frag: Fragment, scope: Scope): {
33
+ sql: string;
34
+ params: unknown[];
35
+ };
36
+ /**
37
+ * Assemble a WHERE group: join present members with `" AND "`, prefix `" WHERE "`.
38
+ * If no member is present, produce the empty string (identical to the ORIGINAL
39
+ * `DBConditions.compile` → `parts.length === 0 ? '' : parts.join(' AND ')`, with the
40
+ * `" WHERE "` prefix owned by the caller/select in the original — here folded in).
41
+ */
42
+ export declare function assembleWhereGroup(group: WhereGroup, scope: Scope): {
43
+ sql: string;
44
+ params: unknown[];
45
+ };
46
+ /**
47
+ * Assemble an ordered fragment/WHERE-group list into a single `{ sql, params }`
48
+ * (with `?`). Fragments whose `skip` is satisfied are omitted entirely (sql AND
49
+ * params). A WHERE group joins its present members with the original's text glue.
50
+ */
51
+ export declare function assemble(nodes: Node[], scope: Scope): {
52
+ sql: string;
53
+ params: unknown[];
54
+ };
55
+ /**
56
+ * PostgreSQL dialect render: `?` → `$1, $2, …`. Byte-identical to the original
57
+ * driver's `convertPlaceholders` (naive left-to-right replace; see
58
+ * `src/drivers/postgres.ts`).
59
+ */
60
+ export declare function toPostgres(sql: string): string;
61
+ //# sourceMappingURL=assemble.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assemble.d.ts","sourceRoot":"","sources":["../../../src/scp/fragment/assemble.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EACL,KAAK,QAAQ,EACb,KAAK,IAAI,EACT,KAAK,UAAU,EAEf,KAAK,SAAS,EACd,KAAK,iBAAiB,EAOvB,MAAM,SAAS,CAAC;AAEjB,qFAAqF;AACrF,MAAM,WAAW,KAAK;IACpB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CAChD;AAWD,8DAA8D;AAC9D,wBAAgB,SAAS,CAAC,IAAI,EAAE,iBAAiB,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAIpF;AAED,0EAA0E;AAC1E,wBAAgB,aAAa,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CA+BpE;AAYD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,EAAE,CAAA;CAAE,CAejG;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,EAAE,CAAA;CAAE,CAWtG;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,EAAE,CAAA;CAAE,CAgBxF;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAG9C"}