turbine-orm 0.19.2 → 0.21.0
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 +82 -18
- package/dist/adapters/cockroachdb.js +4 -9
- package/dist/cjs/adapters/cockroachdb.js +4 -9
- package/dist/cjs/cli/index.js +6 -3
- package/dist/cjs/cli/observe-ui.js +12 -2
- package/dist/cjs/cli/observe.js +6 -7
- package/dist/cjs/cli/studio.js +6 -7
- package/dist/cjs/client.js +33 -20
- package/dist/cjs/dialect.js +116 -0
- package/dist/cjs/errors.js +19 -1
- package/dist/cjs/generate.js +4 -0
- package/dist/cjs/index.js +3 -2
- package/dist/cjs/introspect.js +20 -0
- package/dist/cjs/mssql.js +1338 -0
- package/dist/cjs/mysql.js +1052 -0
- package/dist/cjs/query/builder.js +293 -73
- package/dist/cjs/sqlite.js +849 -0
- package/dist/cjs/typed-sql.js +9 -7
- package/dist/cli/index.js +6 -3
- package/dist/cli/observe-ui.d.ts +1 -1
- package/dist/cli/observe-ui.js +12 -2
- package/dist/cli/observe.js +7 -8
- package/dist/cli/studio.js +7 -8
- package/dist/client.d.ts +23 -1
- package/dist/client.js +34 -21
- package/dist/dialect.d.ts +258 -1
- package/dist/dialect.js +83 -0
- package/dist/errors.d.ts +12 -0
- package/dist/errors.js +17 -0
- package/dist/generate.js +4 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +1 -1
- package/dist/introspect.d.ts +18 -0
- package/dist/introspect.js +19 -0
- package/dist/mssql.d.ts +233 -0
- package/dist/mssql.js +1298 -0
- package/dist/mysql.d.ts +174 -0
- package/dist/mysql.js +1012 -0
- package/dist/query/builder.d.ts +97 -0
- package/dist/query/builder.js +294 -74
- package/dist/query/index.d.ts +1 -1
- package/dist/sqlite.d.ts +144 -0
- package/dist/sqlite.js +842 -0
- package/dist/typed-sql.d.ts +7 -5
- package/dist/typed-sql.js +9 -7
- package/package.json +30 -1
package/dist/cjs/dialect.js
CHANGED
|
@@ -6,6 +6,39 @@
|
|
|
6
6
|
* PostgreSQL-native by default, but query generation now depends on this
|
|
7
7
|
* contract for the SQL primitives that vary across MySQL and SQLite.
|
|
8
8
|
*/
|
|
9
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
12
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
13
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
14
|
+
}
|
|
15
|
+
Object.defineProperty(o, k2, desc);
|
|
16
|
+
}) : (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
o[k2] = m[k];
|
|
19
|
+
}));
|
|
20
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
21
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
22
|
+
}) : function(o, v) {
|
|
23
|
+
o["default"] = v;
|
|
24
|
+
});
|
|
25
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
26
|
+
var ownKeys = function(o) {
|
|
27
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
28
|
+
var ar = [];
|
|
29
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
30
|
+
return ar;
|
|
31
|
+
};
|
|
32
|
+
return ownKeys(o);
|
|
33
|
+
};
|
|
34
|
+
return function (mod) {
|
|
35
|
+
if (mod && mod.__esModule) return mod;
|
|
36
|
+
var result = {};
|
|
37
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
38
|
+
__setModuleDefault(result, mod);
|
|
39
|
+
return result;
|
|
40
|
+
};
|
|
41
|
+
})();
|
|
9
42
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
43
|
exports.postgresDialect = void 0;
|
|
11
44
|
const errors_js_1 = require("./errors.js");
|
|
@@ -13,11 +46,17 @@ const schema_js_1 = require("./schema.js");
|
|
|
13
46
|
/** PostgreSQL implementation of the dialect contract. */
|
|
14
47
|
exports.postgresDialect = {
|
|
15
48
|
name: 'postgresql',
|
|
49
|
+
resultStrategy: 'returning',
|
|
16
50
|
supportsReturning: true,
|
|
17
51
|
supportsILike: true,
|
|
18
52
|
jsonPathSupport: 'native',
|
|
19
53
|
emptyJsonArrayLiteral: "'[]'::json",
|
|
20
54
|
nullJsonLiteral: 'NULL',
|
|
55
|
+
aggSupportsInlineOrderBy: true,
|
|
56
|
+
supportsVector: true,
|
|
57
|
+
supportsListenNotify: true,
|
|
58
|
+
supportsRLS: true,
|
|
59
|
+
supportsAdvisoryLock: true,
|
|
21
60
|
paramPlaceholder(index) {
|
|
22
61
|
return `$${index}`;
|
|
23
62
|
},
|
|
@@ -35,6 +74,9 @@ exports.postgresDialect = {
|
|
|
35
74
|
const suffix = orderBy ? ` ${orderBy}` : '';
|
|
36
75
|
return `COALESCE(json_agg(${jsonObjectExpr}${suffix}), ${this.emptyJsonArrayLiteral})`;
|
|
37
76
|
},
|
|
77
|
+
wrapJsonSubresult(subquery, fallback) {
|
|
78
|
+
return `COALESCE((${subquery}), ${fallback})`;
|
|
79
|
+
},
|
|
38
80
|
buildReturningClause(selection = '*') {
|
|
39
81
|
return ` RETURNING ${selection}`;
|
|
40
82
|
},
|
|
@@ -76,6 +118,15 @@ exports.postgresDialect = {
|
|
|
76
118
|
typeToTypeScript(dialectType, nullable) {
|
|
77
119
|
return (0, schema_js_1.pgTypeToTs)(dialectType, nullable);
|
|
78
120
|
},
|
|
121
|
+
castAggregate(expr, target) {
|
|
122
|
+
return `${expr}::${target}`;
|
|
123
|
+
},
|
|
124
|
+
buildInClause(expr, paramRef, negated) {
|
|
125
|
+
return negated ? `${expr} != ALL(${paramRef})` : `${expr} = ANY(${paramRef})`;
|
|
126
|
+
},
|
|
127
|
+
inClauseParam(values) {
|
|
128
|
+
return values;
|
|
129
|
+
},
|
|
79
130
|
arrayType(baseType) {
|
|
80
131
|
return (0, schema_js_1.pgArrayType)(baseType);
|
|
81
132
|
},
|
|
@@ -131,4 +182,69 @@ exports.postgresDialect = {
|
|
|
131
182
|
buildMigrationDeleteApplied(table) {
|
|
132
183
|
return `DELETE FROM ${table} WHERE name = ${this.paramPlaceholder(1)}`;
|
|
133
184
|
},
|
|
185
|
+
beginStatement(isolationLevel) {
|
|
186
|
+
return isolationLevel ? `BEGIN ISOLATION LEVEL ${isolationLevel}` : 'BEGIN';
|
|
187
|
+
},
|
|
188
|
+
commitStatement() {
|
|
189
|
+
return 'COMMIT';
|
|
190
|
+
},
|
|
191
|
+
rollbackStatement() {
|
|
192
|
+
return 'ROLLBACK';
|
|
193
|
+
},
|
|
194
|
+
savepointStatement(name) {
|
|
195
|
+
return `SAVEPOINT ${name}`;
|
|
196
|
+
},
|
|
197
|
+
releaseSavepointStatement(name) {
|
|
198
|
+
return `RELEASE SAVEPOINT ${name}`;
|
|
199
|
+
},
|
|
200
|
+
rollbackToSavepointStatement(name) {
|
|
201
|
+
return `ROLLBACK TO SAVEPOINT ${name}`;
|
|
202
|
+
},
|
|
203
|
+
buildSetSessionConfig(name, value) {
|
|
204
|
+
// set_config(name, value, is_local=true) — the parameterizable,
|
|
205
|
+
// transaction-local equivalent of `SET LOCAL` (which rejects bind params).
|
|
206
|
+
return {
|
|
207
|
+
sql: `SELECT set_config(${this.paramPlaceholder(1)}, ${this.paramPlaceholder(2)}, true)`,
|
|
208
|
+
params: [name, value],
|
|
209
|
+
};
|
|
210
|
+
},
|
|
211
|
+
async *openStream(connection, sql, params, batchSize) {
|
|
212
|
+
// Cursors require a single connection inside a transaction. Identical SQL
|
|
213
|
+
// sequence to the historical inline implementation: BEGIN → DECLARE … NO
|
|
214
|
+
// SCROLL CURSOR FOR → FETCH n (loop) → CLOSE → COMMIT; ROLLBACK on error.
|
|
215
|
+
const cursorName = `turbine_cursor_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
216
|
+
const quotedCursor = this.quoteIdentifier(cursorName);
|
|
217
|
+
await connection.query(this.beginStatement());
|
|
218
|
+
try {
|
|
219
|
+
await connection.query(`DECLARE ${quotedCursor} NO SCROLL CURSOR FOR ${sql}`, params);
|
|
220
|
+
while (true) {
|
|
221
|
+
const batch = await connection.query(`FETCH ${batchSize} FROM ${quotedCursor}`);
|
|
222
|
+
if (batch.rows.length === 0)
|
|
223
|
+
break;
|
|
224
|
+
yield batch.rows;
|
|
225
|
+
if (batch.rows.length < batchSize)
|
|
226
|
+
break;
|
|
227
|
+
}
|
|
228
|
+
await connection.query(`CLOSE ${quotedCursor}`);
|
|
229
|
+
await connection.query(this.commitStatement());
|
|
230
|
+
}
|
|
231
|
+
catch (err) {
|
|
232
|
+
try {
|
|
233
|
+
await connection.query(this.rollbackStatement());
|
|
234
|
+
}
|
|
235
|
+
catch {
|
|
236
|
+
// Connection may already be broken — ignore rollback error.
|
|
237
|
+
}
|
|
238
|
+
throw err;
|
|
239
|
+
}
|
|
240
|
+
},
|
|
241
|
+
// Postgres introspection wraps the information_schema / pg_catalog reader in
|
|
242
|
+
// introspect.ts. A dynamic import keeps the static graph acyclic (introspect.ts
|
|
243
|
+
// imports postgresDialect) and calls the raw catalog reader (never the router).
|
|
244
|
+
introspector: {
|
|
245
|
+
async introspect(options) {
|
|
246
|
+
const { introspectPostgresCatalog } = await Promise.resolve().then(() => __importStar(require('./introspect.js')));
|
|
247
|
+
return introspectPostgresCatalog(options);
|
|
248
|
+
},
|
|
249
|
+
},
|
|
134
250
|
};
|
package/dist/cjs/errors.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* All Turbine errors extend TurbineError which includes a `code` property.
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.OptimisticLockError = exports.PipelineError = exports.ExclusionConstraintError = exports.CheckConstraintError = exports.SerializationFailureError = exports.DeadlockError = exports.NotNullViolationError = exports.ForeignKeyError = exports.UniqueConstraintError = exports.CircularRelationError = exports.MigrationError = exports.RelationError = exports.ConnectionError = exports.ValidationError = exports.TimeoutError = exports.NotFoundError = exports.TurbineError = exports.TurbineErrorCode = void 0;
|
|
9
|
+
exports.UnsupportedFeatureError = exports.OptimisticLockError = exports.PipelineError = exports.ExclusionConstraintError = exports.CheckConstraintError = exports.SerializationFailureError = exports.DeadlockError = exports.NotNullViolationError = exports.ForeignKeyError = exports.UniqueConstraintError = exports.CircularRelationError = exports.MigrationError = exports.RelationError = exports.ConnectionError = exports.ValidationError = exports.TimeoutError = exports.NotFoundError = exports.TurbineError = exports.TurbineErrorCode = void 0;
|
|
10
10
|
exports.setErrorMessageMode = setErrorMessageMode;
|
|
11
11
|
exports.getErrorMessageMode = getErrorMessageMode;
|
|
12
12
|
exports.wrapPgError = wrapPgError;
|
|
@@ -28,6 +28,7 @@ exports.TurbineErrorCode = {
|
|
|
28
28
|
PIPELINE: 'TURBINE_E014',
|
|
29
29
|
OPTIMISTIC_LOCK: 'TURBINE_E015',
|
|
30
30
|
EXCLUSION_VIOLATION: 'TURBINE_E016',
|
|
31
|
+
UNSUPPORTED_FEATURE: 'TURBINE_E017',
|
|
31
32
|
};
|
|
32
33
|
/** Base error class for all Turbine errors */
|
|
33
34
|
class TurbineError extends Error {
|
|
@@ -458,6 +459,23 @@ class OptimisticLockError extends TurbineError {
|
|
|
458
459
|
}
|
|
459
460
|
}
|
|
460
461
|
exports.OptimisticLockError = OptimisticLockError;
|
|
462
|
+
/**
|
|
463
|
+
* Thrown when a Postgres-only feature (pgvector distance ops, LISTEN/NOTIFY
|
|
464
|
+
* realtime, RLS session GUCs, advisory-lock migration locking, ...) is invoked
|
|
465
|
+
* on a dialect/engine whose capability flag reports it unsupported. Surfaces a
|
|
466
|
+
* clear `unsupported on <engine>` message instead of generating broken SQL.
|
|
467
|
+
*/
|
|
468
|
+
class UnsupportedFeatureError extends TurbineError {
|
|
469
|
+
feature;
|
|
470
|
+
dialect;
|
|
471
|
+
constructor(feature, dialect, hint) {
|
|
472
|
+
super(exports.TurbineErrorCode.UNSUPPORTED_FEATURE, `[turbine] ${feature} is unsupported on "${dialect}".${hint ? ` ${hint}` : ''}`);
|
|
473
|
+
this.name = 'UnsupportedFeatureError';
|
|
474
|
+
this.feature = feature;
|
|
475
|
+
this.dialect = dialect;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
exports.UnsupportedFeatureError = UnsupportedFeatureError;
|
|
461
479
|
/**
|
|
462
480
|
* Parse column names out of a pg `detail` string like:
|
|
463
481
|
* "Key (email)=(foo@bar) already exists."
|
package/dist/cjs/generate.js
CHANGED
|
@@ -363,6 +363,10 @@ function generateMetadata(schema) {
|
|
|
363
363
|
lines.push(' },');
|
|
364
364
|
lines.push('};');
|
|
365
365
|
lines.push('');
|
|
366
|
+
// Back-compat lowercase alias. `SCHEMA` is the canonical export, but docs and
|
|
367
|
+
// users frequently import `schema`; emit both so either name resolves.
|
|
368
|
+
lines.push('export const schema = SCHEMA;');
|
|
369
|
+
lines.push('');
|
|
366
370
|
return lines.join('\n');
|
|
367
371
|
}
|
|
368
372
|
// ---------------------------------------------------------------------------
|
package/dist/cjs/index.js
CHANGED
|
@@ -34,8 +34,8 @@
|
|
|
34
34
|
* ```
|
|
35
35
|
*/
|
|
36
36
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
-
exports.
|
|
38
|
-
exports.TypedSqlQuery = exports.buildTypedSql = exports.turbineHttp = exports.schemaToSQLString = exports.schemaToSQL = exports.schemaPush = exports.schemaDiff = exports.table = exports.defineSchema = void 0;
|
|
37
|
+
exports.ColumnBuilder = exports.applyManyToManyRelations = exports.snakeToPascal = exports.snakeToCamel = exports.singularize = exports.pgTypeToTs = exports.pgArrayType = exports.normalizeKeyColumns = exports.isDateType = exports.camelToSnake = exports.validateChannel = exports.QueryInterface = exports.pipelineSupported = exports.executePipeline = exports.hasRelationFields = exports.executeNestedUpdate = exports.executeNestedCreate = exports.introspect = exports.generate = exports.wrapPgError = exports.ValidationError = exports.UnsupportedFeatureError = exports.UniqueConstraintError = exports.TurbineErrorCode = exports.TurbineError = exports.TimeoutError = exports.setErrorMessageMode = exports.SerializationFailureError = exports.RelationError = exports.PipelineError = exports.OptimisticLockError = exports.NotNullViolationError = exports.NotFoundError = exports.MigrationError = exports.getErrorMessageMode = exports.ForeignKeyError = exports.ExclusionConstraintError = exports.DeadlockError = exports.ConnectionError = exports.CircularRelationError = exports.CheckConstraintError = exports.postgresDialect = exports.withRetry = exports.TurbineClient = exports.TransactionClient = exports.yugabytedb = exports.timescale = exports.postgresql = exports.cockroachdb = exports.alloydb = void 0;
|
|
38
|
+
exports.TypedSqlQuery = exports.buildTypedSql = exports.turbineHttp = exports.schemaToSQLString = exports.schemaToSQL = exports.schemaPush = exports.schemaDiff = exports.table = exports.defineSchema = exports.column = void 0;
|
|
39
39
|
var index_js_1 = require("./adapters/index.js");
|
|
40
40
|
Object.defineProperty(exports, "alloydb", { enumerable: true, get: function () { return index_js_1.alloydb; } });
|
|
41
41
|
Object.defineProperty(exports, "cockroachdb", { enumerable: true, get: function () { return index_js_1.cockroachdb; } });
|
|
@@ -70,6 +70,7 @@ Object.defineProperty(exports, "TimeoutError", { enumerable: true, get: function
|
|
|
70
70
|
Object.defineProperty(exports, "TurbineError", { enumerable: true, get: function () { return errors_js_1.TurbineError; } });
|
|
71
71
|
Object.defineProperty(exports, "TurbineErrorCode", { enumerable: true, get: function () { return errors_js_1.TurbineErrorCode; } });
|
|
72
72
|
Object.defineProperty(exports, "UniqueConstraintError", { enumerable: true, get: function () { return errors_js_1.UniqueConstraintError; } });
|
|
73
|
+
Object.defineProperty(exports, "UnsupportedFeatureError", { enumerable: true, get: function () { return errors_js_1.UnsupportedFeatureError; } });
|
|
73
74
|
Object.defineProperty(exports, "ValidationError", { enumerable: true, get: function () { return errors_js_1.ValidationError; } });
|
|
74
75
|
Object.defineProperty(exports, "wrapPgError", { enumerable: true, get: function () { return errors_js_1.wrapPgError; } });
|
|
75
76
|
// Code generation
|
package/dist/cjs/introspect.js
CHANGED
|
@@ -13,6 +13,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.introspect = introspect;
|
|
16
|
+
exports.introspectPostgresCatalog = introspectPostgresCatalog;
|
|
16
17
|
const pg_1 = __importDefault(require("pg"));
|
|
17
18
|
const dialect_js_1 = require("./dialect.js");
|
|
18
19
|
const schema_js_1 = require("./schema.js");
|
|
@@ -100,7 +101,26 @@ const SQL_ENUMS = `
|
|
|
100
101
|
// ---------------------------------------------------------------------------
|
|
101
102
|
// Main introspection function
|
|
102
103
|
// ---------------------------------------------------------------------------
|
|
104
|
+
/**
|
|
105
|
+
* Introspect a database into {@link SchemaMetadata}, routing through the active
|
|
106
|
+
* dialect's {@link Dialect.introspector} so each engine can override the catalog
|
|
107
|
+
* SQL. PostgreSQL is driven by {@link introspectPostgresCatalog}.
|
|
108
|
+
*/
|
|
103
109
|
async function introspect(options) {
|
|
110
|
+
const dialect = options.dialect ?? dialect_js_1.postgresDialect;
|
|
111
|
+
const introspector = dialect.introspector;
|
|
112
|
+
if (introspector) {
|
|
113
|
+
return introspector.introspect(options);
|
|
114
|
+
}
|
|
115
|
+
// Dialects without an introspector fall back to the Postgres catalog reader.
|
|
116
|
+
return introspectPostgresCatalog(options);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* PostgreSQL catalog introspector: reads information_schema + pg_catalog and
|
|
120
|
+
* produces {@link SchemaMetadata}. This is the implementation wrapped by
|
|
121
|
+
* `postgresDialect.introspector`; call {@link introspect} for dialect routing.
|
|
122
|
+
*/
|
|
123
|
+
async function introspectPostgresCatalog(options) {
|
|
104
124
|
const schema = options.schema ?? 'public';
|
|
105
125
|
const dialect = dialect_js_1.postgresDialect;
|
|
106
126
|
const pool = new pg_1.default.Pool({
|