turbine-orm 0.9.0 → 0.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -5
- package/dist/cjs/cli/migrate.js +2 -2
- package/dist/cjs/cli/studio.js +7 -7
- package/dist/cjs/client.js +3 -3
- package/dist/cjs/index.js +2 -2
- package/dist/cjs/query/builder.js +2641 -0
- package/dist/cjs/query/index.js +20 -0
- package/dist/cjs/query/types.js +7 -0
- package/dist/cjs/query/utils.js +122 -0
- package/dist/cjs/schema-sql.js +26 -26
- package/dist/cli/migrate.js +1 -1
- package/dist/cli/studio.js +1 -1
- package/dist/client.d.ts +1 -1
- package/dist/client.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/pipeline-submittable.d.ts +1 -1
- package/dist/pipeline.d.ts +1 -1
- package/dist/query/builder.d.ts +498 -0
- package/dist/query/builder.js +2638 -0
- package/dist/query/index.d.ts +13 -0
- package/dist/query/index.js +10 -0
- package/dist/query/types.d.ts +365 -0
- package/dist/query/types.js +7 -0
- package/dist/query/utils.d.ts +60 -0
- package/dist/query/utils.js +114 -0
- package/dist/schema-sql.js +1 -1
- package/package.json +8 -1
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* turbine-orm — Query builder barrel
|
|
4
|
+
*
|
|
5
|
+
* Re-exports every public symbol from the query submodules so that
|
|
6
|
+
* `import { … } from './query/index.js'` is a drop-in replacement for the
|
|
7
|
+
* former monolithic `import { … } from './query.js'`.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.QueryInterface = exports.sqlToPreparedName = exports.quoteIdent = exports.OPERATOR_KEYS = exports.LRUCache = exports.fnv1a64Hex = exports.escSingleQuote = exports.escapeLike = void 0;
|
|
11
|
+
var utils_js_1 = require("./utils.js");
|
|
12
|
+
Object.defineProperty(exports, "escapeLike", { enumerable: true, get: function () { return utils_js_1.escapeLike; } });
|
|
13
|
+
Object.defineProperty(exports, "escSingleQuote", { enumerable: true, get: function () { return utils_js_1.escSingleQuote; } });
|
|
14
|
+
Object.defineProperty(exports, "fnv1a64Hex", { enumerable: true, get: function () { return utils_js_1.fnv1a64Hex; } });
|
|
15
|
+
Object.defineProperty(exports, "LRUCache", { enumerable: true, get: function () { return utils_js_1.LRUCache; } });
|
|
16
|
+
Object.defineProperty(exports, "OPERATOR_KEYS", { enumerable: true, get: function () { return utils_js_1.OPERATOR_KEYS; } });
|
|
17
|
+
Object.defineProperty(exports, "quoteIdent", { enumerable: true, get: function () { return utils_js_1.quoteIdent; } });
|
|
18
|
+
Object.defineProperty(exports, "sqlToPreparedName", { enumerable: true, get: function () { return utils_js_1.sqlToPreparedName; } });
|
|
19
|
+
var builder_js_1 = require("./builder.js");
|
|
20
|
+
Object.defineProperty(exports, "QueryInterface", { enumerable: true, get: function () { return builder_js_1.QueryInterface; } });
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* turbine-orm — Query builder utilities
|
|
4
|
+
*
|
|
5
|
+
* Standalone utility functions and classes used by the query builder.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.OPERATOR_KEYS = exports.LRUCache = void 0;
|
|
9
|
+
exports.quoteIdent = quoteIdent;
|
|
10
|
+
exports.escSingleQuote = escSingleQuote;
|
|
11
|
+
exports.escapeLike = escapeLike;
|
|
12
|
+
exports.fnv1a64Hex = fnv1a64Hex;
|
|
13
|
+
exports.sqlToPreparedName = sqlToPreparedName;
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
// Identifier quoting — prevents SQL injection via table/column names
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
/**
|
|
18
|
+
* Quote a SQL identifier (table name, column name) using Postgres double-quote
|
|
19
|
+
* rules: wrap in double quotes, escape internal double quotes by doubling them.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* quoteIdent('users') → '"users"'
|
|
23
|
+
* quoteIdent('my"table') → '"my""table"'
|
|
24
|
+
* quoteIdent('user name') → '"user name"'
|
|
25
|
+
*/
|
|
26
|
+
function quoteIdent(name) {
|
|
27
|
+
return `"${name.replace(/"/g, '""')}"`;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Escape single quotes for use as string keys in json_build_object().
|
|
31
|
+
* Doubles single quotes per SQL quoting rules.
|
|
32
|
+
*/
|
|
33
|
+
function escSingleQuote(s) {
|
|
34
|
+
return s.replace(/'/g, "''");
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Escape LIKE pattern metacharacters: %, _, and \.
|
|
38
|
+
* Must be used with `ESCAPE '\'` in the LIKE clause.
|
|
39
|
+
*/
|
|
40
|
+
function escapeLike(value) {
|
|
41
|
+
return value.replace(/\\/g, '\\\\').replace(/%/g, '\\%').replace(/_/g, '\\_');
|
|
42
|
+
}
|
|
43
|
+
// ---------------------------------------------------------------------------
|
|
44
|
+
// LRU cache — bounded SQL template cache to prevent memory leaks
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
/**
|
|
47
|
+
* Simple LRU (Least Recently Used) cache with a fixed maximum size.
|
|
48
|
+
* When the cache exceeds maxSize, the oldest (least recently used) entry is evicted.
|
|
49
|
+
* Uses Map insertion order for O(1) eviction.
|
|
50
|
+
*/
|
|
51
|
+
class LRUCache {
|
|
52
|
+
maxSize;
|
|
53
|
+
cache = new Map();
|
|
54
|
+
constructor(maxSize) {
|
|
55
|
+
this.maxSize = maxSize;
|
|
56
|
+
}
|
|
57
|
+
get(key) {
|
|
58
|
+
const value = this.cache.get(key);
|
|
59
|
+
if (value !== undefined) {
|
|
60
|
+
// Move to end (most recently used)
|
|
61
|
+
this.cache.delete(key);
|
|
62
|
+
this.cache.set(key, value);
|
|
63
|
+
}
|
|
64
|
+
return value;
|
|
65
|
+
}
|
|
66
|
+
set(key, value) {
|
|
67
|
+
if (this.cache.has(key)) {
|
|
68
|
+
this.cache.delete(key);
|
|
69
|
+
}
|
|
70
|
+
else if (this.cache.size >= this.maxSize) {
|
|
71
|
+
// Delete oldest (first) entry
|
|
72
|
+
const firstKey = this.cache.keys().next().value;
|
|
73
|
+
if (firstKey !== undefined)
|
|
74
|
+
this.cache.delete(firstKey);
|
|
75
|
+
}
|
|
76
|
+
this.cache.set(key, value);
|
|
77
|
+
}
|
|
78
|
+
get size() {
|
|
79
|
+
return this.cache.size;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
exports.LRUCache = LRUCache;
|
|
83
|
+
/**
|
|
84
|
+
* FNV-1a 64-bit hash returning 16 lowercase hex chars.
|
|
85
|
+
* Single-loop string iteration. Uses BigInt for 64-bit math.
|
|
86
|
+
*
|
|
87
|
+
* @internal Exported for testing only.
|
|
88
|
+
*/
|
|
89
|
+
function fnv1a64Hex(s) {
|
|
90
|
+
// FNV-1a offset basis and prime for 64-bit
|
|
91
|
+
let hash = 0xcbf29ce484222325n;
|
|
92
|
+
const prime = 0x100000001b3n;
|
|
93
|
+
const mask = 0xffffffffffffffffn; // 64-bit mask
|
|
94
|
+
for (let i = 0; i < s.length; i++) {
|
|
95
|
+
hash ^= BigInt(s.charCodeAt(i));
|
|
96
|
+
hash = (hash * prime) & mask;
|
|
97
|
+
}
|
|
98
|
+
return hash.toString(16).padStart(16, '0');
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Derive a prepared-statement name from a SQL string.
|
|
102
|
+
* Format: `t_<16hex>` — always 18 chars, well under NAMEDATALEN (63).
|
|
103
|
+
*
|
|
104
|
+
* @internal Exported for testing only.
|
|
105
|
+
*/
|
|
106
|
+
function sqlToPreparedName(sql) {
|
|
107
|
+
return `t_${fnv1a64Hex(sql)}`;
|
|
108
|
+
}
|
|
109
|
+
/** Known operator keys — used to detect operator objects vs plain values */
|
|
110
|
+
exports.OPERATOR_KEYS = new Set([
|
|
111
|
+
'gt',
|
|
112
|
+
'gte',
|
|
113
|
+
'lt',
|
|
114
|
+
'lte',
|
|
115
|
+
'not',
|
|
116
|
+
'in',
|
|
117
|
+
'notIn',
|
|
118
|
+
'contains',
|
|
119
|
+
'startsWith',
|
|
120
|
+
'endsWith',
|
|
121
|
+
'mode',
|
|
122
|
+
]);
|
package/dist/cjs/schema-sql.js
CHANGED
|
@@ -14,7 +14,7 @@ exports.schemaDiff = schemaDiff;
|
|
|
14
14
|
exports.schemaPush = schemaPush;
|
|
15
15
|
exports.schemaToSQLString = schemaToSQLString;
|
|
16
16
|
const pg_1 = __importDefault(require("pg"));
|
|
17
|
-
const
|
|
17
|
+
const index_js_1 = require("./query/index.js");
|
|
18
18
|
const schema_js_1 = require("./schema.js");
|
|
19
19
|
// ---------------------------------------------------------------------------
|
|
20
20
|
// SQL Generation — SchemaDef → CREATE TABLE statements
|
|
@@ -143,18 +143,18 @@ function generateCreateTable(table, resolveRef) {
|
|
|
143
143
|
}
|
|
144
144
|
// Append a table-level PRIMARY KEY constraint when a composite PK is set.
|
|
145
145
|
if (compositePk) {
|
|
146
|
-
const cols = compositePk.map((c) => (0,
|
|
146
|
+
const cols = compositePk.map((c) => (0, index_js_1.quoteIdent)((0, schema_js_1.camelToSnake)(c))).join(', ');
|
|
147
147
|
columnDefs.push(`PRIMARY KEY (${cols})`);
|
|
148
148
|
}
|
|
149
149
|
const body = columnDefs.map((d) => ` ${d}`).join(',\n');
|
|
150
|
-
return `CREATE TABLE ${(0,
|
|
150
|
+
return `CREATE TABLE ${(0, index_js_1.quoteIdent)(tableName)} (\n${body}\n);`;
|
|
151
151
|
}
|
|
152
152
|
/**
|
|
153
153
|
* Generate a single column definition line (e.g. "id BIGSERIAL PRIMARY KEY").
|
|
154
154
|
*/
|
|
155
155
|
function generateColumnDef(fieldName, config, resolveRef) {
|
|
156
156
|
const snakeName = (0, schema_js_1.camelToSnake)(fieldName);
|
|
157
|
-
const parts = [(0,
|
|
157
|
+
const parts = [(0, index_js_1.quoteIdent)(snakeName)];
|
|
158
158
|
// Type
|
|
159
159
|
if (config.type === 'VARCHAR' && config.maxLength != null) {
|
|
160
160
|
parts.push(`VARCHAR(${config.maxLength})`);
|
|
@@ -193,7 +193,7 @@ function generateColumnDef(fieldName, config, resolveRef) {
|
|
|
193
193
|
if (refParts.length === 2) {
|
|
194
194
|
const rawTable = refParts[0];
|
|
195
195
|
const refTable = resolveRef ? resolveRef(rawTable) : rawTable;
|
|
196
|
-
parts.push(`REFERENCES ${(0,
|
|
196
|
+
parts.push(`REFERENCES ${(0, index_js_1.quoteIdent)(refTable)}(${(0, index_js_1.quoteIdent)(refParts[1])})`);
|
|
197
197
|
}
|
|
198
198
|
}
|
|
199
199
|
return parts.join(' ');
|
|
@@ -242,7 +242,7 @@ function generateForeignKeyIndexes(table) {
|
|
|
242
242
|
if (config.referencesTarget) {
|
|
243
243
|
const snakeName = (0, schema_js_1.camelToSnake)(fieldName);
|
|
244
244
|
const indexName = `idx_${table.name}_${snakeName}`;
|
|
245
|
-
indexes.push(`CREATE INDEX ${(0,
|
|
245
|
+
indexes.push(`CREATE INDEX ${(0, index_js_1.quoteIdent)(indexName)} ON ${(0, index_js_1.quoteIdent)(table.name)}(${(0, index_js_1.quoteIdent)(snakeName)});`);
|
|
246
246
|
}
|
|
247
247
|
}
|
|
248
248
|
return indexes;
|
|
@@ -317,7 +317,7 @@ async function schemaDiff(schema, connectionString) {
|
|
|
317
317
|
const fkIndexes = generateForeignKeyIndexes(tableDef);
|
|
318
318
|
result.statements.push(...fkIndexes);
|
|
319
319
|
// Reverse: DROP TABLE (with indexes — they drop automatically)
|
|
320
|
-
result.reverseStatements.unshift(`DROP TABLE IF EXISTS ${(0,
|
|
320
|
+
result.reverseStatements.unshift(`DROP TABLE IF EXISTS ${(0, index_js_1.quoteIdent)(ddlName)} CASCADE;`);
|
|
321
321
|
}
|
|
322
322
|
}
|
|
323
323
|
// Tables to drop (in DB but not in schema)
|
|
@@ -342,8 +342,8 @@ async function schemaDiff(schema, connectionString) {
|
|
|
342
342
|
if (!dbCol) {
|
|
343
343
|
// Column exists in schema but not in DB — ADD COLUMN
|
|
344
344
|
const colDef = generateColumnDef(fieldName, config, resolveRef);
|
|
345
|
-
const sql = `ALTER TABLE ${(0,
|
|
346
|
-
const reverseSql = `ALTER TABLE ${(0,
|
|
345
|
+
const sql = `ALTER TABLE ${(0, index_js_1.quoteIdent)(tableName)} ADD COLUMN ${colDef};`;
|
|
346
|
+
const reverseSql = `ALTER TABLE ${(0, index_js_1.quoteIdent)(tableName)} DROP COLUMN ${(0, index_js_1.quoteIdent)(snakeName)};`;
|
|
347
347
|
alterDef.columns.push({ column: snakeName, action: 'add', sql, reverseSql });
|
|
348
348
|
result.statements.push(sql);
|
|
349
349
|
result.reverseStatements.unshift(reverseSql);
|
|
@@ -354,8 +354,8 @@ async function schemaDiff(schema, connectionString) {
|
|
|
354
354
|
if (expectedUdt && dbCol.udtName !== expectedUdt) {
|
|
355
355
|
const sqlType = config.type === 'VARCHAR' && config.maxLength ? `VARCHAR(${config.maxLength})` : config.type;
|
|
356
356
|
const oldSqlType = udtToSqlType(dbCol.udtName, dbCol.maxLength);
|
|
357
|
-
const sql = `ALTER TABLE ${(0,
|
|
358
|
-
const reverseSql = `ALTER TABLE ${(0,
|
|
357
|
+
const sql = `ALTER TABLE ${(0, index_js_1.quoteIdent)(tableName)} ALTER COLUMN ${(0, index_js_1.quoteIdent)(snakeName)} TYPE ${sqlType} USING ${(0, index_js_1.quoteIdent)(snakeName)}::${sqlType};`;
|
|
358
|
+
const reverseSql = `ALTER TABLE ${(0, index_js_1.quoteIdent)(tableName)} ALTER COLUMN ${(0, index_js_1.quoteIdent)(snakeName)} TYPE ${oldSqlType} USING ${(0, index_js_1.quoteIdent)(snakeName)}::${oldSqlType};`;
|
|
359
359
|
alterDef.columns.push({ column: snakeName, action: 'alter_type', sql, reverseSql });
|
|
360
360
|
result.statements.push(sql);
|
|
361
361
|
result.reverseStatements.unshift(reverseSql);
|
|
@@ -364,15 +364,15 @@ async function schemaDiff(schema, connectionString) {
|
|
|
364
364
|
const shouldBeNotNull = config.isNotNull || config.isPrimaryKey || config.type === 'BIGSERIAL';
|
|
365
365
|
const isCurrentlyNullable = dbCol.isNullable;
|
|
366
366
|
if (shouldBeNotNull && isCurrentlyNullable && !config.isNullable) {
|
|
367
|
-
const sql = `ALTER TABLE ${(0,
|
|
368
|
-
const reverseSql = `ALTER TABLE ${(0,
|
|
367
|
+
const sql = `ALTER TABLE ${(0, index_js_1.quoteIdent)(tableName)} ALTER COLUMN ${(0, index_js_1.quoteIdent)(snakeName)} SET NOT NULL;`;
|
|
368
|
+
const reverseSql = `ALTER TABLE ${(0, index_js_1.quoteIdent)(tableName)} ALTER COLUMN ${(0, index_js_1.quoteIdent)(snakeName)} DROP NOT NULL;`;
|
|
369
369
|
alterDef.columns.push({ column: snakeName, action: 'set_not_null', sql, reverseSql });
|
|
370
370
|
result.statements.push(sql);
|
|
371
371
|
result.reverseStatements.unshift(reverseSql);
|
|
372
372
|
}
|
|
373
373
|
else if (!shouldBeNotNull && !isCurrentlyNullable && config.isNullable) {
|
|
374
|
-
const sql = `ALTER TABLE ${(0,
|
|
375
|
-
const reverseSql = `ALTER TABLE ${(0,
|
|
374
|
+
const sql = `ALTER TABLE ${(0, index_js_1.quoteIdent)(tableName)} ALTER COLUMN ${(0, index_js_1.quoteIdent)(snakeName)} DROP NOT NULL;`;
|
|
375
|
+
const reverseSql = `ALTER TABLE ${(0, index_js_1.quoteIdent)(tableName)} ALTER COLUMN ${(0, index_js_1.quoteIdent)(snakeName)} SET NOT NULL;`;
|
|
376
376
|
alterDef.columns.push({ column: snakeName, action: 'drop_not_null', sql, reverseSql });
|
|
377
377
|
result.statements.push(sql);
|
|
378
378
|
result.reverseStatements.unshift(reverseSql);
|
|
@@ -384,16 +384,16 @@ async function schemaDiff(schema, connectionString) {
|
|
|
384
384
|
const dbDefault = dbCol.columnDefault;
|
|
385
385
|
if (schemaDefault && !dbDefault) {
|
|
386
386
|
// Schema has default, DB doesn't
|
|
387
|
-
const sql = `ALTER TABLE ${(0,
|
|
388
|
-
const reverseSql = `ALTER TABLE ${(0,
|
|
387
|
+
const sql = `ALTER TABLE ${(0, index_js_1.quoteIdent)(tableName)} ALTER COLUMN ${(0, index_js_1.quoteIdent)(snakeName)} SET DEFAULT ${schemaDefault};`;
|
|
388
|
+
const reverseSql = `ALTER TABLE ${(0, index_js_1.quoteIdent)(tableName)} ALTER COLUMN ${(0, index_js_1.quoteIdent)(snakeName)} DROP DEFAULT;`;
|
|
389
389
|
alterDef.columns.push({ column: snakeName, action: 'set_default', sql, reverseSql });
|
|
390
390
|
result.statements.push(sql);
|
|
391
391
|
result.reverseStatements.unshift(reverseSql);
|
|
392
392
|
}
|
|
393
393
|
else if (!schemaDefault && dbDefault && !isSequenceDefault(dbDefault)) {
|
|
394
394
|
// DB has a non-sequence default, schema doesn't
|
|
395
|
-
const sql = `ALTER TABLE ${(0,
|
|
396
|
-
const reverseSql = `ALTER TABLE ${(0,
|
|
395
|
+
const sql = `ALTER TABLE ${(0, index_js_1.quoteIdent)(tableName)} ALTER COLUMN ${(0, index_js_1.quoteIdent)(snakeName)} DROP DEFAULT;`;
|
|
396
|
+
const reverseSql = `ALTER TABLE ${(0, index_js_1.quoteIdent)(tableName)} ALTER COLUMN ${(0, index_js_1.quoteIdent)(snakeName)} SET DEFAULT ${dbDefault};`;
|
|
397
397
|
alterDef.columns.push({ column: snakeName, action: 'drop_default', sql, reverseSql });
|
|
398
398
|
result.statements.push(sql);
|
|
399
399
|
result.reverseStatements.unshift(reverseSql);
|
|
@@ -403,8 +403,8 @@ async function schemaDiff(schema, connectionString) {
|
|
|
403
403
|
!isSequenceDefault(dbDefault) &&
|
|
404
404
|
!defaultsMatch(schemaDefault, dbDefault)) {
|
|
405
405
|
// Both have defaults but they differ
|
|
406
|
-
const sql = `ALTER TABLE ${(0,
|
|
407
|
-
const reverseSql = `ALTER TABLE ${(0,
|
|
406
|
+
const sql = `ALTER TABLE ${(0, index_js_1.quoteIdent)(tableName)} ALTER COLUMN ${(0, index_js_1.quoteIdent)(snakeName)} SET DEFAULT ${schemaDefault};`;
|
|
407
|
+
const reverseSql = `ALTER TABLE ${(0, index_js_1.quoteIdent)(tableName)} ALTER COLUMN ${(0, index_js_1.quoteIdent)(snakeName)} SET DEFAULT ${dbDefault};`;
|
|
408
408
|
alterDef.columns.push({ column: snakeName, action: 'set_default', sql, reverseSql });
|
|
409
409
|
result.statements.push(sql);
|
|
410
410
|
result.reverseStatements.unshift(reverseSql);
|
|
@@ -416,16 +416,16 @@ async function schemaDiff(schema, connectionString) {
|
|
|
416
416
|
const wantsUnique = config.isUnique === true;
|
|
417
417
|
if (wantsUnique && !hasDbUnique) {
|
|
418
418
|
const constraintName = `${tableName}_${snakeName}_key`;
|
|
419
|
-
const sql = `ALTER TABLE ${(0,
|
|
420
|
-
const reverseSql = `ALTER TABLE ${(0,
|
|
419
|
+
const sql = `ALTER TABLE ${(0, index_js_1.quoteIdent)(tableName)} ADD CONSTRAINT ${(0, index_js_1.quoteIdent)(constraintName)} UNIQUE (${(0, index_js_1.quoteIdent)(snakeName)});`;
|
|
420
|
+
const reverseSql = `ALTER TABLE ${(0, index_js_1.quoteIdent)(tableName)} DROP CONSTRAINT ${(0, index_js_1.quoteIdent)(constraintName)};`;
|
|
421
421
|
alterDef.columns.push({ column: snakeName, action: 'add_unique', sql, reverseSql });
|
|
422
422
|
result.statements.push(sql);
|
|
423
423
|
result.reverseStatements.unshift(reverseSql);
|
|
424
424
|
}
|
|
425
425
|
else if (!wantsUnique && hasDbUnique) {
|
|
426
426
|
const constraintName = tableUniques[snakeName];
|
|
427
|
-
const sql = `ALTER TABLE ${(0,
|
|
428
|
-
const reverseSql = `ALTER TABLE ${(0,
|
|
427
|
+
const sql = `ALTER TABLE ${(0, index_js_1.quoteIdent)(tableName)} DROP CONSTRAINT ${(0, index_js_1.quoteIdent)(constraintName)};`;
|
|
428
|
+
const reverseSql = `ALTER TABLE ${(0, index_js_1.quoteIdent)(tableName)} ADD CONSTRAINT ${(0, index_js_1.quoteIdent)(constraintName)} UNIQUE (${(0, index_js_1.quoteIdent)(snakeName)});`;
|
|
429
429
|
alterDef.columns.push({ column: snakeName, action: 'drop_unique', sql, reverseSql });
|
|
430
430
|
result.statements.push(sql);
|
|
431
431
|
result.reverseStatements.unshift(reverseSql);
|
|
@@ -436,7 +436,7 @@ async function schemaDiff(schema, connectionString) {
|
|
|
436
436
|
for (const dbColName of Object.keys(dbCols)) {
|
|
437
437
|
const hasField = Object.entries(tableDef.columns).some(([fieldName]) => (0, schema_js_1.camelToSnake)(fieldName) === dbColName);
|
|
438
438
|
if (!hasField) {
|
|
439
|
-
const sql = `ALTER TABLE ${(0,
|
|
439
|
+
const sql = `ALTER TABLE ${(0, index_js_1.quoteIdent)(tableName)} DROP COLUMN ${(0, index_js_1.quoteIdent)(dbColName)};`;
|
|
440
440
|
const reverseSql = `-- Cannot auto-reverse DROP COLUMN for "${dbColName}" — add it back manually`;
|
|
441
441
|
alterDef.columns.push({ column: dbColName, action: 'drop', sql, reverseSql });
|
|
442
442
|
// Don't auto-add drops to statements for safety — user must opt in
|
package/dist/cli/migrate.js
CHANGED
|
@@ -16,7 +16,7 @@ import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from
|
|
|
16
16
|
import { join } from 'node:path';
|
|
17
17
|
import pg from 'pg';
|
|
18
18
|
import { MigrationError } from '../errors.js';
|
|
19
|
-
import { quoteIdent } from '../query.js';
|
|
19
|
+
import { quoteIdent } from '../query/index.js';
|
|
20
20
|
// ---------------------------------------------------------------------------
|
|
21
21
|
// Tracking table management
|
|
22
22
|
// ---------------------------------------------------------------------------
|
package/dist/cli/studio.js
CHANGED
|
@@ -23,7 +23,7 @@ import { platform } from 'node:os';
|
|
|
23
23
|
import { dirname, resolve as pathResolve } from 'node:path';
|
|
24
24
|
import pg from 'pg';
|
|
25
25
|
import { introspect } from '../introspect.js';
|
|
26
|
-
import { QueryInterface, quoteIdent } from '../query.js';
|
|
26
|
+
import { QueryInterface, quoteIdent } from '../query/index.js';
|
|
27
27
|
import { STUDIO_HTML } from './studio-ui.generated.js';
|
|
28
28
|
// ---------------------------------------------------------------------------
|
|
29
29
|
// Main entry point
|
package/dist/client.d.ts
CHANGED
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
import pg from 'pg';
|
|
25
25
|
import { type ErrorMessageMode } from './errors.js';
|
|
26
26
|
import { type PipelineOptions, type PipelineResults } from './pipeline.js';
|
|
27
|
-
import { type DeferredQuery, QueryInterface, type QueryInterfaceOptions } from './query.js';
|
|
27
|
+
import { type DeferredQuery, QueryInterface, type QueryInterfaceOptions } from './query/index.js';
|
|
28
28
|
import type { SchemaMetadata } from './schema.js';
|
|
29
29
|
/**
|
|
30
30
|
* Minimal pg-compatible query result.
|
package/dist/client.js
CHANGED
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
import pg from 'pg';
|
|
25
25
|
import { setErrorMessageMode, TimeoutError, wrapPgError } from './errors.js';
|
|
26
26
|
import { executePipeline, pipelineSupported } from './pipeline.js';
|
|
27
|
-
import { QueryInterface } from './query.js';
|
|
27
|
+
import { QueryInterface } from './query/index.js';
|
|
28
28
|
/** Maps isolation level names to SQL */
|
|
29
29
|
const ISOLATION_LEVELS = {
|
|
30
30
|
ReadUncommitted: 'READ UNCOMMITTED',
|
package/dist/index.d.ts
CHANGED
|
@@ -37,7 +37,7 @@ export { CheckConstraintError, CircularRelationError, ConnectionError, DeadlockE
|
|
|
37
37
|
export { type GenerateOptions, generate } from './generate.js';
|
|
38
38
|
export { type IntrospectOptions, introspect } from './introspect.js';
|
|
39
39
|
export { executePipeline, type PipelineOptions, type PipelineResults, pipelineSupported } from './pipeline.js';
|
|
40
|
-
export { type AggregateArgs, type AggregateResult, type ArrayFilter, type CountArgs, type CreateArgs, type CreateManyArgs, type DeferredQuery, type DeleteArgs, type DeleteManyArgs, type FindManyArgs, type FindManyStreamArgs, type FindUniqueArgs, type GroupByArgs, type JsonFilter, type OrderDirection, QueryInterface, type RelationDescriptor, type RelationFilter, type TypedWithClause, type UpdateArgs, type UpdateInput, type UpdateManyArgs, type UpdateOperatorInput, type UpsertArgs, type WithClause, type WithOptions, type WithResult, } from './query.js';
|
|
40
|
+
export { type AggregateArgs, type AggregateResult, type ArrayFilter, type CountArgs, type CreateArgs, type CreateManyArgs, type DeferredQuery, type DeleteArgs, type DeleteManyArgs, type FindManyArgs, type FindManyStreamArgs, type FindUniqueArgs, type GroupByArgs, type JsonFilter, type OrderDirection, QueryInterface, type RelationDescriptor, type RelationFilter, type TypedWithClause, type UpdateArgs, type UpdateInput, type UpdateManyArgs, type UpdateOperatorInput, type UpsertArgs, type WithClause, type WithOptions, type WithResult, } from './query/index.js';
|
|
41
41
|
export type { ColumnMetadata, IndexMetadata, RelationDef, SchemaMetadata, TableMetadata, } from './schema.js';
|
|
42
42
|
export { camelToSnake, isDateType, pgArrayType, pgTypeToTs, singularize, snakeToCamel, snakeToPascal, } from './schema.js';
|
|
43
43
|
export { ColumnBuilder, type ColumnConfig, type ColumnDef, type ColumnType, type ColumnTypeName, column, defineSchema, type SchemaDef, type TableDef, table, } from './schema-builder.js';
|
package/dist/index.js
CHANGED
|
@@ -43,7 +43,7 @@ export { introspect } from './introspect.js';
|
|
|
43
43
|
// Pipeline
|
|
44
44
|
export { executePipeline, pipelineSupported } from './pipeline.js';
|
|
45
45
|
// Query builder
|
|
46
|
-
export { QueryInterface, } from './query.js';
|
|
46
|
+
export { QueryInterface, } from './query/index.js';
|
|
47
47
|
// Schema utilities
|
|
48
48
|
export { camelToSnake, isDateType, pgArrayType, pgTypeToTs, singularize, snakeToCamel, snakeToPascal, } from './schema.js';
|
|
49
49
|
// Schema builder — define schemas in TypeScript
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* to handle N queries in a single pipeline.
|
|
18
18
|
*/
|
|
19
19
|
import type { EventEmitter } from 'node:events';
|
|
20
|
-
import type { DeferredQuery } from './query.js';
|
|
20
|
+
import type { DeferredQuery } from './query/index.js';
|
|
21
21
|
/** The pg Connection object — an EventEmitter with wire-protocol methods */
|
|
22
22
|
export interface PgConnection extends EventEmitter {
|
|
23
23
|
stream: {
|
package/dist/pipeline.d.ts
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
* Hyperdrive), mock pools in tests, and any pool that doesn't expose pg internals.
|
|
20
20
|
*/
|
|
21
21
|
import type pg from 'pg';
|
|
22
|
-
import type { DeferredQuery } from './query.js';
|
|
22
|
+
import type { DeferredQuery } from './query/index.js';
|
|
23
23
|
export interface PipelineOptions {
|
|
24
24
|
/**
|
|
25
25
|
* Whether to wrap the pipeline in a transaction (default: true).
|