@happyvertical/sql 0.79.0 → 0.80.1

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 (33) hide show
  1. package/AGENT.md +1 -1
  2. package/dist/backup/index.js +210 -188
  3. package/dist/backup/index.js.map +1 -1
  4. package/dist/chunks/alter-utils-K7tiuj5L.js +135 -0
  5. package/dist/chunks/alter-utils-K7tiuj5L.js.map +1 -0
  6. package/dist/chunks/duckdb-DykBBzd6.js +1056 -0
  7. package/dist/chunks/duckdb-DykBBzd6.js.map +1 -0
  8. package/dist/chunks/duckdb-schema-utils-B-XBP8QF.js +115 -0
  9. package/dist/chunks/duckdb-schema-utils-B-XBP8QF.js.map +1 -0
  10. package/dist/chunks/postgres-cli-DzZcXSIG.js +272 -0
  11. package/dist/chunks/postgres-cli-DzZcXSIG.js.map +1 -0
  12. package/dist/chunks/schema-manager-a8RlxIE2.js +450 -0
  13. package/dist/chunks/schema-manager-a8RlxIE2.js.map +1 -0
  14. package/dist/chunks/sqlite-YgU9LCVy.js +1045 -0
  15. package/dist/chunks/sqlite-YgU9LCVy.js.map +1 -0
  16. package/dist/chunks/sqlite-native-BGtpx7Ro.js +902 -0
  17. package/dist/chunks/sqlite-native-BGtpx7Ro.js.map +1 -0
  18. package/dist/cli/claude-context.js +17 -17
  19. package/dist/cli/claude-context.js.map +1 -1
  20. package/dist/index.js +3244 -35
  21. package/dist/index.js.map +1 -1
  22. package/metadata.json +2 -2
  23. package/package.json +5 -5
  24. package/dist/chunks/duckdb-B6m78QdL.js +0 -924
  25. package/dist/chunks/duckdb-B6m78QdL.js.map +0 -1
  26. package/dist/chunks/index-CzdYvRFp.js +0 -3692
  27. package/dist/chunks/index-CzdYvRFp.js.map +0 -1
  28. package/dist/chunks/postgres-cli-Cr6bBZ3q.js +0 -209
  29. package/dist/chunks/postgres-cli-Cr6bBZ3q.js.map +0 -1
  30. package/dist/chunks/sqlite-CPCNeJIH.js +0 -937
  31. package/dist/chunks/sqlite-CPCNeJIH.js.map +0 -1
  32. package/dist/chunks/sqlite-native-DqVPKNUu.js +0 -1129
  33. package/dist/chunks/sqlite-native-DqVPKNUu.js.map +0 -1
