ts-prorm-orm 1.2.3 → 2.1.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/CHANGELOG.md +331 -1
- package/README.md +32 -24
- package/dist/compliance/data-classifier.d.ts +6 -0
- package/dist/compliance/data-classifier.js +6 -0
- package/dist/compliance/data-lineage.d.ts +4 -0
- package/dist/compliance/data-lineage.js +4 -0
- package/dist/compliance/data-masker.d.ts +4 -0
- package/dist/compliance/data-masker.js +4 -0
- package/dist/compliance/index.d.ts +4 -0
- package/dist/compliance/index.js +15 -1
- package/dist/compliance/pseudonymization.d.ts +4 -0
- package/dist/compliance/pseudonymization.js +4 -0
- package/dist/compliance/query-firewall.d.ts +9 -9
- package/dist/compliance/query-firewall.js +9 -9
- package/dist/compliance/rate-limiter.d.ts +4 -0
- package/dist/compliance/rate-limiter.js +4 -0
- package/dist/compliance/row-level-security.d.ts +2 -0
- package/dist/compliance/row-level-security.js +2 -0
- package/dist/compliance/security-decorator.d.ts +8 -0
- package/dist/compliance/security-decorator.js +8 -0
- package/dist/compliance/session-isolation.d.ts +4 -0
- package/dist/compliance/session-isolation.js +4 -0
- package/dist/compliance/worm-storage.d.ts +4 -0
- package/dist/compliance/worm-storage.js +4 -0
- package/dist/connection-manager.js +13 -1
- package/dist/core/expressions.d.ts +58 -0
- package/dist/core/expressions.js +83 -0
- package/dist/core/hooks-manager.d.ts +179 -0
- package/dist/core/hooks-manager.js +291 -0
- package/dist/core/types.d.ts +235 -0
- package/dist/core/types.js +9 -0
- package/dist/decorators/audit.d.ts +3 -1
- package/dist/decorators/audit.js +3 -1
- package/dist/decorators/check.d.ts +15 -15
- package/dist/decorators/check.js +15 -15
- package/dist/decorators/collate.d.ts +16 -0
- package/dist/decorators/collate.js +16 -0
- package/dist/decorators/comment.d.ts +3 -1
- package/dist/decorators/comment.js +3 -1
- package/dist/decorators/database-settings.d.ts +6 -0
- package/dist/decorators/database-settings.js +6 -0
- package/dist/decorators/default.d.ts +2 -0
- package/dist/decorators/default.js +2 -0
- package/dist/decorators/encryption.d.ts +7 -1
- package/dist/decorators/encryption.js +7 -1
- package/dist/decorators/engine.d.ts +4 -0
- package/dist/decorators/engine.js +4 -0
- package/dist/decorators/fk-constraints.d.ts +32 -32
- package/dist/decorators/fk-constraints.js +32 -32
- package/dist/decorators/foreign-table.d.ts +1 -1
- package/dist/decorators/generated.d.ts +8 -0
- package/dist/decorators/generated.js +8 -0
- package/dist/decorators/hstore.d.ts +6 -0
- package/dist/decorators/hstore.js +6 -0
- package/dist/decorators/index.d.ts +2 -0
- package/dist/decorators/index.js +11 -1
- package/dist/decorators/json-column.d.ts +2 -0
- package/dist/decorators/json-column.js +2 -0
- package/dist/decorators/jsonb.d.ts +6 -0
- package/dist/decorators/jsonb.js +6 -0
- package/dist/decorators/permissions.d.ts +12 -0
- package/dist/decorators/permissions.js +12 -0
- package/dist/decorators/procedure.d.ts +4 -2
- package/dist/decorators/procedure.js +4 -2
- package/dist/decorators/query-options.d.ts +24 -0
- package/dist/decorators/query-options.js +24 -0
- package/dist/decorators/range.d.ts +8 -0
- package/dist/decorators/range.js +8 -0
- package/dist/decorators/set-column.d.ts +2 -0
- package/dist/decorators/set-column.js +2 -0
- package/dist/decorators/spatial.d.ts +2 -0
- package/dist/decorators/spatial.js +2 -0
- package/dist/decorators/storage.d.ts +24 -0
- package/dist/decorators/storage.js +24 -0
- package/dist/decorators/timezone.d.ts +7 -7
- package/dist/decorators/timezone.js +7 -7
- package/dist/decorators/trigger.d.ts +3 -1
- package/dist/decorators/trigger.js +3 -1
- package/dist/decorators/uuid.d.ts +6 -0
- package/dist/decorators/uuid.js +6 -0
- package/dist/decorators/view.d.ts +7 -1
- package/dist/decorators/view.js +7 -1
- package/dist/diagrams/chen-diagram.d.ts +15 -12
- package/dist/diagrams/chen-diagram.js +76 -85
- package/dist/diagrams/class-diagram.d.ts +9 -8
- package/dist/diagrams/class-diagram.js +60 -82
- package/dist/diagrams/core/index.d.ts +13 -0
- package/dist/diagrams/core/index.js +33 -0
- package/dist/diagrams/core/layout.d.ts +104 -0
- package/dist/diagrams/core/layout.js +223 -0
- package/dist/diagrams/{svg-dom.d.ts → core/svg.d.ts} +8 -20
- package/dist/diagrams/{svg-dom.js → core/svg.js} +21 -29
- package/dist/diagrams/core/theme.d.ts +84 -0
- package/dist/diagrams/core/theme.js +62 -0
- package/dist/diagrams/dependency-diagram.d.ts +15 -14
- package/dist/diagrams/dependency-diagram.js +71 -105
- package/dist/diagrams/er-diagram.d.ts +13 -26
- package/dist/diagrams/er-diagram.js +180 -259
- package/dist/diagrams/flow-diagram.d.ts +16 -11
- package/dist/diagrams/flow-diagram.js +96 -91
- package/dist/diagrams/gantt-diagram.d.ts +10 -5
- package/dist/diagrams/gantt-diagram.js +77 -103
- package/dist/diagrams/index-diagram.d.ts +10 -10
- package/dist/diagrams/index-diagram.js +106 -116
- package/dist/diagrams/index.d.ts +6 -9
- package/dist/diagrams/index.js +9 -24
- package/dist/diagrams/migration-diagram.d.ts +8 -4
- package/dist/diagrams/migration-diagram.js +189 -161
- package/dist/diagrams/model-diagram.d.ts +34 -34
- package/dist/diagrams/model-diagram.js +106 -485
- package/dist/diagrams/package-diagram.d.ts +9 -6
- package/dist/diagrams/package-diagram.js +64 -101
- package/dist/diagrams/relational-diagram.d.ts +12 -10
- package/dist/diagrams/relational-diagram.js +87 -114
- package/dist/diagrams/schemadoc-diagram.d.ts +8 -8
- package/dist/diagrams/schemadoc-diagram.js +71 -93
- package/dist/diagrams/sequence-diagram.d.ts +10 -10
- package/dist/diagrams/sequence-diagram.js +64 -89
- package/dist/diagrams/state-diagram.d.ts +10 -9
- package/dist/diagrams/state-diagram.js +69 -92
- package/dist/diagrams/tree-diagram.d.ts +11 -5
- package/dist/diagrams/tree-diagram.js +41 -65
- package/dist/dialects/clickhouse/index.js +15 -0
- package/dist/dialects/cockroachdb/index.d.ts +1 -1
- package/dist/dialects/cockroachdb/index.js +32 -63
- package/dist/dialects/db2/index.js +23 -8
- package/dist/dialects/dialect.d.ts +141 -5
- package/dist/dialects/duckdb/index.js +9 -2
- package/dist/dialects/hana/index.js +22 -5
- package/dist/dialects/lock-clause-helper.d.ts +167 -0
- package/dist/dialects/lock-clause-helper.js +316 -0
- package/dist/dialects/mariadb/index.d.ts +7 -4
- package/dist/dialects/mariadb/index.js +36 -60
- package/dist/dialects/mssql/index.js +34 -3
- package/dist/dialects/mysql/index.d.ts +1 -1
- package/dist/dialects/mysql/index.js +17 -45
- package/dist/dialects/oracle/index.d.ts +14 -3
- package/dist/dialects/oracle/index.js +66 -36
- package/dist/dialects/order-expression-helper.d.ts +72 -0
- package/dist/dialects/order-expression-helper.js +154 -0
- package/dist/dialects/partial-index.d.ts +52 -0
- package/dist/dialects/partial-index.js +251 -0
- package/dist/dialects/postgres/index.d.ts +1 -1
- package/dist/dialects/postgres/index.js +43 -68
- package/dist/dialects/redshift/index.js +9 -2
- package/dist/dialects/snowflake/index.js +17 -0
- package/dist/dialects/spanner/index.js +7 -2
- package/dist/dialects/sqlite/driver.d.ts +55 -0
- package/dist/dialects/sqlite/driver.js +102 -0
- package/dist/dialects/sqlite/index.d.ts +1 -1
- package/dist/dialects/sqlite/index.js +49 -27
- package/dist/external-fields/decorator.d.ts +2 -0
- package/dist/external-fields/decorator.js +2 -0
- package/dist/graph/base-graph-dialect.d.ts +24 -3
- package/dist/graph/base-graph-dialect.js +43 -2
- package/dist/graph/dgraph/index.js +6 -0
- package/dist/graph/gremlin/index.d.ts +6 -0
- package/dist/graph/gremlin/index.js +12 -1
- package/dist/graph/index.d.ts +1 -1
- package/dist/graph/neo4j/index.d.ts +2 -0
- package/dist/graph/neo4j/index.js +6 -1
- package/dist/graph/types.d.ts +12 -1
- package/dist/index.d.ts +12 -3
- package/dist/index.js +53 -7
- package/dist/logging/index.d.ts +10 -0
- package/dist/logging/index.js +23 -0
- package/dist/logging/query-logging.d.ts +82 -0
- package/dist/logging/query-logging.js +102 -0
- package/dist/models/associations.d.ts +38 -0
- package/dist/models/associations.js +16 -0
- package/dist/models/decorators.d.ts +55 -19
- package/dist/models/decorators.js +95 -19
- package/dist/models/eager-load.d.ts +99 -0
- package/dist/models/eager-load.js +348 -5
- package/dist/models/indexes.d.ts +3 -2
- package/dist/models/indexes.js +7 -1
- package/dist/models/model.js +69 -43
- package/dist/prorm.d.ts +175 -409
- package/dist/prorm.js +1132 -553
- package/dist/query-builders/order-limit-builder.js +12 -10
- package/dist/query-builders/sql-compiler.d.ts +10 -3
- package/dist/query-builders/sql-compiler.js +14 -43
- package/dist/query-interface.d.ts +2 -1
- package/dist/schema-objects.d.ts +42 -0
- package/dist/schema-objects.js +28 -0
- package/dist/sql-constants.d.ts +44 -0
- package/dist/sql-constants.js +138 -1
- package/dist/types/index.d.ts +387 -17
- package/dist/types/index.js +10 -15
- package/dist/types/query-types.d.ts +26 -0
- package/dist/types/query-types.js +30 -0
- package/package.json +39 -8
- package/dist/decorators/belongs-to-many.js +0 -115
- package/dist/decorators/belongs-to.js +0 -115
- package/dist/decorators/has-many.js +0 -127
- package/dist/decorators/has-one.js +0 -116
- package/dist/diagrams/palette.d.ts +0 -138
- package/dist/diagrams/palette.js +0 -194
- package/dist/hooks/hooks-manager.d.ts +0 -189
- package/dist/hooks/hooks-manager.js +0 -350
- package/dist/hooks/index.d.ts +0 -8
- package/dist/hooks/index.js +0 -37
- /package/dist/{logging.d.ts → logging/logger.d.ts} +0 -0
- /package/dist/{logging.js → logging/logger.js} +0 -0
|
@@ -40,6 +40,7 @@
|
|
|
40
40
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
41
|
exports.ClickHouseDialect = void 0;
|
|
42
42
|
exports.createClickHouseDialect = createClickHouseDialect;
|
|
43
|
+
const partial_index_1 = require("../partial-index");
|
|
43
44
|
// Lazily-loaded `@clickhouse/client` module. The native/runtime driver is only
|
|
44
45
|
// required the first time a connection is opened, so merely importing this ORM
|
|
45
46
|
// never pulls in the ClickHouse driver.
|
|
@@ -59,6 +60,7 @@ function loadClickHouse() {
|
|
|
59
60
|
}
|
|
60
61
|
const query_stream_helper_1 = require("../query-stream-helper");
|
|
61
62
|
const prorm_1 = require("../../prorm");
|
|
63
|
+
const order_expression_helper_1 = require("../order-expression-helper");
|
|
62
64
|
/**
|
|
63
65
|
* ClickHouse dialect class that implements the Dialect interface.
|
|
64
66
|
*
|
|
@@ -950,6 +952,12 @@ class ClickHouseDialect {
|
|
|
950
952
|
if (options?.ifNotExists)
|
|
951
953
|
sql += ' IF NOT EXISTS';
|
|
952
954
|
sql += ` ${this.escapeId(indexName)} ${expr} TYPE ${type} GRANULARITY ${granularity}`;
|
|
955
|
+
// ClickHouse indexes are data-skipping indexes on the whole part set; there
|
|
956
|
+
// is no predicate to restrict them. `where` was accepted and dropped on the
|
|
957
|
+
// floor here, so the caller silently got an unfiltered index.
|
|
958
|
+
if (options?.where) {
|
|
959
|
+
throw (0, partial_index_1.unsupportedPartialIndex)(this.name);
|
|
960
|
+
}
|
|
953
961
|
await this.query(sql);
|
|
954
962
|
}
|
|
955
963
|
async removeIndex(tableName, indexName) {
|
|
@@ -959,6 +967,7 @@ class ClickHouseDialect {
|
|
|
959
967
|
await this.addIndex(tableName, indexDef.name, indexDef.fields, {
|
|
960
968
|
type: indexDef.type,
|
|
961
969
|
using: indexDef.using,
|
|
970
|
+
where: indexDef.where,
|
|
962
971
|
});
|
|
963
972
|
}
|
|
964
973
|
async dropIndex(tableName, indexName, options) {
|
|
@@ -1359,6 +1368,12 @@ class ClickHouseDialect {
|
|
|
1359
1368
|
return '';
|
|
1360
1369
|
const parts = [];
|
|
1361
1370
|
const processItem = (item) => {
|
|
1371
|
+
// Order helpers: asc('name') / desc('name') / random()
|
|
1372
|
+
const orderExpr = (0, order_expression_helper_1.renderOrderExpressionItem)(this, item);
|
|
1373
|
+
if (orderExpr !== null) {
|
|
1374
|
+
parts.push(orderExpr);
|
|
1375
|
+
return;
|
|
1376
|
+
}
|
|
1362
1377
|
if (typeof item === 'string') {
|
|
1363
1378
|
const [field, dir] = item.split(' ');
|
|
1364
1379
|
parts.push(dir ? `${this.escapeId(field)} ${dir.toUpperCase()}` : this.escapeId(field));
|
|
@@ -1013,7 +1013,7 @@ export declare class CockroachDBDialect implements Dialect {
|
|
|
1013
1013
|
type?: string;
|
|
1014
1014
|
using?: string;
|
|
1015
1015
|
fields: string[];
|
|
1016
|
-
where?: WhereOptions;
|
|
1016
|
+
where?: WhereOptions | string;
|
|
1017
1017
|
expression?: string;
|
|
1018
1018
|
include?: string[];
|
|
1019
1019
|
concurrently?: boolean;
|
|
@@ -36,7 +36,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
36
36
|
exports.CockroachDBTransaction = exports.CockroachDBDialect = void 0;
|
|
37
37
|
exports.createCockroachDBDialect = createCockroachDBDialect;
|
|
38
38
|
const operators_1 = require("../../operators");
|
|
39
|
+
const lock_clause_helper_1 = require("../lock-clause-helper");
|
|
40
|
+
const partial_index_1 = require("../partial-index");
|
|
39
41
|
const prorm_1 = require("../../prorm");
|
|
42
|
+
const order_expression_helper_1 = require("../order-expression-helper");
|
|
40
43
|
// Lazily-loaded `pg` driver. Required only when a connection is opened, so
|
|
41
44
|
// importing this ORM never loads the pg driver.
|
|
42
45
|
let pgModule = null;
|
|
@@ -2327,9 +2330,14 @@ class CockroachDBDialect {
|
|
|
2327
2330
|
if (options?.include && options.include.length > 0) {
|
|
2328
2331
|
sql += ` INCLUDE (${options.include.map((f) => this.escapeId(f)).join(', ')})`;
|
|
2329
2332
|
}
|
|
2333
|
+
// Partial index predicate. The ordinary WHERE builder emits `$1`-style
|
|
2334
|
+
// placeholders and this DDL is executed without a value list, so the
|
|
2335
|
+
// predicate is compiled with its values inlined as escaped literals.
|
|
2330
2336
|
if (options?.where) {
|
|
2331
|
-
const
|
|
2332
|
-
|
|
2337
|
+
const predicate = (0, partial_index_1.buildPartialIndexPredicate)(options.where, this.name, this);
|
|
2338
|
+
if (predicate) {
|
|
2339
|
+
sql += ` WHERE ${predicate}`;
|
|
2340
|
+
}
|
|
2333
2341
|
}
|
|
2334
2342
|
await this.query(sql);
|
|
2335
2343
|
}
|
|
@@ -2385,9 +2393,12 @@ class CockroachDBDialect {
|
|
|
2385
2393
|
if (indexDef.include && indexDef.include.length > 0) {
|
|
2386
2394
|
sql += ` INCLUDE (${indexDef.include.map((f) => this.escapeId(f)).join(', ')})`;
|
|
2387
2395
|
}
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2396
|
+
// Partial index predicate - inlined literals, not placeholders. See addIndex.
|
|
2397
|
+
if (indexDef.where) {
|
|
2398
|
+
const predicate = (0, partial_index_1.buildPartialIndexPredicate)(indexDef.where, this.name, this);
|
|
2399
|
+
if (predicate) {
|
|
2400
|
+
sql += ` WHERE ${predicate}`;
|
|
2401
|
+
}
|
|
2391
2402
|
}
|
|
2392
2403
|
await this.query(sql);
|
|
2393
2404
|
}
|
|
@@ -3252,12 +3263,18 @@ class CockroachDBDialect {
|
|
|
3252
3263
|
* Build an ORDER BY clause
|
|
3253
3264
|
*/
|
|
3254
3265
|
buildOrderClause(order, options) {
|
|
3255
|
-
const orderArray = order;
|
|
3256
|
-
if (
|
|
3266
|
+
const orderArray = (0, order_expression_helper_1.normalizeOrderItems)(order);
|
|
3267
|
+
if (orderArray.length === 0) {
|
|
3257
3268
|
return '';
|
|
3258
3269
|
}
|
|
3259
3270
|
const orderParts = [];
|
|
3260
3271
|
for (const item of orderArray) {
|
|
3272
|
+
// Order helpers: asc('name') / desc('name') / random()
|
|
3273
|
+
const orderExpr = (0, order_expression_helper_1.renderOrderExpressionItem)(this, item);
|
|
3274
|
+
if (orderExpr !== null) {
|
|
3275
|
+
orderParts.push(orderExpr);
|
|
3276
|
+
continue;
|
|
3277
|
+
}
|
|
3261
3278
|
if (Array.isArray(item)) {
|
|
3262
3279
|
const field = typeof item[0] === 'string' ? this.escapeId(item[0]) : item[0];
|
|
3263
3280
|
const direction = item[1] ? ` ${item[1]}` : '';
|
|
@@ -3977,35 +3994,10 @@ class CockroachDBDialect {
|
|
|
3977
3994
|
}
|
|
3978
3995
|
// Build LIMIT/OFFSET clause
|
|
3979
3996
|
sql += this.buildLimitOffset(options.limit, options.offset);
|
|
3980
|
-
// Handle row-level locking
|
|
3981
|
-
|
|
3982
|
-
|
|
3983
|
-
|
|
3984
|
-
if (options.lock === true) {
|
|
3985
|
-
lockType = 'UPDATE';
|
|
3986
|
-
}
|
|
3987
|
-
else if (typeof options.lock === 'string') {
|
|
3988
|
-
lockType = options.lock;
|
|
3989
|
-
}
|
|
3990
|
-
else if (typeof options.lock === 'object' && options.lock.of) {
|
|
3991
|
-
// lock: { of: Model } - defaults to FOR UPDATE for table-specific locking
|
|
3992
|
-
lockType = 'UPDATE';
|
|
3993
|
-
}
|
|
3994
|
-
if (lockType === 'UPDATE') {
|
|
3995
|
-
sql += ' FOR UPDATE';
|
|
3996
|
-
}
|
|
3997
|
-
else if (lockType === 'SHARE') {
|
|
3998
|
-
sql += ' FOR SHARE';
|
|
3999
|
-
}
|
|
4000
|
-
else if (lockType === 'KEY SHARE') {
|
|
4001
|
-
sql += ' FOR KEY SHARE';
|
|
4002
|
-
}
|
|
4003
|
-
// Handle lock on specific table (CockroachDB supports OF clause)
|
|
4004
|
-
if (typeof options.lock === 'object' && options.lock.of) {
|
|
4005
|
-
const model = options.lock.of;
|
|
4006
|
-
sql += ` OF ${this.escapeId(model.tableName || '')}`;
|
|
4007
|
-
}
|
|
4008
|
-
}
|
|
3997
|
+
// Handle row-level locking. CockroachDB implements the PostgreSQL locking
|
|
3998
|
+
// grammar; the shared helper compiles every documented `lock` shape so the
|
|
3999
|
+
// object forms can't silently produce an unlocked SELECT.
|
|
4000
|
+
sql += (0, lock_clause_helper_1.appendLockClause)(options.lock, lock_clause_helper_1.COCKROACHDB_LOCK_SPEC, (id) => this.escapeId(id));
|
|
4009
4001
|
// Build UNION clause if provided
|
|
4010
4002
|
if (options.union && options.union.length > 0) {
|
|
4011
4003
|
const unionType = options.unionType || 'UNION';
|
|
@@ -4156,33 +4148,10 @@ class CockroachDBDialect {
|
|
|
4156
4148
|
* Get CockroachDB specific lock options
|
|
4157
4149
|
*/
|
|
4158
4150
|
getLockOptions(lock) {
|
|
4159
|
-
|
|
4160
|
-
|
|
4161
|
-
|
|
4162
|
-
|
|
4163
|
-
case 'UPDATE':
|
|
4164
|
-
sql = 'FOR UPDATE';
|
|
4165
|
-
break;
|
|
4166
|
-
case 'SHARE':
|
|
4167
|
-
sql = 'FOR SHARE';
|
|
4168
|
-
break;
|
|
4169
|
-
case 'KEY SHARE':
|
|
4170
|
-
sql = 'FOR KEY SHARE';
|
|
4171
|
-
break;
|
|
4172
|
-
default:
|
|
4173
|
-
return { sql: '', params };
|
|
4174
|
-
}
|
|
4175
|
-
if (typeof lock === 'object' && lock?.of) {
|
|
4176
|
-
const model = lock.of;
|
|
4177
|
-
sql += ` OF ${this.escapeId(model.tableName || '')}`;
|
|
4178
|
-
}
|
|
4179
|
-
if (typeof lock === 'object' && lock?.nowait) {
|
|
4180
|
-
sql += ' NOWAIT';
|
|
4181
|
-
}
|
|
4182
|
-
else if (typeof lock === 'object' && lock?.skipLocked) {
|
|
4183
|
-
sql += ' SKIP LOCKED';
|
|
4184
|
-
}
|
|
4185
|
-
return { sql, params };
|
|
4151
|
+
return {
|
|
4152
|
+
sql: (0, lock_clause_helper_1.buildLockClause)(lock, lock_clause_helper_1.COCKROACHDB_LOCK_SPEC, (id) => this.escapeId(id)),
|
|
4153
|
+
params: [],
|
|
4154
|
+
};
|
|
4186
4155
|
}
|
|
4187
4156
|
// ---------------------------------------------------------------------------
|
|
4188
4157
|
// User / Privilege management — CockroachDB dialect
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
*/
|
|
15
15
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
16
|
exports.DB2Dialect = void 0;
|
|
17
|
+
const partial_index_1 = require("../partial-index");
|
|
17
18
|
// Lazily-loaded `ibm_db` driver. This native (ODBC-based) addon is only loaded
|
|
18
19
|
// the first time a connection is opened, so importing this ORM never dlopens
|
|
19
20
|
// the ibm_db native binding.
|
|
@@ -32,7 +33,9 @@ function loadIbmDb() {
|
|
|
32
33
|
return ibmDbModule;
|
|
33
34
|
}
|
|
34
35
|
const query_stream_helper_1 = require("../query-stream-helper");
|
|
36
|
+
const lock_clause_helper_1 = require("../lock-clause-helper");
|
|
35
37
|
const prorm_1 = require("../../prorm");
|
|
38
|
+
const order_expression_helper_1 = require("../order-expression-helper");
|
|
36
39
|
/**
|
|
37
40
|
* Db2-specific transaction class.
|
|
38
41
|
* Db2 transactions (via ibm_db) are tied to a specific connection - the
|
|
@@ -1031,6 +1034,13 @@ class DB2Dialect {
|
|
|
1031
1034
|
if (options?.include && options.include.length > 0) {
|
|
1032
1035
|
sql += ` INCLUDE (${options.include.map((f) => this.escapeId(f)).join(', ')})`;
|
|
1033
1036
|
}
|
|
1037
|
+
// Db2 has no partial/filtered index predicate (only `EXCLUDE NULL KEYS` on
|
|
1038
|
+
// a unique index, which is not a general WHERE). `where` used to be
|
|
1039
|
+
// accepted by createIndex and then silently dropped here, so the caller got
|
|
1040
|
+
// a full index without being told; say so instead.
|
|
1041
|
+
if (options?.where) {
|
|
1042
|
+
throw (0, partial_index_1.unsupportedPartialIndex)(this.name);
|
|
1043
|
+
}
|
|
1034
1044
|
return sql;
|
|
1035
1045
|
}
|
|
1036
1046
|
async addIndex(tableName, indexName, fields, options) {
|
|
@@ -1671,12 +1681,18 @@ class DB2Dialect {
|
|
|
1671
1681
|
return { sql, values };
|
|
1672
1682
|
}
|
|
1673
1683
|
buildOrderClause(order, _options) {
|
|
1674
|
-
const orderArray = order;
|
|
1675
|
-
if (
|
|
1684
|
+
const orderArray = (0, order_expression_helper_1.normalizeOrderItems)(order);
|
|
1685
|
+
if (orderArray.length === 0) {
|
|
1676
1686
|
return '';
|
|
1677
1687
|
}
|
|
1678
1688
|
const orderParts = [];
|
|
1679
1689
|
for (const item of orderArray) {
|
|
1690
|
+
// Order helpers: asc('name') / desc('name') / random()
|
|
1691
|
+
const orderExpr = (0, order_expression_helper_1.renderOrderExpressionItem)(this, item);
|
|
1692
|
+
if (orderExpr !== null) {
|
|
1693
|
+
orderParts.push(orderExpr);
|
|
1694
|
+
continue;
|
|
1695
|
+
}
|
|
1680
1696
|
if (Array.isArray(item)) {
|
|
1681
1697
|
const field = typeof item[0] === 'string' ? this.escapeId(item[0]) : item[0];
|
|
1682
1698
|
const direction = item[1] ? ` ${item[1]}` : '';
|
|
@@ -1902,12 +1918,11 @@ class DB2Dialect {
|
|
|
1902
1918
|
if (options.limit !== undefined || options.offset !== undefined) {
|
|
1903
1919
|
sql += this.buildLimitOffset(options.limit, options.offset);
|
|
1904
1920
|
}
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
}
|
|
1921
|
+
// Row-level locking: `FOR UPDATE`, with the read-stability isolation clause
|
|
1922
|
+
// for a shared lock. Db2 has no `NOWAIT` and spells lock-avoidance as
|
|
1923
|
+
// `SKIP LOCKED DATA` inside an isolation clause, so both modifiers throw
|
|
1924
|
+
// rather than being silently dropped.
|
|
1925
|
+
sql += (0, lock_clause_helper_1.appendLockClause)(options.lock, lock_clause_helper_1.DB2_LOCK_SPEC);
|
|
1911
1926
|
return { sql, values };
|
|
1912
1927
|
}
|
|
1913
1928
|
/**
|
|
@@ -4,6 +4,16 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { Transaction, TransactionOptions, QueryResult, QueryOptions, DataType, WhereOptions, Order, IncludeOptions, PartitionBound, CreatePartitionOptions, AttachPartitionOptions, DetachPartitionOptions, RefreshOptions, MaterializedViewOptions, DropMaterializedViewOptions, StoredProcedureOptions, DropStoredProcedureOptions, ExecuteStoredProcedureOptions, TriggerOptions, DropTriggerOptions, SequenceOptions, DropSequenceOptions, PolicyOptions, DropPolicyOptions, StreamOptions } from '../types';
|
|
6
6
|
import type { Readable } from 'stream';
|
|
7
|
+
/**
|
|
8
|
+
* The contract every SQL engine implements.
|
|
9
|
+
*
|
|
10
|
+
* A dialect owns everything engine-specific: identifier quoting, value escaping,
|
|
11
|
+
* how DDL is written, which clauses are legal, and how pagination and locking
|
|
12
|
+
* are spelled. Model code builds the same `FindOptions` regardless, and
|
|
13
|
+
* the dialect is the single place that turns it into SQL for one engine —
|
|
14
|
+
* which is why `LIMIT ... OFFSET` on PostgreSQL becomes `OFFSET ... FETCH
|
|
15
|
+
* NEXT` on MSSQL without the caller changing.
|
|
16
|
+
*/
|
|
7
17
|
export interface Dialect {
|
|
8
18
|
/**
|
|
9
19
|
* The name of the dialect
|
|
@@ -582,6 +592,10 @@ export interface Dialect {
|
|
|
582
592
|
executeStoredProcedure(options: ExecuteStoredProcedureOptions): Promise<QueryResult>;
|
|
583
593
|
hasStoredProcedure(procedureName: string, schema?: string): Promise<boolean>;
|
|
584
594
|
}
|
|
595
|
+
/**
|
|
596
|
+
* One column in a `CREATE TABLE` or `ALTER TABLE`: its type, nullability,
|
|
597
|
+
* default, and key or reference membership.
|
|
598
|
+
*/
|
|
585
599
|
export interface ColumnDefinition {
|
|
586
600
|
type: DataType;
|
|
587
601
|
allowNull?: boolean;
|
|
@@ -616,6 +630,10 @@ export interface ColumnDefinition {
|
|
|
616
630
|
*/
|
|
617
631
|
invisible?: boolean;
|
|
618
632
|
}
|
|
633
|
+
/**
|
|
634
|
+
* Table-level options for `CREATE TABLE` — the engine, charset, comment,
|
|
635
|
+
* partitioning and any indexes or constraints declared inline.
|
|
636
|
+
*/
|
|
619
637
|
export interface TableOptions {
|
|
620
638
|
ifNotExists?: boolean;
|
|
621
639
|
engine?: string;
|
|
@@ -627,8 +645,18 @@ export interface TableOptions {
|
|
|
627
645
|
rowFormat?: string;
|
|
628
646
|
indexes?: TableIndex[];
|
|
629
647
|
constraints?: TableConstraint[];
|
|
630
|
-
/**
|
|
631
|
-
|
|
648
|
+
/**
|
|
649
|
+
* Unique keys to create with the table.
|
|
650
|
+
*
|
|
651
|
+
* Both shapes are accepted because both have always been passed: the legacy
|
|
652
|
+
* `{ name: fields[] }` map, and the `UniqueKeyOptions`-style array that
|
|
653
|
+
* `ModelOptions.uniqueKeys` is declared as. The dialects already branch on
|
|
654
|
+
* `Array.isArray`; the type now says so.
|
|
655
|
+
*/
|
|
656
|
+
uniqueKeys?: Record<string, string[]> | Array<{
|
|
657
|
+
name?: string;
|
|
658
|
+
fields: string[];
|
|
659
|
+
}>;
|
|
632
660
|
/** PostgreSQL tablespace */
|
|
633
661
|
tablespace?: string;
|
|
634
662
|
/** PostgreSQL: inherit from parent table */
|
|
@@ -657,18 +685,26 @@ export interface TableOptions {
|
|
|
657
685
|
validToColumn?: string;
|
|
658
686
|
};
|
|
659
687
|
}
|
|
688
|
+
/**
|
|
689
|
+
* An index declared alongside the table rather than in a separate statement.
|
|
690
|
+
*/
|
|
660
691
|
export interface TableIndex {
|
|
661
692
|
name?: string;
|
|
662
693
|
unique?: boolean;
|
|
663
694
|
type?: string;
|
|
664
695
|
using?: string;
|
|
665
696
|
fields: string[];
|
|
666
|
-
where
|
|
697
|
+
/** See {@link IndexOptions.where}. */
|
|
698
|
+
where?: WhereOptions | string;
|
|
667
699
|
/** Expression for expression-based indexes (e.g., LOWER(column)) */
|
|
668
700
|
expression?: string;
|
|
669
701
|
/** Include columns for covering index (PostgreSQL 11+, MySQL 8.0.17+) */
|
|
670
702
|
include?: string[];
|
|
671
703
|
}
|
|
704
|
+
/**
|
|
705
|
+
* A constraint declared alongside the table: primary key, unique, check,
|
|
706
|
+
* foreign key or exclusion.
|
|
707
|
+
*/
|
|
672
708
|
export interface TableConstraint {
|
|
673
709
|
name?: string;
|
|
674
710
|
type: 'PRIMARY KEY' | 'UNIQUE' | 'FOREIGN KEY' | 'CHECK';
|
|
@@ -681,10 +717,18 @@ export interface TableConstraint {
|
|
|
681
717
|
};
|
|
682
718
|
check?: string;
|
|
683
719
|
}
|
|
720
|
+
/**
|
|
721
|
+
* Options for `DROP TABLE`, including `ifExists` and whether to cascade to
|
|
722
|
+
* dependent objects.
|
|
723
|
+
*/
|
|
684
724
|
export interface DropTableOptions {
|
|
685
725
|
ifExists?: boolean;
|
|
686
726
|
cascade?: boolean;
|
|
687
727
|
}
|
|
728
|
+
/**
|
|
729
|
+
* What the engine reports back about an existing table — the shape returned
|
|
730
|
+
* by `describeTable`, used by schema diffing.
|
|
731
|
+
*/
|
|
688
732
|
export interface TableDescription {
|
|
689
733
|
[columnName: string]: {
|
|
690
734
|
type: string;
|
|
@@ -694,13 +738,30 @@ export interface TableDescription {
|
|
|
694
738
|
autoIncrement: boolean;
|
|
695
739
|
};
|
|
696
740
|
}
|
|
741
|
+
/**
|
|
742
|
+
* Options for `CREATE INDEX`: uniqueness, method, included columns, and the
|
|
743
|
+
* `where` predicate that makes it partial. Not every engine supports partial
|
|
744
|
+
* indexes; the dialect rejects the option rather than silently dropping it.
|
|
745
|
+
*/
|
|
697
746
|
export interface IndexOptions {
|
|
698
747
|
/** Explicit index name (used by the `(tableName, fields, options)` addIndex shorthand) */
|
|
699
748
|
name?: string;
|
|
700
749
|
unique?: boolean;
|
|
701
750
|
type?: string;
|
|
702
751
|
using?: string;
|
|
703
|
-
|
|
752
|
+
/**
|
|
753
|
+
* Partial (filtered) index predicate.
|
|
754
|
+
*
|
|
755
|
+
* Compiled into the `CREATE INDEX ... WHERE ...` clause with every value
|
|
756
|
+
* inlined as an escaped literal, because DDL is executed without a parameter
|
|
757
|
+
* list - see `src/dialects/partial-index.ts`. A string is taken as a
|
|
758
|
+
* predicate the caller already wrote and passed through unchanged.
|
|
759
|
+
*
|
|
760
|
+
* Only databases with real partial indexes accept this (PostgreSQL family,
|
|
761
|
+
* SQLite/Turso, SQL Server filtered indexes); the rest throw an
|
|
762
|
+
* `UnsupportedSchemaObjectError` rather than emit SQL the server rejects.
|
|
763
|
+
*/
|
|
764
|
+
where?: WhereOptions | string;
|
|
704
765
|
/** Expression for expression-based indexes (e.g., LOWER(column)) */
|
|
705
766
|
expression?: string;
|
|
706
767
|
/** Include columns for covering index (PostgreSQL 11+, MySQL 8.0.17+) */
|
|
@@ -721,20 +782,31 @@ export interface IndexOptions {
|
|
|
721
782
|
*/
|
|
722
783
|
invisible?: boolean;
|
|
723
784
|
}
|
|
785
|
+
/**
|
|
786
|
+
* An existing index as reported by the engine.
|
|
787
|
+
*/
|
|
724
788
|
export interface IndexDefinition {
|
|
725
789
|
name: string;
|
|
726
790
|
unique?: boolean;
|
|
727
791
|
type?: string;
|
|
728
792
|
using?: string;
|
|
729
793
|
fields: string[];
|
|
730
|
-
where
|
|
794
|
+
/** See {@link IndexOptions.where}. */
|
|
795
|
+
where?: WhereOptions | string;
|
|
731
796
|
/** See {@link IndexOptions.invisible}. */
|
|
732
797
|
invisible?: boolean;
|
|
733
798
|
}
|
|
799
|
+
/**
|
|
800
|
+
* Options for `DROP INDEX`, including `ifExists` and concurrency where the
|
|
801
|
+
* engine offers it.
|
|
802
|
+
*/
|
|
734
803
|
export interface DropIndexOptions {
|
|
735
804
|
ifExists?: boolean;
|
|
736
805
|
cascade?: boolean;
|
|
737
806
|
}
|
|
807
|
+
/**
|
|
808
|
+
* An existing constraint as reported by the engine.
|
|
809
|
+
*/
|
|
738
810
|
export interface ConstraintDefinition {
|
|
739
811
|
name: string;
|
|
740
812
|
type: 'PRIMARY KEY' | 'UNIQUE' | 'FOREIGN KEY' | 'CHECK';
|
|
@@ -748,6 +820,9 @@ export interface ConstraintDefinition {
|
|
|
748
820
|
check?: string;
|
|
749
821
|
deferrable?: 'INITIALLY DEFERRED' | 'INITIALLY IMMEDIATE';
|
|
750
822
|
}
|
|
823
|
+
/**
|
|
824
|
+
* Options for dropping a named constraint.
|
|
825
|
+
*/
|
|
751
826
|
export interface DropConstraintOptions {
|
|
752
827
|
ifExists?: boolean;
|
|
753
828
|
cascade?: boolean;
|
|
@@ -772,6 +847,10 @@ export interface DropViewOptions {
|
|
|
772
847
|
/** If true, also drops dependent views (PostgreSQL) */
|
|
773
848
|
cascade?: boolean;
|
|
774
849
|
}
|
|
850
|
+
/**
|
|
851
|
+
* Options for dropping a schema, including whether to cascade to the objects
|
|
852
|
+
* inside it.
|
|
853
|
+
*/
|
|
775
854
|
export interface DropSchemaOptions {
|
|
776
855
|
ifExists?: boolean;
|
|
777
856
|
cascade?: boolean;
|
|
@@ -865,6 +944,10 @@ export interface DropDomainOptions {
|
|
|
865
944
|
/** Schema the domain lives in */
|
|
866
945
|
schema?: string;
|
|
867
946
|
}
|
|
947
|
+
/**
|
|
948
|
+
* Options for `CREATE VIEW` — the defining query, whether it is materialised,
|
|
949
|
+
* and whether to replace an existing view.
|
|
950
|
+
*/
|
|
868
951
|
export interface ViewOptions {
|
|
869
952
|
/** Replace the view if it already exists (CREATE OR REPLACE) */
|
|
870
953
|
replace?: boolean;
|
|
@@ -873,12 +956,19 @@ export interface ViewOptions {
|
|
|
873
956
|
/** View comment */
|
|
874
957
|
comment?: string;
|
|
875
958
|
}
|
|
959
|
+
/**
|
|
960
|
+
* A foreign server: the wrapper that reaches it and the connection options it
|
|
961
|
+
* needs. See the foreign-data-wrappers guide.
|
|
962
|
+
*/
|
|
876
963
|
export interface FdwForeignServerOptions {
|
|
877
964
|
fdw: string;
|
|
878
965
|
options?: Record<string, string>;
|
|
879
966
|
version?: string;
|
|
880
967
|
ifNotExists?: boolean;
|
|
881
968
|
}
|
|
969
|
+
/**
|
|
970
|
+
* Changes to an existing foreign server's version or options.
|
|
971
|
+
*/
|
|
882
972
|
export interface FdwAlterForeignServerOptions {
|
|
883
973
|
options?: Record<string, string>;
|
|
884
974
|
addOptions?: Record<string, string>;
|
|
@@ -886,16 +976,26 @@ export interface FdwAlterForeignServerOptions {
|
|
|
886
976
|
dropOptions?: string[];
|
|
887
977
|
version?: string;
|
|
888
978
|
}
|
|
979
|
+
/**
|
|
980
|
+
* Maps a local role to credentials on a foreign server.
|
|
981
|
+
*/
|
|
889
982
|
export interface FdwUserMappingOptions {
|
|
890
983
|
serverName: string;
|
|
891
984
|
user: string;
|
|
892
985
|
options?: Record<string, string>;
|
|
893
986
|
ifNotExists?: boolean;
|
|
894
987
|
}
|
|
988
|
+
/**
|
|
989
|
+
* One column of a foreign table, including the remote name when it differs.
|
|
990
|
+
*/
|
|
895
991
|
export interface FdwForeignTableColumnDef {
|
|
896
992
|
type: string;
|
|
897
993
|
options?: string;
|
|
898
994
|
}
|
|
995
|
+
/**
|
|
996
|
+
* A foreign table: which server it lives on, its columns, and the remote
|
|
997
|
+
* object it maps to.
|
|
998
|
+
*/
|
|
899
999
|
export interface FdwForeignTableOptions {
|
|
900
1000
|
serverName: string;
|
|
901
1001
|
schema?: string;
|
|
@@ -903,21 +1003,36 @@ export interface FdwForeignTableOptions {
|
|
|
903
1003
|
options?: Record<string, string>;
|
|
904
1004
|
ifNotExists?: boolean;
|
|
905
1005
|
}
|
|
1006
|
+
/**
|
|
1007
|
+
* Options for importing a remote schema wholesale, with optional limits on
|
|
1008
|
+
* which tables come across.
|
|
1009
|
+
*/
|
|
906
1010
|
export interface FdwImportForeignSchemaOptions {
|
|
907
1011
|
localSchema?: string;
|
|
908
1012
|
limitTo?: string[];
|
|
909
1013
|
except?: string[];
|
|
910
1014
|
options?: Record<string, string>;
|
|
911
1015
|
}
|
|
1016
|
+
/**
|
|
1017
|
+
* Options for dropping a view, including the materialised variant.
|
|
1018
|
+
*/
|
|
912
1019
|
export interface DropViewOptions {
|
|
913
1020
|
ifExists?: boolean;
|
|
914
1021
|
cascade?: boolean;
|
|
915
1022
|
}
|
|
1023
|
+
/**
|
|
1024
|
+
* Shared options for the statement builders: the transaction to run inside
|
|
1025
|
+
* and any per-statement logging override.
|
|
1026
|
+
*/
|
|
916
1027
|
export interface BuildOptions {
|
|
917
1028
|
replacements?: Record<string, any>;
|
|
918
1029
|
model?: any;
|
|
919
1030
|
include?: IncludeOptions[];
|
|
920
1031
|
}
|
|
1032
|
+
/**
|
|
1033
|
+
* Options for building an `INSERT`, including returning clauses and conflict
|
|
1034
|
+
* handling where the engine supports them.
|
|
1035
|
+
*/
|
|
921
1036
|
export interface InsertOptions {
|
|
922
1037
|
/** Schema to use for the table */
|
|
923
1038
|
schema?: string;
|
|
@@ -927,6 +1042,10 @@ export interface InsertOptions {
|
|
|
927
1042
|
/** Fields to update on conflict (MySQL: ON DUPLICATE KEY UPDATE, PostgreSQL/SQLite: ON CONFLICT DO UPDATE, MariaDB: ON DUPLICATE KEY UPDATE) */
|
|
928
1043
|
updateOnDuplicate?: string[];
|
|
929
1044
|
}
|
|
1045
|
+
/**
|
|
1046
|
+
* Options for an insert-or-update, including which columns decide whether a
|
|
1047
|
+
* row already exists and which are written on conflict.
|
|
1048
|
+
*/
|
|
930
1049
|
export interface UpsertQueryOptions {
|
|
931
1050
|
/** Fields to use for conflict resolution (ON CONFLICT for PostgreSQL/SQLite, ON DUPLICATE KEY for MySQL/MariaDB) */
|
|
932
1051
|
conflictFields?: string[];
|
|
@@ -939,15 +1058,28 @@ export interface UpsertQueryOptions {
|
|
|
939
1058
|
/** Model raw attributes for type casting */
|
|
940
1059
|
model?: any;
|
|
941
1060
|
}
|
|
1061
|
+
/**
|
|
1062
|
+
* Options for building an `UPDATE`: the `where` that selects rows, and any
|
|
1063
|
+
* limit or ordering the engine permits on it.
|
|
1064
|
+
*/
|
|
942
1065
|
export interface UpdateOptions {
|
|
943
1066
|
limit?: number;
|
|
944
1067
|
returning?: boolean | string[];
|
|
945
1068
|
}
|
|
1069
|
+
/**
|
|
1070
|
+
* Options for building a `DELETE`, including the `where` and any limit the
|
|
1071
|
+
* engine permits.
|
|
1072
|
+
*/
|
|
946
1073
|
export interface DeleteOptions {
|
|
947
1074
|
limit?: number;
|
|
948
1075
|
returning?: boolean | string[];
|
|
949
1076
|
truncate?: boolean;
|
|
950
1077
|
}
|
|
1078
|
+
/**
|
|
1079
|
+
* Everything a `SELECT` can carry once associations have been resolved:
|
|
1080
|
+
* columns, joins, filtering, grouping, ordering, pagination and locking. This
|
|
1081
|
+
* is the dialect-facing form of `FindOptions`.
|
|
1082
|
+
*/
|
|
951
1083
|
export interface SelectOptions {
|
|
952
1084
|
tableName: string;
|
|
953
1085
|
/** Schema to use for the table */
|
|
@@ -1027,6 +1159,10 @@ export interface CTEOption {
|
|
|
1027
1159
|
/** Optional explicit column list: `name (col1, col2, ...) AS (...)`. */
|
|
1028
1160
|
columns?: string[];
|
|
1029
1161
|
}
|
|
1162
|
+
/**
|
|
1163
|
+
* Construction options for a dialect instance — the connection settings and
|
|
1164
|
+
* behaviour flags it needs to build and run statements.
|
|
1165
|
+
*/
|
|
1030
1166
|
export interface DialectOptions {
|
|
1031
1167
|
host?: string;
|
|
1032
1168
|
port?: number;
|
|
@@ -36,6 +36,7 @@ function loadDuckDb() {
|
|
|
36
36
|
const query_stream_helper_1 = require("../query-stream-helper");
|
|
37
37
|
const prorm_1 = require("../../prorm");
|
|
38
38
|
const operators_1 = require("../../operators");
|
|
39
|
+
const order_expression_helper_1 = require("../order-expression-helper");
|
|
39
40
|
function promisifyAll(target, sql, params) {
|
|
40
41
|
return new Promise((resolve, reject) => {
|
|
41
42
|
const cb = (err, rows) => {
|
|
@@ -1437,12 +1438,18 @@ class DuckDBDialect {
|
|
|
1437
1438
|
return { sql: result.sql, values };
|
|
1438
1439
|
}
|
|
1439
1440
|
buildOrderClause(order) {
|
|
1440
|
-
const orderArray = order;
|
|
1441
|
-
if (
|
|
1441
|
+
const orderArray = (0, order_expression_helper_1.normalizeOrderItems)(order);
|
|
1442
|
+
if (orderArray.length === 0) {
|
|
1442
1443
|
return '';
|
|
1443
1444
|
}
|
|
1444
1445
|
const orderParts = [];
|
|
1445
1446
|
for (const item of orderArray) {
|
|
1447
|
+
// Order helpers: asc('name') / desc('name') / random()
|
|
1448
|
+
const orderExpr = (0, order_expression_helper_1.renderOrderExpressionItem)(this, item);
|
|
1449
|
+
if (orderExpr !== null) {
|
|
1450
|
+
orderParts.push(orderExpr);
|
|
1451
|
+
continue;
|
|
1452
|
+
}
|
|
1446
1453
|
if (Array.isArray(item)) {
|
|
1447
1454
|
const field = typeof item[0] === 'string' ? this.escapeId(item[0]) : item[0];
|
|
1448
1455
|
const direction = item[1] ? ` ${item[1]}` : '';
|