@zenstackhq/orm 3.4.3 → 3.4.5
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/dist/index.cjs +52 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -1
- package/dist/index.d.ts +10 -1
- package/dist/index.js +52 -12
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
package/dist/index.d.cts
CHANGED
|
@@ -604,8 +604,11 @@ type ClientOptions<Schema extends SchemaDef> = QueryOptions<Schema> & {
|
|
|
604
604
|
*/
|
|
605
605
|
validateInput?: boolean;
|
|
606
606
|
/**
|
|
607
|
-
* Whether to use compact alias names (e.g., "
|
|
607
|
+
* Whether to use compact alias names (e.g., "$$t1", "$$t2") when transforming ORM queries to SQL.
|
|
608
608
|
* Defaults to `true`.
|
|
609
|
+
*
|
|
610
|
+
* When set to `false`, original aliases are kept unless temporary aliases become too long for
|
|
611
|
+
* safe SQL identifier handling, in which case compact aliases are used as a fallback.
|
|
609
612
|
*/
|
|
610
613
|
useCompactAliasNames?: boolean;
|
|
611
614
|
/**
|
|
@@ -740,6 +743,12 @@ declare abstract class BaseCrudDialect<Schema extends SchemaDef> {
|
|
|
740
743
|
not(...args: Expression<SqlBool>[]): ExpressionWrapper<any, any, SqlBool>;
|
|
741
744
|
fieldRef(model: string, field: string, modelAlias?: string, inlineComputedField?: boolean): any;
|
|
742
745
|
protected canJoinWithoutNestedSelect(modelDef: ModelDef, payload: boolean | FindArgs<Schema, GetModels<Schema>, any, true>): boolean;
|
|
746
|
+
/**
|
|
747
|
+
* Builds an EXISTS expression from an inner SELECT query.
|
|
748
|
+
* Can be overridden by dialects that need special handling (e.g., MySQL wraps
|
|
749
|
+
* in a derived table to avoid "can't specify target table for update in FROM clause").
|
|
750
|
+
*/
|
|
751
|
+
protected buildExistsExpression(innerQuery: SelectQueryBuilder<any, any, any>): Expression<SqlBool>;
|
|
743
752
|
abstract get provider(): DataSourceProviderType;
|
|
744
753
|
/**
|
|
745
754
|
* Builds selection for a relation field.
|
package/dist/index.d.ts
CHANGED
|
@@ -604,8 +604,11 @@ type ClientOptions<Schema extends SchemaDef> = QueryOptions<Schema> & {
|
|
|
604
604
|
*/
|
|
605
605
|
validateInput?: boolean;
|
|
606
606
|
/**
|
|
607
|
-
* Whether to use compact alias names (e.g., "
|
|
607
|
+
* Whether to use compact alias names (e.g., "$$t1", "$$t2") when transforming ORM queries to SQL.
|
|
608
608
|
* Defaults to `true`.
|
|
609
|
+
*
|
|
610
|
+
* When set to `false`, original aliases are kept unless temporary aliases become too long for
|
|
611
|
+
* safe SQL identifier handling, in which case compact aliases are used as a fallback.
|
|
609
612
|
*/
|
|
610
613
|
useCompactAliasNames?: boolean;
|
|
611
614
|
/**
|
|
@@ -740,6 +743,12 @@ declare abstract class BaseCrudDialect<Schema extends SchemaDef> {
|
|
|
740
743
|
not(...args: Expression<SqlBool>[]): ExpressionWrapper<any, any, SqlBool>;
|
|
741
744
|
fieldRef(model: string, field: string, modelAlias?: string, inlineComputedField?: boolean): any;
|
|
742
745
|
protected canJoinWithoutNestedSelect(modelDef: ModelDef, payload: boolean | FindArgs<Schema, GetModels<Schema>, any, true>): boolean;
|
|
746
|
+
/**
|
|
747
|
+
* Builds an EXISTS expression from an inner SELECT query.
|
|
748
|
+
* Can be overridden by dialects that need special handling (e.g., MySQL wraps
|
|
749
|
+
* in a derived table to avoid "can't specify target table for update in FROM clause").
|
|
750
|
+
*/
|
|
751
|
+
protected buildExistsExpression(innerQuery: SelectQueryBuilder<any, any, any>): Expression<SqlBool>;
|
|
743
752
|
abstract get provider(): DataSourceProviderType;
|
|
744
753
|
/**
|
|
745
754
|
* Builds selection for a relation field.
|
package/dist/index.js
CHANGED
|
@@ -931,21 +931,22 @@ var BaseCrudDialect = class {
|
|
|
931
931
|
if (!subPayload) {
|
|
932
932
|
continue;
|
|
933
933
|
}
|
|
934
|
-
const
|
|
934
|
+
const existsSelect = /* @__PURE__ */ __name((negate) => {
|
|
935
935
|
const filter = this.buildFilter(relationModel, relationFilterSelectAlias, subPayload);
|
|
936
|
-
|
|
937
|
-
|
|
936
|
+
const innerQuery = this.buildSelectModel(relationModel, relationFilterSelectAlias).select(this.eb.lit(1).as("_")).where(buildPkFkWhereRefs(this.eb)).where(() => negate ? this.eb.not(filter) : filter);
|
|
937
|
+
return this.buildExistsExpression(innerQuery);
|
|
938
|
+
}, "existsSelect");
|
|
938
939
|
switch (key) {
|
|
939
940
|
case "some": {
|
|
940
|
-
result = this.and(result,
|
|
941
|
+
result = this.and(result, existsSelect(false));
|
|
941
942
|
break;
|
|
942
943
|
}
|
|
943
944
|
case "every": {
|
|
944
|
-
result = this.and(result, this.eb(
|
|
945
|
+
result = this.and(result, this.eb.not(existsSelect(true)));
|
|
945
946
|
break;
|
|
946
947
|
}
|
|
947
948
|
case "none": {
|
|
948
|
-
result = this.and(result, this.eb(
|
|
949
|
+
result = this.and(result, this.eb.not(existsSelect(false)));
|
|
949
950
|
break;
|
|
950
951
|
}
|
|
951
952
|
}
|
|
@@ -1562,6 +1563,15 @@ var BaseCrudDialect = class {
|
|
|
1562
1563
|
}
|
|
1563
1564
|
return true;
|
|
1564
1565
|
}
|
|
1566
|
+
// #endregion
|
|
1567
|
+
/**
|
|
1568
|
+
* Builds an EXISTS expression from an inner SELECT query.
|
|
1569
|
+
* Can be overridden by dialects that need special handling (e.g., MySQL wraps
|
|
1570
|
+
* in a derived table to avoid "can't specify target table for update in FROM clause").
|
|
1571
|
+
*/
|
|
1572
|
+
buildExistsExpression(innerQuery) {
|
|
1573
|
+
return this.eb.exists(innerQuery);
|
|
1574
|
+
}
|
|
1565
1575
|
};
|
|
1566
1576
|
|
|
1567
1577
|
// src/client/crud/dialects/lateral-join-dialect-base.ts
|
|
@@ -1784,6 +1794,9 @@ var MySqlCrudDialect = class extends LateralJoinDialectBase {
|
|
|
1784
1794
|
}
|
|
1785
1795
|
// #endregion
|
|
1786
1796
|
// #region other overrides
|
|
1797
|
+
buildExistsExpression(innerQuery) {
|
|
1798
|
+
return this.eb.exists(this.eb.selectFrom(innerQuery.as("$exists_sub")).select(this.eb.lit(1).as("_")));
|
|
1799
|
+
}
|
|
1787
1800
|
buildArrayAgg(arg) {
|
|
1788
1801
|
return this.eb.fn.coalesce(sql2`JSON_ARRAYAGG(${arg})`, sql2`JSON_ARRAY()`);
|
|
1789
1802
|
}
|
|
@@ -7439,20 +7452,45 @@ var TempAliasTransformer = class extends OperationNodeTransformer2 {
|
|
|
7439
7452
|
__name(this, "TempAliasTransformer");
|
|
7440
7453
|
}
|
|
7441
7454
|
aliasMap = /* @__PURE__ */ new Map();
|
|
7455
|
+
textEncoder = new TextEncoder();
|
|
7456
|
+
mode;
|
|
7457
|
+
maxIdentifierLength;
|
|
7458
|
+
constructor(options = {}) {
|
|
7459
|
+
super();
|
|
7460
|
+
this.mode = options.mode ?? "alwaysCompact";
|
|
7461
|
+
const maxIdentifierLength = options.maxIdentifierLength ?? 63;
|
|
7462
|
+
if (!Number.isFinite(maxIdentifierLength) || !Number.isInteger(maxIdentifierLength) || maxIdentifierLength <= 0) {
|
|
7463
|
+
throw new RangeError("maxIdentifierLength must be a positive integer");
|
|
7464
|
+
}
|
|
7465
|
+
this.maxIdentifierLength = maxIdentifierLength;
|
|
7466
|
+
}
|
|
7442
7467
|
run(node) {
|
|
7443
7468
|
this.aliasMap.clear();
|
|
7444
7469
|
return this.transformNode(node);
|
|
7445
7470
|
}
|
|
7446
7471
|
transformIdentifier(node, queryId) {
|
|
7447
|
-
if (node.name.startsWith(TEMP_ALIAS_PREFIX)) {
|
|
7472
|
+
if (!node.name.startsWith(TEMP_ALIAS_PREFIX)) {
|
|
7473
|
+
return super.transformIdentifier(node, queryId);
|
|
7474
|
+
}
|
|
7475
|
+
let shouldCompact = false;
|
|
7476
|
+
if (this.mode === "alwaysCompact") {
|
|
7477
|
+
shouldCompact = true;
|
|
7478
|
+
} else {
|
|
7479
|
+
const aliasByteLength = this.textEncoder.encode(node.name).length;
|
|
7480
|
+
if (aliasByteLength > this.maxIdentifierLength) {
|
|
7481
|
+
shouldCompact = true;
|
|
7482
|
+
}
|
|
7483
|
+
}
|
|
7484
|
+
if (shouldCompact) {
|
|
7448
7485
|
let mapped = this.aliasMap.get(node.name);
|
|
7449
7486
|
if (!mapped) {
|
|
7450
7487
|
mapped = `$$t${this.aliasMap.size + 1}`;
|
|
7451
7488
|
this.aliasMap.set(node.name, mapped);
|
|
7452
7489
|
}
|
|
7453
7490
|
return IdentifierNode2.create(mapped);
|
|
7491
|
+
} else {
|
|
7492
|
+
return super.transformIdentifier(node, queryId);
|
|
7454
7493
|
}
|
|
7455
|
-
return super.transformIdentifier(node, queryId);
|
|
7456
7494
|
}
|
|
7457
7495
|
};
|
|
7458
7496
|
|
|
@@ -7842,10 +7880,9 @@ In such cases, ZenStack cannot reliably determine the IDs of the mutated entitie
|
|
|
7842
7880
|
return this.nameMapper?.transformNode(query) ?? query;
|
|
7843
7881
|
}
|
|
7844
7882
|
processTempAlias(query) {
|
|
7845
|
-
|
|
7846
|
-
|
|
7847
|
-
}
|
|
7848
|
-
return new TempAliasTransformer().run(query);
|
|
7883
|
+
return new TempAliasTransformer({
|
|
7884
|
+
mode: this.options.useCompactAliasNames === false ? "compactLongNames" : "alwaysCompact"
|
|
7885
|
+
}).run(query);
|
|
7849
7886
|
}
|
|
7850
7887
|
createClientForConnection(connection, inTx) {
|
|
7851
7888
|
const innerExecutor = this.withConnectionProvider(new SingleConnectionProvider(connection));
|
|
@@ -8128,6 +8165,9 @@ var SchemaDbPusher = class {
|
|
|
8128
8165
|
}
|
|
8129
8166
|
for (const field of Object.values(model.fields)) {
|
|
8130
8167
|
if (field.relation && field.relation.fields && field.relation.references) {
|
|
8168
|
+
if (field.type === model.name) {
|
|
8169
|
+
continue;
|
|
8170
|
+
}
|
|
8131
8171
|
const targetModel = requireModel(this.schema, field.type);
|
|
8132
8172
|
graph.push([
|
|
8133
8173
|
model,
|