@@ -0,0 +1,450 @@
1
+ //#region src/shared/utils.ts
2
+ /**
3
+ * Formats a database error to include all relevant details
4
+ *
5
+ * Database drivers often include additional properties beyond just `message`:
6
+ * - PostgreSQL: code, detail, hint, severity
7
+ * - DuckDB: may include additional context
8
+ * - SQLite/LibSQL: may include errno, code
9
+ *
10
+ * This function extracts all available error properties to provide
11
+ * better debugging information.
12
+ *
13
+ * @param error - The caught error object
14
+ * @returns Formatted error string with all available error details
15
+ */
16
+ function formatDbError(error) {
17
+ const dbError = error;
18
+ const parts = [];
19
+ if (dbError.message) parts.push(dbError.message);
20
+ if (dbError.code) parts.push(`code=${dbError.code}`);
21
+ if (dbError.detail) parts.push(`detail=${dbError.detail}`);
22
+ if (dbError.hint) parts.push(`hint=${dbError.hint}`);
23
+ if (dbError.severity) parts.push(`severity=${dbError.severity}`);
24
+ if (dbError.errno !== void 0) parts.push(`errno=${dbError.errno}`);
25
+ return parts.length > 0 ? parts.join(", ") : String(error);
26
+ }
27
+ /**
28
+ * Map of valid SQL operators for use in WHERE clauses
29
+ */
30
+ var VALID_OPERATORS = {
31
+ "=": "=",
32
+ ">": ">",
33
+ ">=": ">=",
34
+ "<": "<",
35
+ "<=": "<=",
36
+ "!=": "!=",
37
+ like: "LIKE",
38
+ in: "IN",
39
+ "not in": "NOT IN"
40
+ };
41
+ function isSimpleSqlIdentifier(field) {
42
+ return /^[a-zA-Z0-9_.]+$/.test(field);
43
+ }
44
+ function parseConditionKey(fullKey) {
45
+ const trimmed = fullKey.trim();
46
+ const lower = trimmed.toLowerCase();
47
+ for (const operator of [
48
+ "not in",
49
+ "like",
50
+ "in",
51
+ "!=",
52
+ ">=",
53
+ "<=",
54
+ ">",
55
+ "<",
56
+ "="
57
+ ]) if (lower.endsWith(` ${operator}`)) return {
58
+ field: trimmed.slice(0, -(operator.length + 1)).trim(),
59
+ operator,
60
+ explicitOperator: true
61
+ };
62
+ return {
63
+ field: trimmed,
64
+ operator: "=",
65
+ explicitOperator: false
66
+ };
67
+ }
68
+ /**
69
+ * Builds a single condition for a WHERE clause
70
+ * @internal
71
+ */
72
+ var buildCondition = (fullKey, value, currIndex, adapterType) => {
73
+ const { field, operator, explicitOperator } = parseConditionKey(fullKey);
74
+ if (!explicitOperator && !isSimpleSqlIdentifier(field)) throw new Error(`Invalid SQL identifier: ${field}`);
75
+ const sqlOperator = VALID_OPERATORS[operator] || "=";
76
+ const values = [];
77
+ let sql;
78
+ if (value === null) sql = `${field} IS ${sqlOperator === "=" ? "NULL" : "NOT NULL"}`;
79
+ else if ((sqlOperator === "IN" || sqlOperator === "NOT IN") && Array.isArray(value)) {
80
+ if (value.length === 0) throw new Error(`${sqlOperator} requires at least one value`);
81
+ sql = `${field} ${sqlOperator} (${value.map(() => `$${currIndex.value++}`).join(", ")})`;
82
+ values.push(...value);
83
+ } else if (value instanceof Date) {
84
+ if (adapterType === "duckdb" || adapterType === "json") sql = `${field} ${sqlOperator} CAST($${currIndex.value++} AS TIMESTAMP)`;
85
+ else sql = `${field} ${sqlOperator} $${currIndex.value++}`;
86
+ values.push(value.toISOString());
87
+ } else {
88
+ sql = `${field} ${sqlOperator} $${currIndex.value++}`;
89
+ values.push(value);
90
+ }
91
+ return {
92
+ sql,
93
+ values
94
+ };
95
+ };
96
+ /**
97
+ * Builds a SQL WHERE clause with parameterized values and flexible operators
98
+ *
99
+ * @param where - Conditions as object (AND-only) or 2D array (OR/AND compound)
100
+ * @param startIndex - Starting index for parameter numbering (default: 1)
101
+ * @param adapterType - Database adapter type. Controls Date handling:
102
+ * - `'duckdb'` / `'json'`: Wraps Date values in `CAST($N AS TIMESTAMP)` to
103
+ * prevent DuckDB ANY-type inference issues.
104
+ * - `'sqlite'` / `'postgres'` / `undefined`: Passes ISO strings directly
105
+ * (these adapters handle ISO timestamp strings natively).
106
+ *
107
+ * Keys with explicit operator suffixes are treated as SQL field/expression
108
+ * text. Keep those keys developer-controlled; do not pass end-user input as a
109
+ * condition key.
110
+ *
111
+ * @returns Object containing the SQL clause and array of values
112
+ *
113
+ * @example Basic Usage (Object format - AND-only):
114
+ * ```typescript
115
+ * buildWhere({
116
+ * 'status': 'active', // equals operator is default
117
+ * 'price >': 100, // greater than
118
+ * 'stock <=': 5, // less than or equal
119
+ * 'category in': ['A', 'B'], // IN clause for arrays
120
+ * 'name like': '%shirt%' // LIKE for pattern matching
121
+ * });
122
+ * ```
123
+ *
124
+ * @example 2D Array Format (OR/AND compound logic):
125
+ * ```typescript
126
+ * // WHERE (status = 'active' AND price > 100) OR (status = 'pending' AND priority = 'high')
127
+ * buildWhere([
128
+ * [{ status: 'active' }, { 'price >': 100 }],
129
+ * [{ status: 'pending' }, { priority: 'high' }]
130
+ * ]);
131
+ * ```
132
+ *
133
+ * @example NULL Handling:
134
+ * ```typescript
135
+ * buildWhere({
136
+ * 'deleted_at': null, // becomes "deleted_at IS NULL"
137
+ * 'updated_at !=': null, // becomes "updated_at IS NOT NULL"
138
+ * 'status': 'active' // regular comparison
139
+ * });
140
+ * ```
141
+ *
142
+ * @example Common Patterns:
143
+ * ```typescript
144
+ * // Price range
145
+ * buildWhere({
146
+ * 'price >=': 10,
147
+ * 'price <': 100
148
+ * });
149
+ *
150
+ * // Date filtering
151
+ * buildWhere({
152
+ * 'created_at >': startDate,
153
+ * 'created_at <=': endDate,
154
+ * 'deleted_at': null
155
+ * });
156
+ *
157
+ * // Search with LIKE
158
+ * buildWhere({
159
+ * 'title like': '%search%',
160
+ * 'description like': '%search%',
161
+ * 'status': 'published'
162
+ * });
163
+ *
164
+ * // Multiple values with IN
165
+ * buildWhere({
166
+ * 'role in': ['admin', 'editor'],
167
+ * 'active': true,
168
+ * 'last_login !=': null
169
+ * });
170
+ * ```
171
+ *
172
+ * The function handles:
173
+ * - Standard comparisons (=, >, >=, <, <=, !=)
174
+ * - NULL checks (IS NULL, IS NOT NULL)
175
+ * - IN clauses for arrays
176
+ * - LIKE for pattern matching
177
+ * - Object format: Multiple conditions combined with AND
178
+ * - 2D array format: Inner arrays ANDed, outer array ORed
179
+ */
180
+ var buildWhere = (where, startIndex = 1, adapterType) => {
181
+ let sql = "";
182
+ const values = [];
183
+ const currIndex = { value: startIndex };
184
+ if (Array.isArray(where)) {
185
+ if (where.length === 0) return {
186
+ sql: "",
187
+ values: []
188
+ };
189
+ const orGroups = [];
190
+ for (const andGroup of where) {
191
+ if (!Array.isArray(andGroup) || andGroup.length === 0) continue;
192
+ const andConditions = [];
193
+ for (const conditionObj of andGroup) for (const [fullKey, value] of Object.entries(conditionObj)) {
194
+ const result = buildCondition(fullKey, value, currIndex, adapterType);
195
+ andConditions.push(result.sql);
196
+ values.push(...result.values);
197
+ }
198
+ if (andConditions.length > 0) orGroups.push(`(${andConditions.join(" AND ")})`);
199
+ }
200
+ if (orGroups.length > 0) sql = `WHERE ${orGroups.join(" OR ")}`;
201
+ return {
202
+ sql,
203
+ values
204
+ };
205
+ }
206
+ if (where && Object.keys(where).length > 0) {
207
+ sql = "WHERE ";
208
+ for (const [fullKey, value] of Object.entries(where)) {
209
+ const result = buildCondition(fullKey, value, currIndex, adapterType);
210
+ if (sql !== "WHERE ") sql += " AND ";
211
+ sql += result.sql;
212
+ values.push(...result.values);
213
+ }
214
+ }
215
+ return {
216
+ sql,
217
+ values
218
+ };
219
+ };
220
+ //#endregion
221
+ //#region src/schema-manager.ts
222
+ /**
223
+ * Manages schema initialization from JSON manifests with dependency resolution
224
+ *
225
+ * Handles topological sorting of schema dependencies, table creation,
226
+ * index and trigger setup, and version tracking to avoid redundant re-initialization.
227
+ */
228
+ var DatabaseSchemaManager = class DatabaseSchemaManager {
229
+ static initializationLock = /* @__PURE__ */ new Map();
230
+ initializedSchemas = /* @__PURE__ */ new Set();
231
+ schemaVersions = /* @__PURE__ */ new Map();
232
+ /**
233
+ * Initializes database schemas from a JSON manifest with dependency resolution
234
+ *
235
+ * Schemas are topologically sorted by their declared dependencies and
236
+ * initialized in order. Supports legacy raw-SQL schemas via the `schema` option,
237
+ * JSON manifests via the `manifest` option, and schema overrides for extending
238
+ * base schemas.
239
+ *
240
+ * @param db - Database interface to execute DDL against
241
+ * @param options - Schema initialization options (manifest, overrides, force, debug)
242
+ * @returns Result with lists of initialized/skipped schemas, errors, and execution time
243
+ */
244
+ async initializeSchemas(db, options) {
245
+ const startTime = Date.now();
246
+ const result = {
247
+ initialized: [],
248
+ skipped: [],
249
+ errors: [],
250
+ executionTime: 0
251
+ };
252
+ try {
253
+ let schemas = {};
254
+ if (options.schema) {
255
+ console.log("[schema] Legacy SQL schema provided, converting to manifest format");
256
+ if (db.syncSchema) {
257
+ await db.syncSchema(options.schema);
258
+ result.initialized.push("legacy-sql");
259
+ }
260
+ result.executionTime = Date.now() - startTime;
261
+ return result;
262
+ }
263
+ if (options.manifest) schemas = { ...options.manifest.schemas };
264
+ if (options.overrides) schemas = {
265
+ ...schemas,
266
+ ...options.overrides
267
+ };
268
+ if (Object.keys(schemas).length === 0) {
269
+ console.warn("[schema] No schemas provided for initialization");
270
+ result.executionTime = Date.now() - startTime;
271
+ return result;
272
+ }
273
+ const dependencyGraph = this.buildDependencyGraph(schemas);
274
+ const initializationOrder = this.resolveDependencies(dependencyGraph);
275
+ if (options.debug) console.log("[schema] Initialization order:", initializationOrder);
276
+ for (const schemaName of initializationOrder) {
277
+ const schema = schemas[schemaName];
278
+ if (!schema) continue;
279
+ try {
280
+ await this.initializeSchema(db, schemaName, schema, {
281
+ force: options.force,
282
+ debug: options.debug
283
+ });
284
+ result.initialized.push(schemaName);
285
+ } catch (error) {
286
+ const errorMessage = error instanceof Error ? error.message : String(error);
287
+ result.errors.push({
288
+ schema: schemaName,
289
+ error: errorMessage
290
+ });
291
+ if (options.debug) console.error(`[schema] Failed to initialize ${schemaName}:`, error);
292
+ }
293
+ }
294
+ result.executionTime = Date.now() - startTime;
295
+ if (options.debug) console.log("[schema] Initialization complete:", result);
296
+ return result;
297
+ } catch (error) {
298
+ result.executionTime = Date.now() - startTime;
299
+ const errorMessage = error instanceof Error ? error.message : String(error);
300
+ result.errors.push({
301
+ schema: "dependency-resolution",
302
+ error: errorMessage
303
+ });
304
+ return result;
305
+ }
306
+ }
307
+ /**
308
+ * Initialize a single schema
309
+ */
310
+ async initializeSchema(db, schemaName, schema, options) {
311
+ const { tableName, version } = schema;
312
+ const lockKey = `${schemaName}:${tableName}`;
313
+ if (DatabaseSchemaManager.initializationLock.has(lockKey)) {
314
+ await DatabaseSchemaManager.initializationLock.get(lockKey);
315
+ return;
316
+ }
317
+ if (!options.force && this.isSchemaUpToDate(schemaName, version)) {
318
+ if (options.debug) console.log(`[schema] Skipping ${schemaName} - already up to date`);
319
+ return;
320
+ }
321
+ const initPromise = this.performSchemaInitialization(db, schemaName, schema, options);
322
+ DatabaseSchemaManager.initializationLock.set(lockKey, initPromise);
323
+ try {
324
+ await initPromise;
325
+ this.markSchemaInitialized(schemaName, version);
326
+ } finally {
327
+ DatabaseSchemaManager.initializationLock.delete(lockKey);
328
+ }
329
+ }
330
+ /**
331
+ * Perform the actual schema initialization
332
+ */
333
+ async performSchemaInitialization(db, schemaName, schema, options) {
334
+ const { tableName, columns, indexes, triggers } = schema;
335
+ if (options.debug) console.log(`[schema] Initializing ${schemaName} (${tableName})`);
336
+ if (!await db.tableExists(tableName)) {
337
+ await this.createTable(db, schema);
338
+ for (const index of indexes) await this.createIndex(db, tableName, index);
339
+ for (const trigger of triggers) await this.createTrigger(db, trigger);
340
+ } else if (options.force) {
341
+ await db.query(`DROP TABLE IF EXISTS ${tableName}`);
342
+ await this.createTable(db, schema);
343
+ for (const index of indexes) await this.createIndex(db, tableName, index);
344
+ for (const trigger of triggers) await this.createTrigger(db, trigger);
345
+ } else await this.updateSchemaIfNeeded(db, schema);
346
+ }
347
+ /**
348
+ * Create table from schema definition
349
+ */
350
+ async createTable(db, schema) {
351
+ const { tableName, columns, foreignKeys } = schema;
352
+ const columnDefinitions = [];
353
+ for (const [columnName, columnDef] of Object.entries(columns)) {
354
+ let def = `${columnName} ${columnDef.type}`;
355
+ if (columnDef.primaryKey) def += " PRIMARY KEY";
356
+ if (columnDef.unique && !columnDef.primaryKey) def += " UNIQUE";
357
+ if (columnDef.notNull) def += " NOT NULL";
358
+ if (columnDef.defaultValue !== void 0) def += ` DEFAULT ${columnDef.defaultValue}`;
359
+ if (columnDef.check) def += ` CHECK (${columnDef.check})`;
360
+ columnDefinitions.push(def);
361
+ }
362
+ for (const fk of foreignKeys) {
363
+ let fkDef = `FOREIGN KEY (${fk.column}) REFERENCES ${fk.referencesTable}(${fk.referencesColumn})`;
364
+ if (fk.onDelete) fkDef += ` ON DELETE ${fk.onDelete}`;
365
+ if (fk.onUpdate) fkDef += ` ON UPDATE ${fk.onUpdate}`;
366
+ columnDefinitions.push(fkDef);
367
+ }
368
+ const createTableSQL = `CREATE TABLE ${tableName} (\n ${columnDefinitions.join(",\n ")}\n)`;
369
+ await db.query(createTableSQL);
370
+ }
371
+ /**
372
+ * Create index from definition
373
+ */
374
+ async createIndex(db, tableName, index) {
375
+ const uniqueClause = index.unique ? "UNIQUE " : "";
376
+ const whereClause = index.where ? ` WHERE ${index.where}` : "";
377
+ const createIndexSQL = `CREATE ${uniqueClause}INDEX ${index.name} ON ${tableName} (${index.columns.join(", ")})${whereClause}`;
378
+ await db.query(createIndexSQL);
379
+ }
380
+ /**
381
+ * Create trigger from definition
382
+ */
383
+ async createTrigger(db, trigger) {
384
+ const conditionClause = trigger.condition ? ` WHEN ${trigger.condition}` : "";
385
+ const createTriggerSQL = `CREATE TRIGGER ${trigger.name} ${trigger.when} ${trigger.event} ON ${trigger.table}${conditionClause} BEGIN ${trigger.body} END`;
386
+ await db.query(createTriggerSQL);
387
+ }
388
+ /**
389
+ * Update schema if changes are detected
390
+ */
391
+ async updateSchemaIfNeeded(_db, schema) {
392
+ console.log(`[schema] Schema update logic not yet implemented for ${schema.tableName}`);
393
+ }
394
+ /**
395
+ * Build dependency graph from schemas
396
+ */
397
+ buildDependencyGraph(schemas) {
398
+ const graph = /* @__PURE__ */ new Map();
399
+ for (const [schemaName, schema] of Object.entries(schemas)) {
400
+ const dependencies = schema.dependencies.filter((dep) => Object.values(schemas).some((s) => s.tableName === dep));
401
+ graph.set(schemaName, dependencies.map((dep) => Object.entries(schemas).find(([_, s]) => s.tableName === dep)?.[0] || dep));
402
+ }
403
+ return graph;
404
+ }
405
+ /**
406
+ * Resolve dependencies using topological sort
407
+ */
408
+ resolveDependencies(graph) {
409
+ const resolved = [];
410
+ const visited = /* @__PURE__ */ new Set();
411
+ const visiting = /* @__PURE__ */ new Set();
412
+ const visit = (node) => {
413
+ if (visiting.has(node)) throw new Error(`Circular dependency detected involving ${node}`);
414
+ if (visited.has(node)) return;
415
+ visiting.add(node);
416
+ const dependencies = graph.get(node) || [];
417
+ for (const dep of dependencies) if (graph.has(dep)) visit(dep);
418
+ visiting.delete(node);
419
+ visited.add(node);
420
+ resolved.push(node);
421
+ };
422
+ for (const node of graph.keys()) if (!visited.has(node)) visit(node);
423
+ return resolved;
424
+ }
425
+ /**
426
+ * Check if schema is up to date
427
+ */
428
+ isSchemaUpToDate(schemaName, version) {
429
+ return this.initializedSchemas.has(schemaName) && this.schemaVersions.get(schemaName) === version;
430
+ }
431
+ /**
432
+ * Mark schema as initialized
433
+ */
434
+ markSchemaInitialized(schemaName, version) {
435
+ this.initializedSchemas.add(schemaName);
436
+ this.schemaVersions.set(schemaName, version);
437
+ }
438
+ /**
439
+ * Reset initialization state (for testing)
440
+ */
441
+ reset() {
442
+ this.initializedSchemas.clear();
443
+ this.schemaVersions.clear();
444
+ DatabaseSchemaManager.initializationLock.clear();
445
+ }
446
+ };
447
+ //#endregion
448
+ export { parseConditionKey as i, buildWhere as n, formatDbError as r, DatabaseSchemaManager as t };
449
+
450
+ //# sourceMappingURL=schema-manager-a8RlxIE2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-manager-a8RlxIE2.js","names":[],"sources":["../../src/shared/utils.ts","../../src/schema-manager.ts"],"sourcesContent":["/**\n * Shared SQL utilities that work in both browser and Node.js environments\n */\n\nimport type { WhereClause } from './types.js';\n\n/**\n * Formats a database error to include all relevant details\n *\n * Database drivers often include additional properties beyond just `message`:\n * - PostgreSQL: code, detail, hint, severity\n * - DuckDB: may include additional context\n * - SQLite/LibSQL: may include errno, code\n *\n * This function extracts all available error properties to provide\n * better debugging information.\n *\n * @param error - The caught error object\n * @returns Formatted error string with all available error details\n */\nexport function formatDbError(error: unknown): string {\n const dbError = error as {\n message?: string;\n code?: string;\n detail?: string;\n hint?: string;\n severity?: string;\n errno?: number;\n cause?: unknown;\n };\n\n const parts: string[] = [];\n\n if (dbError.message) parts.push(dbError.message);\n if (dbError.code) parts.push(`code=${dbError.code}`);\n if (dbError.detail) parts.push(`detail=${dbError.detail}`);\n if (dbError.hint) parts.push(`hint=${dbError.hint}`);\n if (dbError.severity) parts.push(`severity=${dbError.severity}`);\n if (dbError.errno !== undefined) parts.push(`errno=${dbError.errno}`);\n\n return parts.length > 0 ? parts.join(', ') : String(error);\n}\n\n/**\n * Map of valid SQL operators for use in WHERE clauses\n */\nconst VALID_OPERATORS = {\n '=': '=',\n '>': '>',\n '>=': '>=',\n '<': '<',\n '<=': '<=',\n '!=': '!=',\n like: 'LIKE',\n in: 'IN',\n 'not in': 'NOT IN',\n} as const;\n\nfunction isSimpleSqlIdentifier(field: string): boolean {\n return /^[a-zA-Z0-9_.]+$/.test(field);\n}\n\nexport function parseConditionKey(fullKey: string): {\n field: string;\n operator: string;\n explicitOperator: boolean;\n} {\n const trimmed = fullKey.trim();\n const lower = trimmed.toLowerCase();\n const operators = ['not in', 'like', 'in', '!=', '>=', '<=', '>', '<', '='];\n\n for (const operator of operators) {\n if (lower.endsWith(` ${operator}`)) {\n return {\n field: trimmed.slice(0, -(operator.length + 1)).trim(),\n operator,\n explicitOperator: true,\n };\n }\n }\n\n return { field: trimmed, operator: '=', explicitOperator: false };\n}\n\n/**\n * SQL adapter type for adapter-specific query generation\n */\nexport type SqlAdapterType = 'sqlite' | 'postgres' | 'duckdb' | 'json';\n\n/**\n * Builds a single condition for a WHERE clause\n * @internal\n */\nconst buildCondition = (\n fullKey: string,\n value: any,\n currIndex: { value: number },\n adapterType?: SqlAdapterType,\n): { sql: string; values: any[] } => {\n const { field, operator, explicitOperator } = parseConditionKey(fullKey);\n if (!explicitOperator && !isSimpleSqlIdentifier(field)) {\n throw new Error(`Invalid SQL identifier: ${field}`);\n }\n const sqlOperator =\n VALID_OPERATORS[operator as keyof typeof VALID_OPERATORS] || '=';\n const values: any[] = [];\n\n let sql: string;\n\n if (value === null) {\n sql = `${field} IS ${sqlOperator === '=' ? 'NULL' : 'NOT NULL'}`;\n } else if (\n (sqlOperator === 'IN' || sqlOperator === 'NOT IN') &&\n Array.isArray(value)\n ) {\n if (value.length === 0) {\n throw new Error(`${sqlOperator} requires at least one value`);\n }\n const placeholders = value.map(() => `$${currIndex.value++}`).join(', ');\n sql = `${field} ${sqlOperator} (${placeholders})`;\n values.push(...value);\n } else if (value instanceof Date) {\n // DuckDB/JSON need CAST to TIMESTAMP to prevent ANY type inference (issue #540)\n // SQLite/PostgreSQL handle ISO strings natively without CAST\n const needsCast = adapterType === 'duckdb' || adapterType === 'json';\n if (needsCast) {\n sql = `${field} ${sqlOperator} CAST($${currIndex.value++} AS TIMESTAMP)`;\n } else {\n sql = `${field} ${sqlOperator} $${currIndex.value++}`;\n }\n values.push(value.toISOString());\n } else {\n sql = `${field} ${sqlOperator} $${currIndex.value++}`;\n values.push(value);\n }\n\n return { sql, values };\n};\n\n/**\n * Builds a SQL WHERE clause with parameterized values and flexible operators\n *\n * @param where - Conditions as object (AND-only) or 2D array (OR/AND compound)\n * @param startIndex - Starting index for parameter numbering (default: 1)\n * @param adapterType - Database adapter type. Controls Date handling:\n * - `'duckdb'` / `'json'`: Wraps Date values in `CAST($N AS TIMESTAMP)` to\n * prevent DuckDB ANY-type inference issues.\n * - `'sqlite'` / `'postgres'` / `undefined`: Passes ISO strings directly\n * (these adapters handle ISO timestamp strings natively).\n *\n * Keys with explicit operator suffixes are treated as SQL field/expression\n * text. Keep those keys developer-controlled; do not pass end-user input as a\n * condition key.\n *\n * @returns Object containing the SQL clause and array of values\n *\n * @example Basic Usage (Object format - AND-only):\n * ```typescript\n * buildWhere({\n * 'status': 'active', // equals operator is default\n * 'price >': 100, // greater than\n * 'stock <=': 5, // less than or equal\n * 'category in': ['A', 'B'], // IN clause for arrays\n * 'name like': '%shirt%' // LIKE for pattern matching\n * });\n * ```\n *\n * @example 2D Array Format (OR/AND compound logic):\n * ```typescript\n * // WHERE (status = 'active' AND price > 100) OR (status = 'pending' AND priority = 'high')\n * buildWhere([\n * [{ status: 'active' }, { 'price >': 100 }],\n * [{ status: 'pending' }, { priority: 'high' }]\n * ]);\n * ```\n *\n * @example NULL Handling:\n * ```typescript\n * buildWhere({\n * 'deleted_at': null, // becomes \"deleted_at IS NULL\"\n * 'updated_at !=': null, // becomes \"updated_at IS NOT NULL\"\n * 'status': 'active' // regular comparison\n * });\n * ```\n *\n * @example Common Patterns:\n * ```typescript\n * // Price range\n * buildWhere({\n * 'price >=': 10,\n * 'price <': 100\n * });\n *\n * // Date filtering\n * buildWhere({\n * 'created_at >': startDate,\n * 'created_at <=': endDate,\n * 'deleted_at': null\n * });\n *\n * // Search with LIKE\n * buildWhere({\n * 'title like': '%search%',\n * 'description like': '%search%',\n * 'status': 'published'\n * });\n *\n * // Multiple values with IN\n * buildWhere({\n * 'role in': ['admin', 'editor'],\n * 'active': true,\n * 'last_login !=': null\n * });\n * ```\n *\n * The function handles:\n * - Standard comparisons (=, >, >=, <, <=, !=)\n * - NULL checks (IS NULL, IS NOT NULL)\n * - IN clauses for arrays\n * - LIKE for pattern matching\n * - Object format: Multiple conditions combined with AND\n * - 2D array format: Inner arrays ANDed, outer array ORed\n */\nexport const buildWhere = (\n where: WhereClause,\n startIndex = 1,\n adapterType?: SqlAdapterType,\n) => {\n let sql = '';\n const values: any[] = [];\n const currIndex = { value: startIndex };\n\n // Handle 2D array format for OR/AND compound logic\n if (Array.isArray(where)) {\n if (where.length === 0) {\n return { sql: '', values: [] };\n }\n\n const orGroups: string[] = [];\n\n for (const andGroup of where) {\n if (!Array.isArray(andGroup) || andGroup.length === 0) {\n continue;\n }\n\n const andConditions: string[] = [];\n\n for (const conditionObj of andGroup) {\n for (const [fullKey, value] of Object.entries(conditionObj)) {\n const result = buildCondition(fullKey, value, currIndex, adapterType);\n andConditions.push(result.sql);\n values.push(...result.values);\n }\n }\n\n if (andConditions.length > 0) {\n // Wrap AND group in parentheses\n orGroups.push(`(${andConditions.join(' AND ')})`);\n }\n }\n\n if (orGroups.length > 0) {\n sql = `WHERE ${orGroups.join(' OR ')}`;\n }\n\n return { sql, values };\n }\n\n // Handle object format (original behavior - AND-only)\n if (where && Object.keys(where).length > 0) {\n sql = 'WHERE ';\n for (const [fullKey, value] of Object.entries(where)) {\n const result = buildCondition(fullKey, value, currIndex, adapterType);\n\n if (sql !== 'WHERE ') {\n sql += ' AND ';\n }\n\n sql += result.sql;\n values.push(...result.values);\n }\n }\n\n return { sql, values };\n};\n","/**\n * Schema management and dependency resolution for JSON manifests\n * Moved from SMRT package to SQL package for proper separation of concerns\n */\n\nimport type {\n DatabaseInterface,\n IndexDefinition,\n SchemaDefinition,\n SchemaInitializationOptions,\n TriggerDefinition,\n} from './shared/types.js';\n\n/**\n * Result returned by DatabaseSchemaManager.initializeSchemas()\n *\n * Contains the list of schemas that were successfully initialized,\n * any that were skipped (already up to date), errors encountered,\n * and the total execution time in milliseconds.\n */\nexport interface SchemaInitializationResult {\n initialized: string[];\n skipped: string[];\n errors: Array<{ schema: string; error: string }>;\n executionTime: number;\n}\n\n/**\n * Manages schema initialization from JSON manifests with dependency resolution\n *\n * Handles topological sorting of schema dependencies, table creation,\n * index and trigger setup, and version tracking to avoid redundant re-initialization.\n */\nexport class DatabaseSchemaManager {\n private static initializationLock = new Map<string, Promise<void>>();\n private initializedSchemas = new Set<string>();\n private schemaVersions = new Map<string, string>();\n\n /**\n * Initializes database schemas from a JSON manifest with dependency resolution\n *\n * Schemas are topologically sorted by their declared dependencies and\n * initialized in order. Supports legacy raw-SQL schemas via the `schema` option,\n * JSON manifests via the `manifest` option, and schema overrides for extending\n * base schemas.\n *\n * @param db - Database interface to execute DDL against\n * @param options - Schema initialization options (manifest, overrides, force, debug)\n * @returns Result with lists of initialized/skipped schemas, errors, and execution time\n */\n async initializeSchemas(\n db: DatabaseInterface,\n options: SchemaInitializationOptions,\n ): Promise<SchemaInitializationResult> {\n const startTime = Date.now();\n const result: SchemaInitializationResult = {\n initialized: [],\n skipped: [],\n errors: [],\n executionTime: 0,\n };\n\n try {\n let schemas: Record<string, SchemaDefinition> = {};\n\n // Handle legacy SQL schema format\n if (options.schema) {\n console.log(\n '[schema] Legacy SQL schema provided, converting to manifest format',\n );\n // For legacy support, we'll still use the original syncSchema method\n if (db.syncSchema) {\n await db.syncSchema(options.schema);\n result.initialized.push('legacy-sql');\n }\n result.executionTime = Date.now() - startTime;\n return result;\n }\n\n // Handle JSON manifest format\n if (options.manifest) {\n schemas = { ...options.manifest.schemas };\n }\n\n // Apply schema overrides\n if (options.overrides) {\n schemas = { ...schemas, ...options.overrides };\n }\n\n if (Object.keys(schemas).length === 0) {\n console.warn('[schema] No schemas provided for initialization');\n result.executionTime = Date.now() - startTime;\n return result;\n }\n\n // Build dependency graph\n const dependencyGraph = this.buildDependencyGraph(schemas);\n\n // Get initialization order\n const initializationOrder = this.resolveDependencies(dependencyGraph);\n\n if (options.debug) {\n console.log('[schema] Initialization order:', initializationOrder);\n }\n\n // Initialize schemas in dependency order\n for (const schemaName of initializationOrder) {\n const schema = schemas[schemaName];\n if (!schema) continue;\n\n try {\n await this.initializeSchema(db, schemaName, schema, {\n force: options.force,\n debug: options.debug,\n });\n result.initialized.push(schemaName);\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n result.errors.push({ schema: schemaName, error: errorMessage });\n\n if (options.debug) {\n console.error(\n `[schema] Failed to initialize ${schemaName}:`,\n error,\n );\n }\n }\n }\n\n result.executionTime = Date.now() - startTime;\n\n if (options.debug) {\n console.log('[schema] Initialization complete:', result);\n }\n\n return result;\n } catch (error) {\n result.executionTime = Date.now() - startTime;\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n result.errors.push({\n schema: 'dependency-resolution',\n error: errorMessage,\n });\n return result;\n }\n }\n\n /**\n * Initialize a single schema\n */\n private async initializeSchema(\n db: DatabaseInterface,\n schemaName: string,\n schema: SchemaDefinition,\n options: { force?: boolean; debug?: boolean },\n ): Promise<void> {\n const { tableName, version } = schema;\n const lockKey = `${schemaName}:${tableName}`;\n\n // Check if already being initialized\n if (DatabaseSchemaManager.initializationLock.has(lockKey)) {\n await DatabaseSchemaManager.initializationLock.get(lockKey);\n return;\n }\n\n // Check if already initialized and up to date\n if (!options.force && this.isSchemaUpToDate(schemaName, version)) {\n if (options.debug) {\n console.log(`[schema] Skipping ${schemaName} - already up to date`);\n }\n return;\n }\n\n // Create initialization promise\n const initPromise = this.performSchemaInitialization(\n db,\n schemaName,\n schema,\n options,\n );\n DatabaseSchemaManager.initializationLock.set(lockKey, initPromise);\n\n try {\n await initPromise;\n this.markSchemaInitialized(schemaName, version);\n } finally {\n DatabaseSchemaManager.initializationLock.delete(lockKey);\n }\n }\n\n /**\n * Perform the actual schema initialization\n */\n private async performSchemaInitialization(\n db: DatabaseInterface,\n schemaName: string,\n schema: SchemaDefinition,\n options: { force?: boolean; debug?: boolean },\n ): Promise<void> {\n const { tableName, columns, indexes, triggers } = schema;\n\n if (options.debug) {\n console.log(`[schema] Initializing ${schemaName} (${tableName})`);\n }\n\n // Check if table exists\n const tableExists = await db.tableExists(tableName);\n\n if (!tableExists) {\n // Create table\n await this.createTable(db, schema);\n\n // Create indexes\n for (const index of indexes) {\n await this.createIndex(db, tableName, index);\n }\n\n // Create triggers\n for (const trigger of triggers) {\n await this.createTrigger(db, trigger);\n }\n } else if (options.force) {\n // Recreate table if forced\n await db.query(`DROP TABLE IF EXISTS ${tableName}`);\n await this.createTable(db, schema);\n\n for (const index of indexes) {\n await this.createIndex(db, tableName, index);\n }\n\n for (const trigger of triggers) {\n await this.createTrigger(db, trigger);\n }\n } else {\n // Table exists, check for schema changes\n await this.updateSchemaIfNeeded(db, schema);\n }\n }\n\n /**\n * Create table from schema definition\n */\n private async createTable(\n db: DatabaseInterface,\n schema: SchemaDefinition,\n ): Promise<void> {\n const { tableName, columns, foreignKeys } = schema;\n\n const columnDefinitions: string[] = [];\n\n // Add column definitions\n for (const [columnName, columnDef] of Object.entries(columns)) {\n let def = `${columnName} ${columnDef.type}`;\n\n if (columnDef.primaryKey) def += ' PRIMARY KEY';\n if (columnDef.unique && !columnDef.primaryKey) def += ' UNIQUE';\n if (columnDef.notNull) def += ' NOT NULL';\n if (columnDef.defaultValue !== undefined) {\n def += ` DEFAULT ${columnDef.defaultValue}`;\n }\n if (columnDef.check) def += ` CHECK (${columnDef.check})`;\n\n columnDefinitions.push(def);\n }\n\n // Add foreign key constraints\n for (const fk of foreignKeys) {\n let fkDef = `FOREIGN KEY (${fk.column}) REFERENCES ${fk.referencesTable}(${fk.referencesColumn})`;\n if (fk.onDelete) fkDef += ` ON DELETE ${fk.onDelete}`;\n if (fk.onUpdate) fkDef += ` ON UPDATE ${fk.onUpdate}`;\n columnDefinitions.push(fkDef);\n }\n\n const createTableSQL = `CREATE TABLE ${tableName} (\\n ${columnDefinitions.join(',\\n ')}\\n)`;\n await db.query(createTableSQL);\n }\n\n /**\n * Create index from definition\n */\n private async createIndex(\n db: DatabaseInterface,\n tableName: string,\n index: IndexDefinition,\n ): Promise<void> {\n const uniqueClause = index.unique ? 'UNIQUE ' : '';\n const whereClause = index.where ? ` WHERE ${index.where}` : '';\n const createIndexSQL = `CREATE ${uniqueClause}INDEX ${index.name} ON ${tableName} (${index.columns.join(', ')})${whereClause}`;\n\n await db.query(createIndexSQL);\n }\n\n /**\n * Create trigger from definition\n */\n private async createTrigger(\n db: DatabaseInterface,\n trigger: TriggerDefinition,\n ): Promise<void> {\n const conditionClause = trigger.condition\n ? ` WHEN ${trigger.condition}`\n : '';\n const createTriggerSQL = `CREATE TRIGGER ${trigger.name} ${trigger.when} ${trigger.event} ON ${trigger.table}${conditionClause} BEGIN ${trigger.body} END`;\n\n await db.query(createTriggerSQL);\n }\n\n /**\n * Update schema if changes are detected\n */\n private async updateSchemaIfNeeded(\n _db: DatabaseInterface,\n schema: SchemaDefinition,\n ): Promise<void> {\n // For now, just log that update is needed\n // In future, implement ALTER TABLE logic\n console.log(\n `[schema] Schema update logic not yet implemented for ${schema.tableName}`,\n );\n }\n\n /**\n * Build dependency graph from schemas\n */\n private buildDependencyGraph(\n schemas: Record<string, SchemaDefinition>,\n ): Map<string, string[]> {\n const graph = new Map<string, string[]>();\n\n for (const [schemaName, schema] of Object.entries(schemas)) {\n const dependencies = schema.dependencies.filter((dep) =>\n Object.values(schemas).some((s) => s.tableName === dep),\n );\n graph.set(\n schemaName,\n dependencies.map(\n (dep) =>\n Object.entries(schemas).find(\n ([_, s]) => s.tableName === dep,\n )?.[0] || dep,\n ),\n );\n }\n\n return graph;\n }\n\n /**\n * Resolve dependencies using topological sort\n */\n private resolveDependencies(graph: Map<string, string[]>): string[] {\n const resolved: string[] = [];\n const visited = new Set<string>();\n const visiting = new Set<string>();\n\n const visit = (node: string) => {\n if (visiting.has(node)) {\n throw new Error(`Circular dependency detected involving ${node}`);\n }\n if (visited.has(node)) return;\n\n visiting.add(node);\n const dependencies = graph.get(node) || [];\n\n for (const dep of dependencies) {\n if (graph.has(dep)) {\n visit(dep);\n }\n }\n\n visiting.delete(node);\n visited.add(node);\n resolved.push(node);\n };\n\n for (const node of graph.keys()) {\n if (!visited.has(node)) {\n visit(node);\n }\n }\n\n return resolved;\n }\n\n /**\n * Check if schema is up to date\n */\n private isSchemaUpToDate(schemaName: string, version: string): boolean {\n return (\n this.initializedSchemas.has(schemaName) &&\n this.schemaVersions.get(schemaName) === version\n );\n }\n\n /**\n * Mark schema as initialized\n */\n private markSchemaInitialized(schemaName: string, version: string): void {\n this.initializedSchemas.add(schemaName);\n this.schemaVersions.set(schemaName, version);\n }\n\n /**\n * Reset initialization state (for testing)\n */\n reset(): void {\n this.initializedSchemas.clear();\n this.schemaVersions.clear();\n DatabaseSchemaManager.initializationLock.clear();\n }\n}\n"],"mappings":"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"}