@zenstackhq/runtime 3.0.0-alpha.32 → 3.0.0-alpha.33
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/{contract-CToGslMD.d.cts → contract-CusA0mQO.d.cts} +3 -1
- package/dist/{contract-CToGslMD.d.ts → contract-CusA0mQO.d.ts} +3 -1
- package/dist/index.cjs +259 -185
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +259 -185
- package/dist/index.js.map +1 -1
- package/dist/plugins/policy/index.cjs +109 -70
- package/dist/plugins/policy/index.cjs.map +1 -1
- package/dist/plugins/policy/index.d.cts +1 -1
- package/dist/plugins/policy/index.d.ts +1 -1
- package/dist/plugins/policy/index.js +109 -70
- package/dist/plugins/policy/index.js.map +1 -1
- package/dist/schema.cjs +4 -1
- package/dist/schema.cjs.map +1 -1
- package/dist/schema.d.cts +1 -0
- package/dist/schema.d.ts +1 -0
- package/dist/schema.js +4 -1
- package/dist/schema.js.map +1 -1
- package/package.json +8 -8
|
@@ -145,7 +145,10 @@ var ExpressionUtils = {
|
|
|
145
145
|
isUnary: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "unary"), "isUnary"),
|
|
146
146
|
isBinary: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "binary"), "isBinary"),
|
|
147
147
|
isField: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "field"), "isField"),
|
|
148
|
-
isMember: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "member"), "isMember")
|
|
148
|
+
isMember: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "member"), "isMember"),
|
|
149
|
+
getLiteralValue: /* @__PURE__ */ __name((expr2) => {
|
|
150
|
+
return ExpressionUtils.isLiteral(expr2) ? expr2.value : void 0;
|
|
151
|
+
}, "getLiteralValue")
|
|
149
152
|
};
|
|
150
153
|
|
|
151
154
|
// src/client/errors.ts
|
|
@@ -936,6 +939,16 @@ var BaseCrudDialect = class {
|
|
|
936
939
|
}
|
|
937
940
|
return result;
|
|
938
941
|
}
|
|
942
|
+
buildModelSelect(eb, model, subQueryAlias, payload, selectAllFields) {
|
|
943
|
+
let subQuery = this.buildSelectModel(eb, model, subQueryAlias);
|
|
944
|
+
if (selectAllFields) {
|
|
945
|
+
subQuery = this.buildSelectAllFields(model, subQuery, typeof payload === "object" ? payload?.omit : void 0, subQueryAlias);
|
|
946
|
+
}
|
|
947
|
+
if (payload && typeof payload === "object") {
|
|
948
|
+
subQuery = this.buildFilterSortTake(model, payload, subQuery, subQueryAlias);
|
|
949
|
+
}
|
|
950
|
+
return subQuery;
|
|
951
|
+
}
|
|
939
952
|
buildSelectField(query, model, modelAlias, field) {
|
|
940
953
|
const fieldDef = requireField(this.schema, model, field);
|
|
941
954
|
if (fieldDef.computed) {
|
|
@@ -1033,6 +1046,18 @@ var BaseCrudDialect = class {
|
|
|
1033
1046
|
fieldRef(model, field, eb, modelAlias, inlineComputedField = true) {
|
|
1034
1047
|
return buildFieldRef(this.schema, model, field, this.options, eb, modelAlias, inlineComputedField);
|
|
1035
1048
|
}
|
|
1049
|
+
canJoinWithoutNestedSelect(modelDef, payload) {
|
|
1050
|
+
if (modelDef.computedFields) {
|
|
1051
|
+
return false;
|
|
1052
|
+
}
|
|
1053
|
+
if (modelDef.baseModel || modelDef.isDelegate) {
|
|
1054
|
+
return false;
|
|
1055
|
+
}
|
|
1056
|
+
if (typeof payload === "object" && (payload.orderBy || payload.skip !== void 0 || payload.take !== void 0 || payload.cursor || payload.distinct)) {
|
|
1057
|
+
return false;
|
|
1058
|
+
}
|
|
1059
|
+
return true;
|
|
1060
|
+
}
|
|
1036
1061
|
};
|
|
1037
1062
|
|
|
1038
1063
|
// src/client/crud/dialects/postgresql.ts
|
|
@@ -1058,52 +1083,58 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
|
|
|
1058
1083
|
}
|
|
1059
1084
|
}
|
|
1060
1085
|
buildRelationSelection(query, model, relationField, parentAlias, payload) {
|
|
1061
|
-
const
|
|
1062
|
-
|
|
1086
|
+
const relationResultName = `${parentAlias}$${relationField}`;
|
|
1087
|
+
const joinedQuery = this.buildRelationJSON(model, query, relationField, parentAlias, payload, relationResultName);
|
|
1088
|
+
return joinedQuery.select(`${relationResultName}.$data as ${relationField}`);
|
|
1063
1089
|
}
|
|
1064
|
-
buildRelationJSON(model, qb, relationField,
|
|
1090
|
+
buildRelationJSON(model, qb, relationField, parentAlias, payload, resultName) {
|
|
1065
1091
|
const relationFieldDef = requireField(this.schema, model, relationField);
|
|
1066
1092
|
const relationModel = relationFieldDef.type;
|
|
1067
1093
|
return qb.leftJoinLateral((eb) => {
|
|
1068
|
-
const
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
} else {
|
|
1085
|
-
const joinPairs = buildJoinPairs(this.schema, model, parentName, relationField, subQueryAlias);
|
|
1086
|
-
subQuery = subQuery.where((eb2) => this.and(eb2, ...joinPairs.map(([left, right]) => eb2(import_kysely2.sql.ref(left), "=", import_kysely2.sql.ref(right)))));
|
|
1087
|
-
}
|
|
1088
|
-
return subQuery.as(joinTableName);
|
|
1089
|
-
});
|
|
1090
|
-
result = this.buildRelationObjectSelect(relationModel, joinTableName, relationField, relationFieldDef, result, payload, parentName);
|
|
1091
|
-
result = this.buildRelationJoins(relationModel, relationField, result, payload, parentName);
|
|
1092
|
-
return result.as(joinTableName);
|
|
1094
|
+
const relationSelectName = `${resultName}$sub`;
|
|
1095
|
+
const relationModelDef = requireModel(this.schema, relationModel);
|
|
1096
|
+
let tbl;
|
|
1097
|
+
if (this.canJoinWithoutNestedSelect(relationModelDef, payload)) {
|
|
1098
|
+
tbl = this.buildModelSelect(eb, relationModel, relationSelectName, payload, false);
|
|
1099
|
+
tbl = this.buildRelationJoinFilter(tbl, model, relationField, relationModel, relationSelectName, parentAlias);
|
|
1100
|
+
} else {
|
|
1101
|
+
tbl = eb.selectFrom(() => {
|
|
1102
|
+
let subQuery = this.buildModelSelect(eb, relationModel, `${relationSelectName}$t`, payload, true);
|
|
1103
|
+
subQuery = this.buildRelationJoinFilter(subQuery, model, relationField, relationModel, `${relationSelectName}$t`, parentAlias);
|
|
1104
|
+
return subQuery.as(relationSelectName);
|
|
1105
|
+
});
|
|
1106
|
+
}
|
|
1107
|
+
tbl = this.buildRelationObjectSelect(relationModel, relationSelectName, relationFieldDef, tbl, payload, resultName);
|
|
1108
|
+
tbl = this.buildRelationJoins(tbl, relationModel, relationSelectName, payload, resultName);
|
|
1109
|
+
return tbl.as(resultName);
|
|
1093
1110
|
}, (join) => join.onTrue());
|
|
1094
1111
|
}
|
|
1095
|
-
|
|
1112
|
+
buildRelationJoinFilter(query, model, relationField, relationModel, relationModelAlias, parentAlias) {
|
|
1113
|
+
const m2m = getManyToManyRelation(this.schema, model, relationField);
|
|
1114
|
+
if (m2m) {
|
|
1115
|
+
const parentIds = getIdFields(this.schema, model);
|
|
1116
|
+
const relationIds = getIdFields(this.schema, relationModel);
|
|
1117
|
+
(0, import_common_helpers2.invariant)(parentIds.length === 1, "many-to-many relation must have exactly one id field");
|
|
1118
|
+
(0, import_common_helpers2.invariant)(relationIds.length === 1, "many-to-many relation must have exactly one id field");
|
|
1119
|
+
query = query.where((eb) => eb(eb.ref(`${relationModelAlias}.${relationIds[0]}`), "in", eb.selectFrom(m2m.joinTable).select(`${m2m.joinTable}.${m2m.otherFkName}`).whereRef(`${parentAlias}.${parentIds[0]}`, "=", `${m2m.joinTable}.${m2m.parentFkName}`)));
|
|
1120
|
+
} else {
|
|
1121
|
+
const joinPairs = buildJoinPairs(this.schema, model, parentAlias, relationField, relationModelAlias);
|
|
1122
|
+
query = query.where((eb) => this.and(eb, ...joinPairs.map(([left, right]) => eb(import_kysely2.sql.ref(left), "=", import_kysely2.sql.ref(right)))));
|
|
1123
|
+
}
|
|
1124
|
+
return query;
|
|
1125
|
+
}
|
|
1126
|
+
buildRelationObjectSelect(relationModel, relationModelAlias, relationFieldDef, qb, payload, parentResultName) {
|
|
1096
1127
|
qb = qb.select((eb) => {
|
|
1097
|
-
const objArgs = this.buildRelationObjectArgs(relationModel, relationModelAlias,
|
|
1128
|
+
const objArgs = this.buildRelationObjectArgs(relationModel, relationModelAlias, eb, payload, parentResultName);
|
|
1098
1129
|
if (relationFieldDef.array) {
|
|
1099
|
-
return eb.fn.coalesce(import_kysely2.sql`jsonb_agg(jsonb_build_object(${import_kysely2.sql.join(objArgs)}))`, import_kysely2.sql`'[]'::jsonb`).as("$
|
|
1130
|
+
return eb.fn.coalesce(import_kysely2.sql`jsonb_agg(jsonb_build_object(${import_kysely2.sql.join(objArgs)}))`, import_kysely2.sql`'[]'::jsonb`).as("$data");
|
|
1100
1131
|
} else {
|
|
1101
|
-
return import_kysely2.sql`jsonb_build_object(${import_kysely2.sql.join(objArgs)})`.as("$
|
|
1132
|
+
return import_kysely2.sql`jsonb_build_object(${import_kysely2.sql.join(objArgs)})`.as("$data");
|
|
1102
1133
|
}
|
|
1103
1134
|
});
|
|
1104
1135
|
return qb;
|
|
1105
1136
|
}
|
|
1106
|
-
buildRelationObjectArgs(relationModel, relationModelAlias,
|
|
1137
|
+
buildRelationObjectArgs(relationModel, relationModelAlias, eb, payload, parentResultName) {
|
|
1107
1138
|
const relationModelDef = requireModel(this.schema, relationModel);
|
|
1108
1139
|
const objArgs = [];
|
|
1109
1140
|
const descendantModels = getDelegateDescendantModels(this.schema, relationModel);
|
|
@@ -1121,14 +1152,14 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
|
|
|
1121
1152
|
} else if (payload.select) {
|
|
1122
1153
|
objArgs.push(...Object.entries(payload.select).filter(([, value]) => value).map(([field, value]) => {
|
|
1123
1154
|
if (field === "_count") {
|
|
1124
|
-
const subJson = this.buildCountJson(relationModel, eb,
|
|
1155
|
+
const subJson = this.buildCountJson(relationModel, eb, relationModelAlias, value);
|
|
1125
1156
|
return [
|
|
1126
1157
|
import_kysely2.sql.lit(field),
|
|
1127
1158
|
subJson
|
|
1128
1159
|
];
|
|
1129
1160
|
} else {
|
|
1130
1161
|
const fieldDef = requireField(this.schema, relationModel, field);
|
|
1131
|
-
const fieldValue = fieldDef.relation ? eb.ref(`${
|
|
1162
|
+
const fieldValue = fieldDef.relation ? eb.ref(`${parentResultName}$${field}.$data`) : this.fieldRef(relationModel, field, eb, relationModelAlias, false);
|
|
1132
1163
|
return [
|
|
1133
1164
|
import_kysely2.sql.lit(field),
|
|
1134
1165
|
fieldValue
|
|
@@ -1140,18 +1171,18 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
|
|
|
1140
1171
|
objArgs.push(...Object.entries(payload.include).filter(([, value]) => value).map(([field]) => [
|
|
1141
1172
|
import_kysely2.sql.lit(field),
|
|
1142
1173
|
// reference the synthesized JSON field
|
|
1143
|
-
eb.ref(`${
|
|
1174
|
+
eb.ref(`${parentResultName}$${field}.$data`)
|
|
1144
1175
|
]).flatMap((v) => v));
|
|
1145
1176
|
}
|
|
1146
1177
|
return objArgs;
|
|
1147
1178
|
}
|
|
1148
|
-
buildRelationJoins(
|
|
1149
|
-
let result =
|
|
1179
|
+
buildRelationJoins(query, relationModel, relationModelAlias, payload, parentResultName) {
|
|
1180
|
+
let result = query;
|
|
1150
1181
|
if (typeof payload === "object") {
|
|
1151
1182
|
const selectInclude = payload.include ?? payload.select;
|
|
1152
1183
|
if (selectInclude && typeof selectInclude === "object") {
|
|
1153
1184
|
Object.entries(selectInclude).filter(([, value]) => value).filter(([field]) => isRelationField(this.schema, relationModel, field)).forEach(([field, value]) => {
|
|
1154
|
-
result = this.buildRelationJSON(relationModel, result, field, `${
|
|
1185
|
+
result = this.buildRelationJSON(relationModel, result, field, relationModelAlias, value, `${parentResultName}$${field}`);
|
|
1155
1186
|
});
|
|
1156
1187
|
}
|
|
1157
1188
|
}
|
|
@@ -1231,32 +1262,18 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
|
|
|
1231
1262
|
const relationModel = relationFieldDef.type;
|
|
1232
1263
|
const relationModelDef = requireModel(this.schema, relationModel);
|
|
1233
1264
|
const subQueryName = `${parentAlias}$${relationField}`;
|
|
1234
|
-
let tbl
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
(0, import_common_helpers3.invariant)(relationIds.length === 1, "many-to-many relation must have exactly one id field");
|
|
1247
|
-
subQuery = subQuery.where(eb(eb.ref(`${subQueryAlias}.${relationIds[0]}`), "in", eb.selectFrom(m2m.joinTable).select(`${m2m.joinTable}.${m2m.otherFkName}`).whereRef(`${parentAlias}.${parentIds[0]}`, "=", `${m2m.joinTable}.${m2m.parentFkName}`)));
|
|
1248
|
-
} else {
|
|
1249
|
-
const { keyPairs, ownedByModel } = getRelationForeignKeyFieldPairs(this.schema, model, relationField);
|
|
1250
|
-
keyPairs.forEach(({ fk, pk }) => {
|
|
1251
|
-
if (ownedByModel) {
|
|
1252
|
-
subQuery = subQuery.whereRef(`${subQueryAlias}.${pk}`, "=", `${parentAlias}.${fk}`);
|
|
1253
|
-
} else {
|
|
1254
|
-
subQuery = subQuery.whereRef(`${subQueryAlias}.${fk}`, "=", `${parentAlias}.${pk}`);
|
|
1255
|
-
}
|
|
1256
|
-
});
|
|
1257
|
-
}
|
|
1258
|
-
return subQuery.as(subQueryName);
|
|
1259
|
-
});
|
|
1265
|
+
let tbl;
|
|
1266
|
+
if (this.canJoinWithoutNestedSelect(relationModelDef, payload)) {
|
|
1267
|
+
tbl = this.buildModelSelect(eb, relationModel, subQueryName, payload, false);
|
|
1268
|
+
tbl = this.buildRelationJoinFilter(tbl, model, relationField, subQueryName, parentAlias);
|
|
1269
|
+
} else {
|
|
1270
|
+
tbl = eb.selectFrom(() => {
|
|
1271
|
+
const selectModelAlias = `${parentAlias}$${relationField}$sub`;
|
|
1272
|
+
let selectModelQuery = this.buildModelSelect(eb, relationModel, selectModelAlias, payload, true);
|
|
1273
|
+
selectModelQuery = this.buildRelationJoinFilter(selectModelQuery, model, relationField, selectModelAlias, parentAlias);
|
|
1274
|
+
return selectModelQuery.as(subQueryName);
|
|
1275
|
+
});
|
|
1276
|
+
}
|
|
1260
1277
|
tbl = tbl.select(() => {
|
|
1261
1278
|
const objArgs = [];
|
|
1262
1279
|
const descendantModels = getDelegateDescendantModels(this.schema, relationModel);
|
|
@@ -1269,7 +1286,7 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
|
|
|
1269
1286
|
if (payload === true || !payload.select) {
|
|
1270
1287
|
objArgs.push(...Object.entries(relationModelDef.fields).filter(([, value]) => !value.relation).filter(([name]) => !(typeof payload === "object" && payload.omit?.[name] === true)).map(([field]) => [
|
|
1271
1288
|
import_kysely3.sql.lit(field),
|
|
1272
|
-
this.fieldRef(relationModel, field, eb,
|
|
1289
|
+
this.fieldRef(relationModel, field, eb, subQueryName, false)
|
|
1273
1290
|
]).flatMap((v) => v));
|
|
1274
1291
|
} else if (payload.select) {
|
|
1275
1292
|
objArgs.push(...Object.entries(payload.select).filter(([, value]) => value).map(([field, value]) => {
|
|
@@ -1290,7 +1307,7 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
|
|
|
1290
1307
|
} else {
|
|
1291
1308
|
return [
|
|
1292
1309
|
import_kysely3.sql.lit(field),
|
|
1293
|
-
this.fieldRef(relationModel, field, eb,
|
|
1310
|
+
this.fieldRef(relationModel, field, eb, subQueryName, false)
|
|
1294
1311
|
];
|
|
1295
1312
|
}
|
|
1296
1313
|
}
|
|
@@ -1306,13 +1323,35 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
|
|
|
1306
1323
|
}).flatMap((v) => v));
|
|
1307
1324
|
}
|
|
1308
1325
|
if (relationFieldDef.array) {
|
|
1309
|
-
return eb.fn.coalesce(import_kysely3.sql`json_group_array(json_object(${import_kysely3.sql.join(objArgs)}))`, import_kysely3.sql`json_array()`).as("$
|
|
1326
|
+
return eb.fn.coalesce(import_kysely3.sql`json_group_array(json_object(${import_kysely3.sql.join(objArgs)}))`, import_kysely3.sql`json_array()`).as("$data");
|
|
1310
1327
|
} else {
|
|
1311
|
-
return import_kysely3.sql`json_object(${import_kysely3.sql.join(objArgs)})`.as("data");
|
|
1328
|
+
return import_kysely3.sql`json_object(${import_kysely3.sql.join(objArgs)})`.as("$data");
|
|
1312
1329
|
}
|
|
1313
1330
|
});
|
|
1314
1331
|
return tbl;
|
|
1315
1332
|
}
|
|
1333
|
+
buildRelationJoinFilter(selectModelQuery, model, relationField, relationModelAlias, parentAlias) {
|
|
1334
|
+
const fieldDef = requireField(this.schema, model, relationField);
|
|
1335
|
+
const relationModel = fieldDef.type;
|
|
1336
|
+
const m2m = getManyToManyRelation(this.schema, model, relationField);
|
|
1337
|
+
if (m2m) {
|
|
1338
|
+
const parentIds = getIdFields(this.schema, model);
|
|
1339
|
+
const relationIds = getIdFields(this.schema, relationModel);
|
|
1340
|
+
(0, import_common_helpers3.invariant)(parentIds.length === 1, "many-to-many relation must have exactly one id field");
|
|
1341
|
+
(0, import_common_helpers3.invariant)(relationIds.length === 1, "many-to-many relation must have exactly one id field");
|
|
1342
|
+
selectModelQuery = selectModelQuery.where((eb) => eb(eb.ref(`${relationModelAlias}.${relationIds[0]}`), "in", eb.selectFrom(m2m.joinTable).select(`${m2m.joinTable}.${m2m.otherFkName}`).whereRef(`${parentAlias}.${parentIds[0]}`, "=", `${m2m.joinTable}.${m2m.parentFkName}`)));
|
|
1343
|
+
} else {
|
|
1344
|
+
const { keyPairs, ownedByModel } = getRelationForeignKeyFieldPairs(this.schema, model, relationField);
|
|
1345
|
+
keyPairs.forEach(({ fk, pk }) => {
|
|
1346
|
+
if (ownedByModel) {
|
|
1347
|
+
selectModelQuery = selectModelQuery.whereRef(`${relationModelAlias}.${pk}`, "=", `${parentAlias}.${fk}`);
|
|
1348
|
+
} else {
|
|
1349
|
+
selectModelQuery = selectModelQuery.whereRef(`${relationModelAlias}.${fk}`, "=", `${parentAlias}.${pk}`);
|
|
1350
|
+
}
|
|
1351
|
+
});
|
|
1352
|
+
}
|
|
1353
|
+
return selectModelQuery;
|
|
1354
|
+
}
|
|
1316
1355
|
buildSkipTake(query, skip, take) {
|
|
1317
1356
|
if (take !== void 0) {
|
|
1318
1357
|
query = query.limit(take);
|