@zenstackhq/orm 3.5.2 → 3.5.4
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 +261 -136
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +21 -4
- package/dist/index.d.ts +21 -4
- package/dist/index.js +140 -15
- package/dist/index.js.map +1 -1
- package/package.json +19 -9
package/dist/index.cjs
CHANGED
|
@@ -65,7 +65,7 @@ __export(src_exports, {
|
|
|
65
65
|
module.exports = __toCommonJS(src_exports);
|
|
66
66
|
|
|
67
67
|
// src/client/client-impl.ts
|
|
68
|
-
var
|
|
68
|
+
var import_common_helpers15 = require("@zenstackhq/common-helpers");
|
|
69
69
|
var import_kysely12 = require("kysely");
|
|
70
70
|
var import_zod3 = __toESM(require("zod"), 1);
|
|
71
71
|
|
|
@@ -119,7 +119,7 @@ __export(query_utils_exports, {
|
|
|
119
119
|
stripAlias: () => stripAlias,
|
|
120
120
|
tmpAlias: () => tmpAlias
|
|
121
121
|
});
|
|
122
|
-
var
|
|
122
|
+
var import_common_helpers2 = require("@zenstackhq/common-helpers");
|
|
123
123
|
var import_kysely = require("kysely");
|
|
124
124
|
var import_ts_pattern = require("ts-pattern");
|
|
125
125
|
|
|
@@ -128,6 +128,7 @@ var schema_exports = {};
|
|
|
128
128
|
__reExport(schema_exports, require("@zenstackhq/schema"));
|
|
129
129
|
|
|
130
130
|
// src/utils/object-utils.ts
|
|
131
|
+
var import_common_helpers = require("@zenstackhq/common-helpers");
|
|
131
132
|
function extractFields(obj, fields) {
|
|
132
133
|
return Object.fromEntries(Object.entries(obj).filter(([key]) => fields.includes(key)));
|
|
133
134
|
}
|
|
@@ -139,6 +140,10 @@ function fieldsToSelectObject(fields) {
|
|
|
139
140
|
]));
|
|
140
141
|
}
|
|
141
142
|
__name(fieldsToSelectObject, "fieldsToSelectObject");
|
|
143
|
+
function isEmptyObject(x) {
|
|
144
|
+
return (0, import_common_helpers.isPlainObject)(x) && Object.keys(x).length === 0;
|
|
145
|
+
}
|
|
146
|
+
__name(isEmptyObject, "isEmptyObject");
|
|
142
147
|
|
|
143
148
|
// src/client/executor/error-processor.ts
|
|
144
149
|
function getDbErrorCode(error) {
|
|
@@ -507,9 +512,9 @@ function getManyToManyRelation(schema, model, field) {
|
|
|
507
512
|
];
|
|
508
513
|
}
|
|
509
514
|
const modelIdFields = requireIdFields(schema, realModel);
|
|
510
|
-
(0,
|
|
515
|
+
(0, import_common_helpers2.invariant)(modelIdFields.length === 1, "Only single-field ID is supported for many-to-many relation");
|
|
511
516
|
const otherIdFields = requireIdFields(schema, fieldDef.type);
|
|
512
|
-
(0,
|
|
517
|
+
(0, import_common_helpers2.invariant)(otherIdFields.length === 1, "Only single-field ID is supported for many-to-many relation");
|
|
513
518
|
return {
|
|
514
519
|
parentFkName: orderedFK[0],
|
|
515
520
|
parentPKName: modelIdFields[0],
|
|
@@ -651,7 +656,7 @@ __name(tmpAlias, "tmpAlias");
|
|
|
651
656
|
|
|
652
657
|
// src/client/crud/operations/base.ts
|
|
653
658
|
var import_cuid2 = require("@paralleldrive/cuid2");
|
|
654
|
-
var
|
|
659
|
+
var import_common_helpers8 = require("@zenstackhq/common-helpers");
|
|
655
660
|
var import_cuid = __toESM(require("cuid"), 1);
|
|
656
661
|
var import_kysely6 = require("kysely");
|
|
657
662
|
var import_nanoid = require("nanoid");
|
|
@@ -741,7 +746,7 @@ var CRUD_EXT = [
|
|
|
741
746
|
var import_ts_pattern3 = require("ts-pattern");
|
|
742
747
|
|
|
743
748
|
// src/client/crud/dialects/mysql.ts
|
|
744
|
-
var
|
|
749
|
+
var import_common_helpers5 = require("@zenstackhq/common-helpers");
|
|
745
750
|
var import_decimal = __toESM(require("decimal.js"), 1);
|
|
746
751
|
var import_kysely3 = require("kysely");
|
|
747
752
|
|
|
@@ -772,10 +777,10 @@ var AnyNullClass = class {
|
|
|
772
777
|
var AnyNull = new AnyNullClass();
|
|
773
778
|
|
|
774
779
|
// src/client/crud/dialects/lateral-join-dialect-base.ts
|
|
775
|
-
var
|
|
780
|
+
var import_common_helpers4 = require("@zenstackhq/common-helpers");
|
|
776
781
|
|
|
777
782
|
// src/client/crud/dialects/base-dialect.ts
|
|
778
|
-
var
|
|
783
|
+
var import_common_helpers3 = require("@zenstackhq/common-helpers");
|
|
779
784
|
var import_kysely2 = require("kysely");
|
|
780
785
|
var import_ts_pattern2 = require("ts-pattern");
|
|
781
786
|
var BaseCrudDialect = class {
|
|
@@ -903,7 +908,31 @@ var BaseCrudDialect = class {
|
|
|
903
908
|
return LOGICAL_COMBINATORS.includes(key);
|
|
904
909
|
}
|
|
905
910
|
buildCompositeFilter(model, modelAlias, key, payload) {
|
|
906
|
-
|
|
911
|
+
const normalizedPayload = (0, import_common_helpers3.enumerate)(payload).filter((el) => {
|
|
912
|
+
if (typeof el === "object" && el !== null && !Array.isArray(el)) {
|
|
913
|
+
const entries = Object.entries(el);
|
|
914
|
+
return entries.some(([, v]) => v !== void 0);
|
|
915
|
+
} else {
|
|
916
|
+
return true;
|
|
917
|
+
}
|
|
918
|
+
});
|
|
919
|
+
const normalizedFilters = normalizedPayload.map((el) => this.buildFilter(model, modelAlias, el));
|
|
920
|
+
return (0, import_ts_pattern2.match)(key).with("AND", () => {
|
|
921
|
+
if (normalizedFilters.length === 0) {
|
|
922
|
+
return this.true();
|
|
923
|
+
}
|
|
924
|
+
return this.and(...normalizedFilters);
|
|
925
|
+
}).with("OR", () => {
|
|
926
|
+
if (normalizedFilters.length === 0) {
|
|
927
|
+
return this.false();
|
|
928
|
+
}
|
|
929
|
+
return this.or(...normalizedFilters);
|
|
930
|
+
}).with("NOT", () => {
|
|
931
|
+
if (normalizedFilters.length === 0) {
|
|
932
|
+
return this.true();
|
|
933
|
+
}
|
|
934
|
+
return this.not(...normalizedFilters);
|
|
935
|
+
}).exhaustive();
|
|
907
936
|
}
|
|
908
937
|
buildRelationFilter(model, modelAlias, field, fieldDef, payload) {
|
|
909
938
|
if (!fieldDef.array) {
|
|
@@ -970,9 +999,9 @@ var BaseCrudDialect = class {
|
|
|
970
999
|
const m2m = getManyToManyRelation(this.schema, model, field);
|
|
971
1000
|
if (m2m) {
|
|
972
1001
|
const modelIdFields = requireIdFields(this.schema, model);
|
|
973
|
-
(0,
|
|
1002
|
+
(0, import_common_helpers3.invariant)(modelIdFields.length === 1, "many-to-many relation must have exactly one id field");
|
|
974
1003
|
const relationIdFields = requireIdFields(this.schema, relationModel);
|
|
975
|
-
(0,
|
|
1004
|
+
(0, import_common_helpers3.invariant)(relationIdFields.length === 1, "many-to-many relation must have exactly one id field");
|
|
976
1005
|
return eb(this.eb.ref(`${relationFilterSelectAlias}.${relationIdFields[0]}`), "in", eb.selectFrom(m2m.joinTable).select(`${m2m.joinTable}.${m2m.otherFkName}`).whereRef(this.eb.ref(`${m2m.joinTable}.${m2m.parentFkName}`), "=", this.eb.ref(`${modelAlias}.${modelIdFields[0]}`)));
|
|
977
1006
|
} else {
|
|
978
1007
|
const relationKeyPairs = getRelationForeignKeyFieldPairs(this.schema, model, field);
|
|
@@ -1021,14 +1050,14 @@ var BaseCrudDialect = class {
|
|
|
1021
1050
|
if (_value === void 0) {
|
|
1022
1051
|
continue;
|
|
1023
1052
|
}
|
|
1024
|
-
(0,
|
|
1053
|
+
(0, import_common_helpers3.invariant)(fieldDef.array, "Field must be an array type to build array filter");
|
|
1025
1054
|
const value = this.transformInput(_value, fieldType, true);
|
|
1026
1055
|
let receiver = fieldRef;
|
|
1027
1056
|
if (isEnum(this.schema, fieldType)) {
|
|
1028
1057
|
receiver = this.eb.cast(fieldRef, import_kysely2.sql.raw("text[]"));
|
|
1029
1058
|
}
|
|
1030
1059
|
const buildArray = /* @__PURE__ */ __name((value2) => {
|
|
1031
|
-
(0,
|
|
1060
|
+
(0, import_common_helpers3.invariant)(Array.isArray(value2), "Array filter value must be an array");
|
|
1032
1061
|
return this.buildArrayValue(value2.map((v) => this.eb.val(v)), fieldType);
|
|
1033
1062
|
}, "buildArray");
|
|
1034
1063
|
switch (key) {
|
|
@@ -1074,7 +1103,7 @@ var BaseCrudDialect = class {
|
|
|
1074
1103
|
}).exhaustive();
|
|
1075
1104
|
}
|
|
1076
1105
|
buildJsonFilter(receiver, filter, fieldDef) {
|
|
1077
|
-
(0,
|
|
1106
|
+
(0, import_common_helpers3.invariant)(filter && typeof filter === "object", "Json filter payload must be an object");
|
|
1078
1107
|
if ([
|
|
1079
1108
|
"path",
|
|
1080
1109
|
"equals",
|
|
@@ -1099,7 +1128,7 @@ var BaseCrudDialect = class {
|
|
|
1099
1128
|
const jsonReceiver = this.buildJsonPathSelection(receiver, path);
|
|
1100
1129
|
const stringReceiver = this.castText(jsonReceiver);
|
|
1101
1130
|
const mode = filter.mode ?? "default";
|
|
1102
|
-
(0,
|
|
1131
|
+
(0, import_common_helpers3.invariant)(mode === "default" || mode === "insensitive", "Invalid JSON filter mode");
|
|
1103
1132
|
for (const [key, value] of Object.entries(filter)) {
|
|
1104
1133
|
switch (key) {
|
|
1105
1134
|
case "equals": {
|
|
@@ -1111,17 +1140,17 @@ var BaseCrudDialect = class {
|
|
|
1111
1140
|
break;
|
|
1112
1141
|
}
|
|
1113
1142
|
case "string_contains": {
|
|
1114
|
-
(0,
|
|
1143
|
+
(0, import_common_helpers3.invariant)(typeof value === "string", "string_contains value must be a string");
|
|
1115
1144
|
clauses.push(this.buildJsonStringFilter(stringReceiver, key, value, mode));
|
|
1116
1145
|
break;
|
|
1117
1146
|
}
|
|
1118
1147
|
case "string_starts_with": {
|
|
1119
|
-
(0,
|
|
1148
|
+
(0, import_common_helpers3.invariant)(typeof value === "string", "string_starts_with value must be a string");
|
|
1120
1149
|
clauses.push(this.buildJsonStringFilter(stringReceiver, key, value, mode));
|
|
1121
1150
|
break;
|
|
1122
1151
|
}
|
|
1123
1152
|
case "string_ends_with": {
|
|
1124
|
-
(0,
|
|
1153
|
+
(0, import_common_helpers3.invariant)(typeof value === "string", "string_ends_with value must be a string");
|
|
1125
1154
|
clauses.push(this.buildJsonStringFilter(stringReceiver, key, value, mode));
|
|
1126
1155
|
break;
|
|
1127
1156
|
}
|
|
@@ -1154,7 +1183,7 @@ var BaseCrudDialect = class {
|
|
|
1154
1183
|
}
|
|
1155
1184
|
}
|
|
1156
1185
|
buildTypedJsonArrayFilter(receiver, filter, typeDefName) {
|
|
1157
|
-
(0,
|
|
1186
|
+
(0, import_common_helpers3.invariant)(filter && typeof filter === "object", "Typed JSON array filter payload must be an object");
|
|
1158
1187
|
const makeExistsPred = /* @__PURE__ */ __name((filter2) => this.buildJsonArrayExistsPredicate(receiver, (elem) => this.buildTypedJsonFilter(elem, filter2, typeDefName, false)), "makeExistsPred");
|
|
1159
1188
|
const makeExistsNegatedPred = /* @__PURE__ */ __name((filter2) => this.buildJsonArrayExistsPredicate(receiver, (elem) => this.eb.not(this.buildTypedJsonFilter(elem, filter2, typeDefName, false))), "makeExistsNegatedPred");
|
|
1160
1189
|
const clauses = [];
|
|
@@ -1173,7 +1202,7 @@ var BaseCrudDialect = class {
|
|
|
1173
1202
|
clauses.push(this.eb.not(makeExistsNegatedPred(value)));
|
|
1174
1203
|
break;
|
|
1175
1204
|
default:
|
|
1176
|
-
(0,
|
|
1205
|
+
(0, import_common_helpers3.invariant)(false, `Invalid typed JSON array filter key: ${key}`);
|
|
1177
1206
|
}
|
|
1178
1207
|
}
|
|
1179
1208
|
return this.and(...clauses);
|
|
@@ -1183,7 +1212,7 @@ var BaseCrudDialect = class {
|
|
|
1183
1212
|
if (filter === null) {
|
|
1184
1213
|
return this.eb(receiver, "=", this.transformInput(null, "Json", false));
|
|
1185
1214
|
}
|
|
1186
|
-
(0,
|
|
1215
|
+
(0, import_common_helpers3.invariant)(filter && typeof filter === "object", "Typed JSON filter payload must be an object");
|
|
1187
1216
|
if ("is" in filter || "isNot" in filter) {
|
|
1188
1217
|
if ("is" in filter && filter.is && typeof filter.is === "object") {
|
|
1189
1218
|
clauses.push(this.buildTypedJsonFilter(receiver, filter.is, typeDefName, false));
|
|
@@ -1195,7 +1224,7 @@ var BaseCrudDialect = class {
|
|
|
1195
1224
|
const typeDef = requireTypeDef(this.schema, typeDefName);
|
|
1196
1225
|
for (const [key, value] of Object.entries(filter)) {
|
|
1197
1226
|
const fieldDef = typeDef.fields[key];
|
|
1198
|
-
(0,
|
|
1227
|
+
(0, import_common_helpers3.invariant)(fieldDef, `Field "${key}" not found in type definition "${typeDefName}"`);
|
|
1199
1228
|
const fieldReceiver = this.buildJsonPathSelection(receiver, `$.${key}`);
|
|
1200
1229
|
if (isTypeDef(this.schema, fieldDef.type)) {
|
|
1201
1230
|
clauses.push(this.buildTypedJsonFilter(fieldReceiver, value, fieldDef.type, !!fieldDef.array));
|
|
@@ -1244,7 +1273,7 @@ var BaseCrudDialect = class {
|
|
|
1244
1273
|
return this.eb(lhs, "=", this.transformInput(rhs, type, false));
|
|
1245
1274
|
}
|
|
1246
1275
|
buildStandardFilter(type, payload, lhs, getRhs, recurse, throwIfInvalid = false, onlyForKeys = void 0, excludeKeys = []) {
|
|
1247
|
-
if (payload === null || !(0,
|
|
1276
|
+
if (payload === null || !(0, import_common_helpers3.isPlainObject)(payload)) {
|
|
1248
1277
|
return {
|
|
1249
1278
|
conditions: [
|
|
1250
1279
|
this.buildValueFilter(lhs, type, payload)
|
|
@@ -1261,24 +1290,27 @@ var BaseCrudDialect = class {
|
|
|
1261
1290
|
if (excludeKeys.includes(op)) {
|
|
1262
1291
|
continue;
|
|
1263
1292
|
}
|
|
1293
|
+
if (value === void 0) {
|
|
1294
|
+
continue;
|
|
1295
|
+
}
|
|
1264
1296
|
const rhs = Array.isArray(value) ? value.map(getRhs) : getRhs(value);
|
|
1265
1297
|
const condition = (0, import_ts_pattern2.match)(op).with("equals", () => rhs === null ? this.eb(lhs, "is", null) : this.eb(lhs, "=", rhs)).with("in", () => {
|
|
1266
|
-
(0,
|
|
1298
|
+
(0, import_common_helpers3.invariant)(Array.isArray(rhs), "right hand side must be an array");
|
|
1267
1299
|
if (rhs.length === 0) {
|
|
1268
1300
|
return this.false();
|
|
1269
1301
|
} else {
|
|
1270
1302
|
return this.eb(lhs, "in", rhs);
|
|
1271
1303
|
}
|
|
1272
1304
|
}).with("notIn", () => {
|
|
1273
|
-
(0,
|
|
1305
|
+
(0, import_common_helpers3.invariant)(Array.isArray(rhs), "right hand side must be an array");
|
|
1274
1306
|
if (rhs.length === 0) {
|
|
1275
1307
|
return this.true();
|
|
1276
1308
|
} else {
|
|
1277
1309
|
return this.eb.not(this.eb(lhs, "in", rhs));
|
|
1278
1310
|
}
|
|
1279
1311
|
}).with("lt", () => this.eb(lhs, "<", rhs)).with("lte", () => this.eb(lhs, "<=", rhs)).with("gt", () => this.eb(lhs, ">", rhs)).with("gte", () => this.eb(lhs, ">=", rhs)).with("between", () => {
|
|
1280
|
-
(0,
|
|
1281
|
-
(0,
|
|
1312
|
+
(0, import_common_helpers3.invariant)(Array.isArray(rhs), "right hand side must be an array");
|
|
1313
|
+
(0, import_common_helpers3.invariant)(rhs.length === 2, "right hand side must have a length of 2");
|
|
1282
1314
|
const [start, end] = rhs;
|
|
1283
1315
|
return this.eb.and([
|
|
1284
1316
|
this.eb(lhs, ">=", start),
|
|
@@ -1318,7 +1350,10 @@ var BaseCrudDialect = class {
|
|
|
1318
1350
|
if (key === "mode" || consumedKeys.includes(key)) {
|
|
1319
1351
|
continue;
|
|
1320
1352
|
}
|
|
1321
|
-
|
|
1353
|
+
if (value === void 0) {
|
|
1354
|
+
continue;
|
|
1355
|
+
}
|
|
1356
|
+
(0, import_common_helpers3.invariant)(typeof value === "string", `${key} value must be a string`);
|
|
1322
1357
|
const escapedValue = this.escapeLikePattern(value);
|
|
1323
1358
|
const condition = (0, import_ts_pattern2.match)(key).with("contains", () => this.buildStringLike(fieldRef, `%${escapedValue}%`, mode === "insensitive")).with("startsWith", () => this.buildStringLike(fieldRef, `${escapedValue}%`, mode === "insensitive")).with("endsWith", () => this.buildStringLike(fieldRef, `%${escapedValue}`, mode === "insensitive")).otherwise(() => {
|
|
1324
1359
|
throw createInvalidInputError(`Invalid string filter key: ${key}`);
|
|
@@ -1399,7 +1434,7 @@ var BaseCrudDialect = class {
|
|
|
1399
1434
|
const fieldDef = requireField(this.schema, model2, field);
|
|
1400
1435
|
return fieldDef.originModel ? this.fieldRef(fieldDef.originModel, field, fieldDef.originModel) : this.fieldRef(model2, field, modelAlias2);
|
|
1401
1436
|
}, "buildFieldRef");
|
|
1402
|
-
(0,
|
|
1437
|
+
(0, import_common_helpers3.enumerate)(orderBy).forEach((orderBy2, index) => {
|
|
1403
1438
|
for (const [field, value] of Object.entries(orderBy2)) {
|
|
1404
1439
|
if (!value) {
|
|
1405
1440
|
continue;
|
|
@@ -1411,9 +1446,9 @@ var BaseCrudDialect = class {
|
|
|
1411
1446
|
"_min",
|
|
1412
1447
|
"_max"
|
|
1413
1448
|
].includes(field)) {
|
|
1414
|
-
(0,
|
|
1449
|
+
(0, import_common_helpers3.invariant)(typeof value === "object", `invalid orderBy value for field "${field}"`);
|
|
1415
1450
|
for (const [k, v] of Object.entries(value)) {
|
|
1416
|
-
(0,
|
|
1451
|
+
(0, import_common_helpers3.invariant)(v === "asc" || v === "desc", `invalid orderBy value for field "${field}"`);
|
|
1417
1452
|
result = result.orderBy((eb) => aggregate(eb, buildFieldRef(model, k, modelAlias), field), this.negateSort(v, negated));
|
|
1418
1453
|
}
|
|
1419
1454
|
continue;
|
|
@@ -1433,7 +1468,7 @@ var BaseCrudDialect = class {
|
|
|
1433
1468
|
throw createInvalidInputError(`invalid orderBy value for field "${field}"`);
|
|
1434
1469
|
}
|
|
1435
1470
|
if ("_count" in value) {
|
|
1436
|
-
(0,
|
|
1471
|
+
(0, import_common_helpers3.invariant)(value._count === "asc" || value._count === "desc", 'invalid orderBy value for field "_count"');
|
|
1437
1472
|
const sort = this.negateSort(value._count, negated);
|
|
1438
1473
|
result = result.orderBy((eb) => {
|
|
1439
1474
|
const subQueryAlias = tmpAlias(`${modelAlias}$ob$${field}$ct`);
|
|
@@ -1490,7 +1525,7 @@ var BaseCrudDialect = class {
|
|
|
1490
1525
|
if (omit && typeof omit === "object" && typeof omit[field] === "boolean") {
|
|
1491
1526
|
return omit[field];
|
|
1492
1527
|
}
|
|
1493
|
-
const uncapModel = (0,
|
|
1528
|
+
const uncapModel = (0, import_common_helpers3.lowerCaseFirst)(model);
|
|
1494
1529
|
const omitConfig = this.options.omit?.[uncapModel] ?? this.options.omit?.[model];
|
|
1495
1530
|
if (omitConfig && typeof omitConfig === "object" && typeof omitConfig[field] === "boolean") {
|
|
1496
1531
|
return omitConfig[field];
|
|
@@ -1612,7 +1647,7 @@ var BaseCrudDialect = class {
|
|
|
1612
1647
|
if ("computedFields" in this.options) {
|
|
1613
1648
|
const computedFields = this.options.computedFields;
|
|
1614
1649
|
const computedModel = fieldDef.originModel ?? model;
|
|
1615
|
-
computer = computedFields?.[(0,
|
|
1650
|
+
computer = computedFields?.[(0, import_common_helpers3.lowerCaseFirst)(computedModel)]?.[field] ?? computedFields?.[computedModel]?.[field];
|
|
1616
1651
|
}
|
|
1617
1652
|
if (!computer) {
|
|
1618
1653
|
throw createConfigError(`Computed field "${field}" implementation not provided for model "${model}"`);
|
|
@@ -1643,6 +1678,12 @@ var BaseCrudDialect = class {
|
|
|
1643
1678
|
buildExistsExpression(innerQuery) {
|
|
1644
1679
|
return this.eb.exists(innerQuery);
|
|
1645
1680
|
}
|
|
1681
|
+
/**
|
|
1682
|
+
* Builds a binary comparison expression between two operands.
|
|
1683
|
+
*/
|
|
1684
|
+
buildComparison(left, _leftFieldDef, op, right, _rightFieldDef) {
|
|
1685
|
+
return this.eb(left, op, right);
|
|
1686
|
+
}
|
|
1646
1687
|
};
|
|
1647
1688
|
|
|
1648
1689
|
// src/client/crud/dialects/lateral-join-dialect-base.ts
|
|
@@ -1685,8 +1726,8 @@ var LateralJoinDialectBase = class extends BaseCrudDialect {
|
|
|
1685
1726
|
if (m2m) {
|
|
1686
1727
|
const parentIds = requireIdFields(this.schema, model);
|
|
1687
1728
|
const relationIds = requireIdFields(this.schema, relationModel);
|
|
1688
|
-
(0,
|
|
1689
|
-
(0,
|
|
1729
|
+
(0, import_common_helpers4.invariant)(parentIds.length === 1, "many-to-many relation must have exactly one id field");
|
|
1730
|
+
(0, import_common_helpers4.invariant)(relationIds.length === 1, "many-to-many relation must have exactly one id field");
|
|
1690
1731
|
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}`)));
|
|
1691
1732
|
} else {
|
|
1692
1733
|
const joinPairs = buildJoinPairs(this.schema, model, parentAlias, relationField, relationModelAlias);
|
|
@@ -1840,7 +1881,7 @@ var MySqlCrudDialect = class extends LateralJoinDialectBase {
|
|
|
1840
1881
|
} else if (value instanceof DbNullClass) {
|
|
1841
1882
|
return null;
|
|
1842
1883
|
} else if (value instanceof AnyNullClass) {
|
|
1843
|
-
(0,
|
|
1884
|
+
(0, import_common_helpers5.invariant)(false, "should not reach here: AnyNull is not a valid input value");
|
|
1844
1885
|
}
|
|
1845
1886
|
if (isTypeDef(this.schema, type)) {
|
|
1846
1887
|
if (typeof value !== "string") {
|
|
@@ -1903,14 +1944,14 @@ var MySqlCrudDialect = class extends LateralJoinDialectBase {
|
|
|
1903
1944
|
if (typeof value === "bigint") {
|
|
1904
1945
|
return value;
|
|
1905
1946
|
}
|
|
1906
|
-
(0,
|
|
1947
|
+
(0, import_common_helpers5.invariant)(typeof value === "string" || typeof value === "number", `Expected string or number, got ${typeof value}`);
|
|
1907
1948
|
return BigInt(value);
|
|
1908
1949
|
}
|
|
1909
1950
|
transformDecimal(value) {
|
|
1910
1951
|
if (value instanceof import_decimal.default) {
|
|
1911
1952
|
return value;
|
|
1912
1953
|
}
|
|
1913
|
-
(0,
|
|
1954
|
+
(0, import_common_helpers5.invariant)(typeof value === "string" || typeof value === "number" || value instanceof import_decimal.default, `Expected string, number or Decimal, got ${typeof value}`);
|
|
1914
1955
|
return new import_decimal.default(value);
|
|
1915
1956
|
}
|
|
1916
1957
|
transformOutputDate(value) {
|
|
@@ -2057,7 +2098,7 @@ var MySqlCrudDialect = class extends LateralJoinDialectBase {
|
|
|
2057
2098
|
};
|
|
2058
2099
|
|
|
2059
2100
|
// src/client/crud/dialects/postgresql.ts
|
|
2060
|
-
var
|
|
2101
|
+
var import_common_helpers6 = require("@zenstackhq/common-helpers");
|
|
2061
2102
|
var import_decimal2 = __toESM(require("decimal.js"), 1);
|
|
2062
2103
|
var import_kysely4 = require("kysely");
|
|
2063
2104
|
var import_postgres_array = require("postgres-array");
|
|
@@ -2077,6 +2118,33 @@ var PostgresCrudDialect = class _PostgresCrudDialect extends LateralJoinDialectB
|
|
|
2077
2118
|
Bytes: "bytea",
|
|
2078
2119
|
Json: "jsonb"
|
|
2079
2120
|
};
|
|
2121
|
+
// Maps @db.* attribute names to PostgreSQL SQL types for use in VALUES table casts
|
|
2122
|
+
static dbAttributeToSqlTypeMap = {
|
|
2123
|
+
"@db.Uuid": "uuid",
|
|
2124
|
+
"@db.Citext": "citext",
|
|
2125
|
+
"@db.Inet": "inet",
|
|
2126
|
+
"@db.Bit": "bit",
|
|
2127
|
+
"@db.VarBit": "varbit",
|
|
2128
|
+
"@db.Xml": "xml",
|
|
2129
|
+
"@db.Json": "json",
|
|
2130
|
+
"@db.JsonB": "jsonb",
|
|
2131
|
+
"@db.ByteA": "bytea",
|
|
2132
|
+
"@db.Text": "text",
|
|
2133
|
+
"@db.Char": "bpchar",
|
|
2134
|
+
"@db.VarChar": "varchar",
|
|
2135
|
+
"@db.Date": "date",
|
|
2136
|
+
"@db.Time": "time",
|
|
2137
|
+
"@db.Timetz": "timetz",
|
|
2138
|
+
"@db.Timestamp": "timestamp",
|
|
2139
|
+
"@db.Timestamptz": "timestamptz",
|
|
2140
|
+
"@db.SmallInt": "smallint",
|
|
2141
|
+
"@db.Integer": "integer",
|
|
2142
|
+
"@db.BigInt": "bigint",
|
|
2143
|
+
"@db.Real": "real",
|
|
2144
|
+
"@db.DoublePrecision": "double precision",
|
|
2145
|
+
"@db.Decimal": "decimal",
|
|
2146
|
+
"@db.Boolean": "boolean"
|
|
2147
|
+
};
|
|
2080
2148
|
constructor(schema, options) {
|
|
2081
2149
|
super(schema, options);
|
|
2082
2150
|
this.overrideTypeParsers();
|
|
@@ -2150,7 +2218,7 @@ var PostgresCrudDialect = class _PostgresCrudDialect extends LateralJoinDialectB
|
|
|
2150
2218
|
} else if (value instanceof DbNullClass) {
|
|
2151
2219
|
return null;
|
|
2152
2220
|
} else if (value instanceof AnyNullClass) {
|
|
2153
|
-
(0,
|
|
2221
|
+
(0, import_common_helpers6.invariant)(false, "should not reach here: AnyNull is not a valid input value");
|
|
2154
2222
|
}
|
|
2155
2223
|
if (isTypeDef(this.schema, type)) {
|
|
2156
2224
|
if (typeof value !== "string") {
|
|
@@ -2206,14 +2274,14 @@ var PostgresCrudDialect = class _PostgresCrudDialect extends LateralJoinDialectB
|
|
|
2206
2274
|
if (typeof value === "bigint") {
|
|
2207
2275
|
return value;
|
|
2208
2276
|
}
|
|
2209
|
-
(0,
|
|
2277
|
+
(0, import_common_helpers6.invariant)(typeof value === "string" || typeof value === "number", `Expected string or number, got ${typeof value}`);
|
|
2210
2278
|
return BigInt(value);
|
|
2211
2279
|
}
|
|
2212
2280
|
transformDecimal(value) {
|
|
2213
2281
|
if (value instanceof import_decimal2.default) {
|
|
2214
2282
|
return value;
|
|
2215
2283
|
}
|
|
2216
|
-
(0,
|
|
2284
|
+
(0, import_common_helpers6.invariant)(typeof value === "string" || typeof value === "number" || value instanceof import_decimal2.default, `Expected string, number or Decimal, got ${typeof value}`);
|
|
2217
2285
|
return new import_decimal2.default(value);
|
|
2218
2286
|
}
|
|
2219
2287
|
transformOutputDate(value) {
|
|
@@ -2341,13 +2409,55 @@ var PostgresCrudDialect = class _PostgresCrudDialect extends LateralJoinDialectB
|
|
|
2341
2409
|
receiver
|
|
2342
2410
|
]).as("$items")).select(this.eb.lit(1).as("_")).where(buildFilter(this.eb.ref("$items.value"))));
|
|
2343
2411
|
}
|
|
2344
|
-
getSqlType(zmodelType) {
|
|
2412
|
+
getSqlType(zmodelType, attributes) {
|
|
2413
|
+
if (attributes) {
|
|
2414
|
+
for (const attr of attributes) {
|
|
2415
|
+
const mapped = _PostgresCrudDialect.dbAttributeToSqlTypeMap[attr.name];
|
|
2416
|
+
if (mapped) {
|
|
2417
|
+
return mapped;
|
|
2418
|
+
}
|
|
2419
|
+
}
|
|
2420
|
+
}
|
|
2345
2421
|
if (isEnum(this.schema, zmodelType)) {
|
|
2346
2422
|
return "text";
|
|
2347
2423
|
} else {
|
|
2348
2424
|
return this.zmodelToSqlTypeMap[zmodelType] ?? "text";
|
|
2349
2425
|
}
|
|
2350
2426
|
}
|
|
2427
|
+
// Resolves the effective SQL type for a field: the native type from any @db.* attribute,
|
|
2428
|
+
// or the base ZModel SQL type if no attribute is present, or undefined if the field is unknown.
|
|
2429
|
+
resolveFieldSqlType(fieldDef) {
|
|
2430
|
+
if (!fieldDef) {
|
|
2431
|
+
return {
|
|
2432
|
+
sqlType: void 0,
|
|
2433
|
+
hasDbOverride: false
|
|
2434
|
+
};
|
|
2435
|
+
}
|
|
2436
|
+
const dbAttr = fieldDef.attributes?.find((a) => a.name.startsWith("@db."));
|
|
2437
|
+
if (dbAttr) {
|
|
2438
|
+
return {
|
|
2439
|
+
sqlType: _PostgresCrudDialect.dbAttributeToSqlTypeMap[dbAttr.name],
|
|
2440
|
+
hasDbOverride: true
|
|
2441
|
+
};
|
|
2442
|
+
}
|
|
2443
|
+
return {
|
|
2444
|
+
sqlType: this.getSqlType(fieldDef.type),
|
|
2445
|
+
hasDbOverride: false
|
|
2446
|
+
};
|
|
2447
|
+
}
|
|
2448
|
+
buildComparison(left, leftFieldDef, op, right, rightFieldDef) {
|
|
2449
|
+
const leftResolved = this.resolveFieldSqlType(leftFieldDef);
|
|
2450
|
+
const rightResolved = this.resolveFieldSqlType(rightFieldDef);
|
|
2451
|
+
if (leftResolved.sqlType !== rightResolved.sqlType && (leftResolved.hasDbOverride || rightResolved.hasDbOverride)) {
|
|
2452
|
+
if (leftResolved.hasDbOverride) {
|
|
2453
|
+
left = this.eb.cast(left, import_kysely4.sql.raw(this.getSqlType(leftFieldDef.type)));
|
|
2454
|
+
}
|
|
2455
|
+
if (rightResolved.hasDbOverride) {
|
|
2456
|
+
right = this.eb.cast(right, import_kysely4.sql.raw(this.getSqlType(rightFieldDef.type)));
|
|
2457
|
+
}
|
|
2458
|
+
}
|
|
2459
|
+
return super.buildComparison(left, leftFieldDef, op, right, rightFieldDef);
|
|
2460
|
+
}
|
|
2351
2461
|
getStringCasingBehavior() {
|
|
2352
2462
|
return {
|
|
2353
2463
|
supportsILike: true,
|
|
@@ -2369,7 +2479,7 @@ var PostgresCrudDialect = class _PostgresCrudDialect extends LateralJoinDialectB
|
|
|
2369
2479
|
}
|
|
2370
2480
|
const eb = (0, import_kysely4.expressionBuilder)();
|
|
2371
2481
|
return eb.selectFrom(import_kysely4.sql`(VALUES ${import_kysely4.sql.join(rows.map((row) => import_kysely4.sql`(${import_kysely4.sql.join(row.map((v) => import_kysely4.sql.val(v)))})`), import_kysely4.sql.raw(", "))})`.as("$values")).select(fields.map((f, i) => {
|
|
2372
|
-
const mappedType = this.getSqlType(f.type);
|
|
2482
|
+
const mappedType = this.getSqlType(f.type, f.attributes);
|
|
2373
2483
|
const castType = f.array ? import_kysely4.sql`${import_kysely4.sql.raw(mappedType)}[]` : import_kysely4.sql.raw(mappedType);
|
|
2374
2484
|
return this.eb.cast(import_kysely4.sql.ref(`$values.column${i + 1}`), castType).as(f.name);
|
|
2375
2485
|
}));
|
|
@@ -2384,7 +2494,7 @@ var PostgresCrudDialect = class _PostgresCrudDialect extends LateralJoinDialectB
|
|
|
2384
2494
|
};
|
|
2385
2495
|
|
|
2386
2496
|
// src/client/crud/dialects/sqlite.ts
|
|
2387
|
-
var
|
|
2497
|
+
var import_common_helpers7 = require("@zenstackhq/common-helpers");
|
|
2388
2498
|
var import_decimal3 = __toESM(require("decimal.js"), 1);
|
|
2389
2499
|
var import_kysely5 = require("kysely");
|
|
2390
2500
|
var SqliteCrudDialect = class extends BaseCrudDialect {
|
|
@@ -2427,7 +2537,7 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
|
|
|
2427
2537
|
} else if (value instanceof DbNullClass) {
|
|
2428
2538
|
return null;
|
|
2429
2539
|
} else if (value instanceof AnyNullClass) {
|
|
2430
|
-
(0,
|
|
2540
|
+
(0, import_common_helpers7.invariant)(false, "should not reach here: AnyNull is not a valid input value");
|
|
2431
2541
|
}
|
|
2432
2542
|
if (type === "Json" || this.schema.typeDefs && type in this.schema.typeDefs) {
|
|
2433
2543
|
return JSON.stringify(value);
|
|
@@ -2477,14 +2587,14 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
|
|
|
2477
2587
|
if (value instanceof import_decimal3.default) {
|
|
2478
2588
|
return value;
|
|
2479
2589
|
}
|
|
2480
|
-
(0,
|
|
2590
|
+
(0, import_common_helpers7.invariant)(typeof value === "string" || typeof value === "number" || value instanceof import_decimal3.default, `Expected string, number or Decimal, got ${typeof value}`);
|
|
2481
2591
|
return new import_decimal3.default(value);
|
|
2482
2592
|
}
|
|
2483
2593
|
transformOutputBigInt(value) {
|
|
2484
2594
|
if (typeof value === "bigint") {
|
|
2485
2595
|
return value;
|
|
2486
2596
|
}
|
|
2487
|
-
(0,
|
|
2597
|
+
(0, import_common_helpers7.invariant)(typeof value === "string" || typeof value === "number", `Expected string or number, got ${typeof value}`);
|
|
2488
2598
|
return BigInt(value);
|
|
2489
2599
|
}
|
|
2490
2600
|
transformOutputBoolean(value) {
|
|
@@ -2600,8 +2710,8 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
|
|
|
2600
2710
|
if (m2m) {
|
|
2601
2711
|
const parentIds = requireIdFields(this.schema, model);
|
|
2602
2712
|
const relationIds = requireIdFields(this.schema, relationModel);
|
|
2603
|
-
(0,
|
|
2604
|
-
(0,
|
|
2713
|
+
(0, import_common_helpers7.invariant)(parentIds.length === 1, "many-to-many relation must have exactly one id field");
|
|
2714
|
+
(0, import_common_helpers7.invariant)(relationIds.length === 1, "many-to-many relation must have exactly one id field");
|
|
2605
2715
|
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}`)));
|
|
2606
2716
|
} else {
|
|
2607
2717
|
const { keyPairs, ownedByModel } = getRelationForeignKeyFieldPairs(this.schema, model, relationField);
|
|
@@ -3034,7 +3144,7 @@ var BaseOperationHandler = class {
|
|
|
3034
3144
|
}
|
|
3035
3145
|
});
|
|
3036
3146
|
const discriminatorField = getDiscriminatorField(this.schema, model);
|
|
3037
|
-
(0,
|
|
3147
|
+
(0, import_common_helpers8.invariant)(discriminatorField, `Base model "${model}" must have a discriminator field`);
|
|
3038
3148
|
thisCreateFields[discriminatorField] = forModel;
|
|
3039
3149
|
const baseEntity = await this.create(kysely, model, thisCreateFields, void 0, true);
|
|
3040
3150
|
const idValues = extractIdFields(baseEntity, this.schema, model);
|
|
@@ -3046,8 +3156,8 @@ var BaseOperationHandler = class {
|
|
|
3046
3156
|
}
|
|
3047
3157
|
async buildFkAssignments(kysely, model, relationField, entity) {
|
|
3048
3158
|
const parentFkFields = {};
|
|
3049
|
-
(0,
|
|
3050
|
-
(0,
|
|
3159
|
+
(0, import_common_helpers8.invariant)(relationField, "parentField must be defined if parentModel is defined");
|
|
3160
|
+
(0, import_common_helpers8.invariant)(entity, "parentEntity must be defined if parentModel is defined");
|
|
3051
3161
|
const { keyPairs } = getRelationForeignKeyFieldPairs(this.schema, model, relationField);
|
|
3052
3162
|
for (const pair of keyPairs) {
|
|
3053
3163
|
if (!(pair.pk in entity)) {
|
|
@@ -3076,8 +3186,8 @@ var BaseOperationHandler = class {
|
|
|
3076
3186
|
const leftFirst = leftModel !== rightModel ? leftModel.localeCompare(rightModel) <= 0 : leftField.localeCompare(rightField) <= 0;
|
|
3077
3187
|
const leftIdField = requireIdFields(this.schema, leftModel);
|
|
3078
3188
|
const rightIdField = requireIdFields(this.schema, rightModel);
|
|
3079
|
-
(0,
|
|
3080
|
-
(0,
|
|
3189
|
+
(0, import_common_helpers8.invariant)(leftIdField.length === 1, "many-to-many relation must have exactly one id field");
|
|
3190
|
+
(0, import_common_helpers8.invariant)(rightIdField.length === 1, "many-to-many relation must have exactly one id field");
|
|
3081
3191
|
const leftIdValue = leftEntity[leftIdField[0]];
|
|
3082
3192
|
const rightIdValues = rightEntities.map((e) => e[rightIdField[0]]);
|
|
3083
3193
|
if (action === "connect") {
|
|
@@ -3102,10 +3212,10 @@ var BaseOperationHandler = class {
|
|
|
3102
3212
|
}
|
|
3103
3213
|
}
|
|
3104
3214
|
resetManyToManyRelation(kysely, model, field, parentIds) {
|
|
3105
|
-
(0,
|
|
3215
|
+
(0, import_common_helpers8.invariant)(Object.keys(parentIds).length === 1, "parentIds must have exactly one field");
|
|
3106
3216
|
const parentId = Object.values(parentIds)[0];
|
|
3107
3217
|
const m2m = getManyToManyRelation(this.schema, model, field);
|
|
3108
|
-
(0,
|
|
3218
|
+
(0, import_common_helpers8.invariant)(m2m, "not a many-to-many relation");
|
|
3109
3219
|
const eb = (0, import_kysely6.expressionBuilder)();
|
|
3110
3220
|
return kysely.deleteFrom(m2m.joinTable).where(eb(`${m2m.joinTable}.${m2m.parentFkName}`, "=", parentId)).execute();
|
|
3111
3221
|
}
|
|
@@ -3127,7 +3237,7 @@ var BaseOperationHandler = class {
|
|
|
3127
3237
|
}
|
|
3128
3238
|
case "connect": {
|
|
3129
3239
|
const referencedPkFields = relationField.relation.references;
|
|
3130
|
-
(0,
|
|
3240
|
+
(0, import_common_helpers8.invariant)(referencedPkFields, "relation must have fields info");
|
|
3131
3241
|
const extractedFks = extractFields(subPayload, referencedPkFields);
|
|
3132
3242
|
if (Object.keys(extractedFks).length === referencedPkFields.length) {
|
|
3133
3243
|
result = extractedFks;
|
|
@@ -3174,13 +3284,13 @@ var BaseOperationHandler = class {
|
|
|
3174
3284
|
}
|
|
3175
3285
|
switch (action) {
|
|
3176
3286
|
case "create": {
|
|
3177
|
-
for (const item of (0,
|
|
3287
|
+
for (const item of (0, import_common_helpers8.enumerate)(subPayload)) {
|
|
3178
3288
|
await this.create(kysely, relationModel, item, fromRelationContext);
|
|
3179
3289
|
}
|
|
3180
3290
|
break;
|
|
3181
3291
|
}
|
|
3182
3292
|
case "createMany": {
|
|
3183
|
-
(0,
|
|
3293
|
+
(0, import_common_helpers8.invariant)(relationFieldDef.array, "relation must be an array for createMany");
|
|
3184
3294
|
await this.createMany(kysely, relationModel, subPayload, false, fromRelationContext);
|
|
3185
3295
|
break;
|
|
3186
3296
|
}
|
|
@@ -3189,7 +3299,7 @@ var BaseOperationHandler = class {
|
|
|
3189
3299
|
break;
|
|
3190
3300
|
}
|
|
3191
3301
|
case "connectOrCreate": {
|
|
3192
|
-
for (const item of (0,
|
|
3302
|
+
for (const item of (0, import_common_helpers8.enumerate)(subPayload)) {
|
|
3193
3303
|
const found = await this.exists(kysely, relationModel, item.where);
|
|
3194
3304
|
if (!found) {
|
|
3195
3305
|
await this.create(kysely, relationModel, item.create, fromRelationContext);
|
|
@@ -3219,11 +3329,11 @@ var BaseOperationHandler = class {
|
|
|
3219
3329
|
}
|
|
3220
3330
|
relationKeyPairs.push(...keyPairs);
|
|
3221
3331
|
}
|
|
3222
|
-
let createData = (0,
|
|
3332
|
+
let createData = (0, import_common_helpers8.enumerate)(input.data).map((item) => {
|
|
3223
3333
|
const newItem = {};
|
|
3224
3334
|
for (const [name, value] of Object.entries(item)) {
|
|
3225
3335
|
const fieldDef = this.requireField(model, name);
|
|
3226
|
-
(0,
|
|
3336
|
+
(0, import_common_helpers8.invariant)(!fieldDef.relation, "createMany does not support relations");
|
|
3227
3337
|
newItem[name] = this.dialect.transformInput(value, fieldDef.type, !!fieldDef.array);
|
|
3228
3338
|
}
|
|
3229
3339
|
if (fromRelation) {
|
|
@@ -3286,7 +3396,7 @@ var BaseOperationHandler = class {
|
|
|
3286
3396
|
const thisCreateRows = [];
|
|
3287
3397
|
const remainingFieldRows = [];
|
|
3288
3398
|
const discriminatorField = getDiscriminatorField(this.schema, model);
|
|
3289
|
-
(0,
|
|
3399
|
+
(0, import_common_helpers8.invariant)(discriminatorField, `Base model "${model}" must have a discriminator field`);
|
|
3290
3400
|
for (const createFields of createRows) {
|
|
3291
3401
|
const thisCreateFields = {};
|
|
3292
3402
|
const remainingFields = {};
|
|
@@ -3325,7 +3435,7 @@ var BaseOperationHandler = class {
|
|
|
3325
3435
|
}
|
|
3326
3436
|
fillGeneratedAndDefaultValues(modelDef, data) {
|
|
3327
3437
|
const fields = modelDef.fields;
|
|
3328
|
-
const values = (0,
|
|
3438
|
+
const values = (0, import_common_helpers8.clone)(data);
|
|
3329
3439
|
for (const [field, fieldDef] of Object.entries(fields)) {
|
|
3330
3440
|
if (fieldDef.originModel) {
|
|
3331
3441
|
continue;
|
|
@@ -3397,7 +3507,7 @@ var BaseOperationHandler = class {
|
|
|
3397
3507
|
throw createInvalidInputError("data must be an object");
|
|
3398
3508
|
}
|
|
3399
3509
|
const parentWhere = await this.buildUpdateParentRelationFilter(kysely, fromRelation);
|
|
3400
|
-
let combinedWhere = where ??
|
|
3510
|
+
let combinedWhere = where ?? true;
|
|
3401
3511
|
if (Object.keys(parentWhere).length > 0) {
|
|
3402
3512
|
combinedWhere = Object.keys(combinedWhere).length > 0 ? {
|
|
3403
3513
|
AND: [
|
|
@@ -3416,7 +3526,7 @@ var BaseOperationHandler = class {
|
|
|
3416
3526
|
const hasNonIgnoredFields = Object.keys(data).some((field) => (isScalarField(this.schema, modelDef.name, field) || isForeignKeyField(this.schema, modelDef.name, field)) && !ignoredFields.has(field));
|
|
3417
3527
|
if (hasNonIgnoredFields) {
|
|
3418
3528
|
if (finalData === data) {
|
|
3419
|
-
finalData = (0,
|
|
3529
|
+
finalData = (0, import_common_helpers8.clone)(data);
|
|
3420
3530
|
}
|
|
3421
3531
|
finalData[fieldName] = this.dialect.transformInput(/* @__PURE__ */ new Date(), "DateTime", false);
|
|
3422
3532
|
autoUpdatedFields.push(fieldName);
|
|
@@ -3519,7 +3629,7 @@ var BaseOperationHandler = class {
|
|
|
3519
3629
|
const updatingIdFields = idFields.some((idField) => idField in updateFields);
|
|
3520
3630
|
if (updatingIdFields) {
|
|
3521
3631
|
const origIdValues = await loadThisEntity();
|
|
3522
|
-
(0,
|
|
3632
|
+
(0, import_common_helpers8.invariant)(origIdValues, "Original entity should have been loaded for update without RETURNING");
|
|
3523
3633
|
readFilter = {
|
|
3524
3634
|
...origIdValues
|
|
3525
3635
|
};
|
|
@@ -3578,7 +3688,7 @@ var BaseOperationHandler = class {
|
|
|
3578
3688
|
}
|
|
3579
3689
|
} else {
|
|
3580
3690
|
const fromRelationFieldDef = this.requireField(fromRelation.model, fromRelation.field);
|
|
3581
|
-
(0,
|
|
3691
|
+
(0, import_common_helpers8.invariant)(fromRelationFieldDef.relation?.opposite);
|
|
3582
3692
|
parentWhere[fromRelationFieldDef.relation.opposite] = {
|
|
3583
3693
|
some: fromRelation.ids
|
|
3584
3694
|
};
|
|
@@ -3629,7 +3739,7 @@ var BaseOperationHandler = class {
|
|
|
3629
3739
|
};
|
|
3630
3740
|
}
|
|
3631
3741
|
transformIncrementalUpdate(model, field, fieldDef, payload) {
|
|
3632
|
-
(0,
|
|
3742
|
+
(0, import_common_helpers8.invariant)(Object.keys(payload).length === 1, 'Only one of "set", "increment", "decrement", "multiply", or "divide" can be provided');
|
|
3633
3743
|
const key = Object.keys(payload)[0];
|
|
3634
3744
|
const value = this.dialect.transformInput(payload[key], fieldDef.type, false);
|
|
3635
3745
|
const eb = (0, import_kysely6.expressionBuilder)();
|
|
@@ -3639,7 +3749,7 @@ var BaseOperationHandler = class {
|
|
|
3639
3749
|
});
|
|
3640
3750
|
}
|
|
3641
3751
|
transformScalarListUpdate(model, field, fieldDef, payload) {
|
|
3642
|
-
(0,
|
|
3752
|
+
(0, import_common_helpers8.invariant)(Object.keys(payload).length === 1, 'Only one of "set", "push" can be provided');
|
|
3643
3753
|
const key = Object.keys(payload)[0];
|
|
3644
3754
|
const value = this.dialect.transformInput(payload[key], fieldDef.type, true);
|
|
3645
3755
|
const eb = (0, import_kysely6.expressionBuilder)();
|
|
@@ -3670,7 +3780,7 @@ var BaseOperationHandler = class {
|
|
|
3670
3780
|
throw createNotSupportedError("Updating with a limit is not supported for polymorphic models");
|
|
3671
3781
|
}
|
|
3672
3782
|
const parentWhere = await this.buildUpdateParentRelationFilter(kysely, fromRelation);
|
|
3673
|
-
let combinedWhere = where ??
|
|
3783
|
+
let combinedWhere = where ?? true;
|
|
3674
3784
|
if (Object.keys(parentWhere).length > 0) {
|
|
3675
3785
|
combinedWhere = Object.keys(combinedWhere).length > 0 ? {
|
|
3676
3786
|
AND: [
|
|
@@ -3799,14 +3909,14 @@ var BaseOperationHandler = class {
|
|
|
3799
3909
|
for (const [key, value] of Object.entries(args)) {
|
|
3800
3910
|
switch (key) {
|
|
3801
3911
|
case "create": {
|
|
3802
|
-
(0,
|
|
3803
|
-
for (const item of (0,
|
|
3912
|
+
(0, import_common_helpers8.invariant)(!Array.isArray(value) || fieldDef.array, "relation must be an array if create is an array");
|
|
3913
|
+
for (const item of (0, import_common_helpers8.enumerate)(value)) {
|
|
3804
3914
|
await this.create(kysely, fieldModel, item, fromRelationContext);
|
|
3805
3915
|
}
|
|
3806
3916
|
break;
|
|
3807
3917
|
}
|
|
3808
3918
|
case "createMany": {
|
|
3809
|
-
(0,
|
|
3919
|
+
(0, import_common_helpers8.invariant)(fieldDef.array, "relation must be an array for createMany");
|
|
3810
3920
|
await this.createMany(kysely, fieldModel, value, false, fromRelationContext);
|
|
3811
3921
|
break;
|
|
3812
3922
|
}
|
|
@@ -3823,12 +3933,12 @@ var BaseOperationHandler = class {
|
|
|
3823
3933
|
break;
|
|
3824
3934
|
}
|
|
3825
3935
|
case "set": {
|
|
3826
|
-
(0,
|
|
3936
|
+
(0, import_common_helpers8.invariant)(fieldDef.array, "relation must be an array");
|
|
3827
3937
|
await this.setRelation(kysely, fieldModel, value, fromRelationContext);
|
|
3828
3938
|
break;
|
|
3829
3939
|
}
|
|
3830
3940
|
case "update": {
|
|
3831
|
-
for (const _item of (0,
|
|
3941
|
+
for (const _item of (0, import_common_helpers8.enumerate)(value)) {
|
|
3832
3942
|
const item = _item;
|
|
3833
3943
|
let where;
|
|
3834
3944
|
let data;
|
|
@@ -3845,7 +3955,7 @@ var BaseOperationHandler = class {
|
|
|
3845
3955
|
break;
|
|
3846
3956
|
}
|
|
3847
3957
|
case "upsert": {
|
|
3848
|
-
for (const _item of (0,
|
|
3958
|
+
for (const _item of (0, import_common_helpers8.enumerate)(value)) {
|
|
3849
3959
|
const item = _item;
|
|
3850
3960
|
const updated = await this.update(kysely, fieldModel, item.where, item.update, fromRelationContext, true, false);
|
|
3851
3961
|
if (!updated) {
|
|
@@ -3855,18 +3965,18 @@ var BaseOperationHandler = class {
|
|
|
3855
3965
|
break;
|
|
3856
3966
|
}
|
|
3857
3967
|
case "updateMany": {
|
|
3858
|
-
for (const _item of (0,
|
|
3968
|
+
for (const _item of (0, import_common_helpers8.enumerate)(value)) {
|
|
3859
3969
|
const item = _item;
|
|
3860
3970
|
await this.updateMany(kysely, fieldModel, item.where, item.data, item.limit, false, fieldModel, fromRelationContext);
|
|
3861
3971
|
}
|
|
3862
3972
|
break;
|
|
3863
3973
|
}
|
|
3864
3974
|
case "delete": {
|
|
3865
|
-
await this.deleteRelation(kysely, fieldModel, value, fromRelationContext, true);
|
|
3975
|
+
await this.deleteRelation(kysely, fieldModel, value, fromRelationContext, true, true);
|
|
3866
3976
|
break;
|
|
3867
3977
|
}
|
|
3868
3978
|
case "deleteMany": {
|
|
3869
|
-
await this.deleteRelation(kysely, fieldModel, value, fromRelationContext, false);
|
|
3979
|
+
await this.deleteRelation(kysely, fieldModel, value, fromRelationContext, false, false);
|
|
3870
3980
|
break;
|
|
3871
3981
|
}
|
|
3872
3982
|
default: {
|
|
@@ -3892,7 +4002,7 @@ var BaseOperationHandler = class {
|
|
|
3892
4002
|
} else {
|
|
3893
4003
|
const { ownedByModel, keyPairs } = getRelationForeignKeyFieldPairs(this.schema, fromRelation.model, fromRelation.field);
|
|
3894
4004
|
if (ownedByModel) {
|
|
3895
|
-
(0,
|
|
4005
|
+
(0, import_common_helpers8.invariant)(_data.length === 1, "only one entity can be connected");
|
|
3896
4006
|
const target = await this.readUnique(kysely, model, {
|
|
3897
4007
|
where: _data[0]
|
|
3898
4008
|
});
|
|
@@ -3929,7 +4039,7 @@ var BaseOperationHandler = class {
|
|
|
3929
4039
|
}
|
|
3930
4040
|
}
|
|
3931
4041
|
async connectOrCreateRelation(kysely, model, data, fromRelation) {
|
|
3932
|
-
const _data = (0,
|
|
4042
|
+
const _data = (0, import_common_helpers8.enumerate)(data);
|
|
3933
4043
|
if (_data.length === 0) {
|
|
3934
4044
|
return;
|
|
3935
4045
|
}
|
|
@@ -3954,6 +4064,10 @@ var BaseOperationHandler = class {
|
|
|
3954
4064
|
true
|
|
3955
4065
|
];
|
|
3956
4066
|
}
|
|
4067
|
+
} else if (isEmptyObject(data)) {
|
|
4068
|
+
disconnectConditions = [
|
|
4069
|
+
true
|
|
4070
|
+
];
|
|
3957
4071
|
} else {
|
|
3958
4072
|
disconnectConditions = this.normalizeRelationManipulationInput(model, data);
|
|
3959
4073
|
if (disconnectConditions.length === 0) {
|
|
@@ -3973,7 +4087,7 @@ var BaseOperationHandler = class {
|
|
|
3973
4087
|
const { ownedByModel, keyPairs } = getRelationForeignKeyFieldPairs(this.schema, fromRelation.model, fromRelation.field);
|
|
3974
4088
|
const eb = (0, import_kysely6.expressionBuilder)();
|
|
3975
4089
|
if (ownedByModel) {
|
|
3976
|
-
(0,
|
|
4090
|
+
(0, import_common_helpers8.invariant)(disconnectConditions.length === 1, "only one entity can be disconnected");
|
|
3977
4091
|
const condition = disconnectConditions[0];
|
|
3978
4092
|
if (condition === true) {
|
|
3979
4093
|
for (const { fk } of keyPairs) {
|
|
@@ -4076,9 +4190,9 @@ var BaseOperationHandler = class {
|
|
|
4076
4190
|
}
|
|
4077
4191
|
}
|
|
4078
4192
|
}
|
|
4079
|
-
async deleteRelation(kysely, model, data, fromRelation, throwForNotFound) {
|
|
4193
|
+
async deleteRelation(kysely, model, data, fromRelation, uniqueDelete, throwForNotFound) {
|
|
4080
4194
|
let deleteConditions = [];
|
|
4081
|
-
let expectedDeleteCount;
|
|
4195
|
+
let expectedDeleteCount = -1;
|
|
4082
4196
|
if (typeof data === "boolean") {
|
|
4083
4197
|
if (data === false) {
|
|
4084
4198
|
return;
|
|
@@ -4086,6 +4200,15 @@ var BaseOperationHandler = class {
|
|
|
4086
4200
|
deleteConditions = [
|
|
4087
4201
|
true
|
|
4088
4202
|
];
|
|
4203
|
+
if (uniqueDelete) {
|
|
4204
|
+
expectedDeleteCount = 1;
|
|
4205
|
+
}
|
|
4206
|
+
}
|
|
4207
|
+
} else if (isEmptyObject(data)) {
|
|
4208
|
+
deleteConditions = [
|
|
4209
|
+
true
|
|
4210
|
+
];
|
|
4211
|
+
if (uniqueDelete) {
|
|
4089
4212
|
expectedDeleteCount = 1;
|
|
4090
4213
|
}
|
|
4091
4214
|
} else {
|
|
@@ -4093,7 +4216,9 @@ var BaseOperationHandler = class {
|
|
|
4093
4216
|
if (deleteConditions.length === 0) {
|
|
4094
4217
|
return;
|
|
4095
4218
|
}
|
|
4096
|
-
|
|
4219
|
+
if (uniqueDelete) {
|
|
4220
|
+
expectedDeleteCount = deleteConditions.length;
|
|
4221
|
+
}
|
|
4097
4222
|
}
|
|
4098
4223
|
let deleteResult;
|
|
4099
4224
|
let deleteFromModel;
|
|
@@ -4101,7 +4226,7 @@ var BaseOperationHandler = class {
|
|
|
4101
4226
|
if (m2m) {
|
|
4102
4227
|
deleteFromModel = model;
|
|
4103
4228
|
const fieldDef = this.requireField(fromRelation.model, fromRelation.field);
|
|
4104
|
-
(0,
|
|
4229
|
+
(0, import_common_helpers8.invariant)(fieldDef.relation?.opposite);
|
|
4105
4230
|
deleteResult = await this.delete(kysely, model, {
|
|
4106
4231
|
AND: [
|
|
4107
4232
|
{
|
|
@@ -4125,7 +4250,7 @@ var BaseOperationHandler = class {
|
|
|
4125
4250
|
throw createNotFoundError(fromRelation.model);
|
|
4126
4251
|
}
|
|
4127
4252
|
const fieldDef = this.requireField(fromRelation.model, fromRelation.field);
|
|
4128
|
-
(0,
|
|
4253
|
+
(0, import_common_helpers8.invariant)(fieldDef.relation?.opposite);
|
|
4129
4254
|
deleteResult = await this.delete(kysely, model, {
|
|
4130
4255
|
AND: [
|
|
4131
4256
|
// filter for parent
|
|
@@ -4153,12 +4278,12 @@ var BaseOperationHandler = class {
|
|
|
4153
4278
|
});
|
|
4154
4279
|
}
|
|
4155
4280
|
}
|
|
4156
|
-
if (throwForNotFound && expectedDeleteCount > (deleteResult.numAffectedRows ?? 0)) {
|
|
4281
|
+
if (throwForNotFound && expectedDeleteCount >= 0 && expectedDeleteCount > (deleteResult.numAffectedRows ?? 0)) {
|
|
4157
4282
|
throw createNotFoundError(deleteFromModel);
|
|
4158
4283
|
}
|
|
4159
4284
|
}
|
|
4160
4285
|
normalizeRelationManipulationInput(model, data) {
|
|
4161
|
-
return (0,
|
|
4286
|
+
return (0, import_common_helpers8.enumerate)(data).map((item) => flattenCompoundUniqueFilters(this.schema, model, item));
|
|
4162
4287
|
}
|
|
4163
4288
|
// #endregion
|
|
4164
4289
|
async delete(kysely, model, where, limit, filterModel, fieldsToReturn) {
|
|
@@ -4279,7 +4404,7 @@ var BaseOperationHandler = class {
|
|
|
4279
4404
|
if (!args) {
|
|
4280
4405
|
return;
|
|
4281
4406
|
}
|
|
4282
|
-
const newArgs = (0,
|
|
4407
|
+
const newArgs = (0, import_common_helpers8.clone)(args);
|
|
4283
4408
|
this.doNormalizeArgs(newArgs);
|
|
4284
4409
|
return newArgs;
|
|
4285
4410
|
}
|
|
@@ -4288,7 +4413,7 @@ var BaseOperationHandler = class {
|
|
|
4288
4413
|
for (const [key, value] of Object.entries(args)) {
|
|
4289
4414
|
if (value === void 0) {
|
|
4290
4415
|
delete args[key];
|
|
4291
|
-
} else if (value && (0,
|
|
4416
|
+
} else if (value && (0, import_common_helpers8.isPlainObject)(value)) {
|
|
4292
4417
|
this.doNormalizeArgs(value);
|
|
4293
4418
|
}
|
|
4294
4419
|
}
|
|
@@ -4922,11 +5047,11 @@ var UpdateOperationHandler = class extends BaseOperationHandler {
|
|
|
4922
5047
|
};
|
|
4923
5048
|
|
|
4924
5049
|
// src/client/crud/validator/validator.ts
|
|
4925
|
-
var
|
|
5050
|
+
var import_common_helpers10 = require("@zenstackhq/common-helpers");
|
|
4926
5051
|
var import_ts_pattern11 = require("ts-pattern");
|
|
4927
5052
|
|
|
4928
5053
|
// src/client/zod/factory.ts
|
|
4929
|
-
var
|
|
5054
|
+
var import_common_helpers9 = require("@zenstackhq/common-helpers");
|
|
4930
5055
|
var import_zod = require("@zenstackhq/zod");
|
|
4931
5056
|
var import_decimal4 = __toESM(require("decimal.js"), 1);
|
|
4932
5057
|
var import_ts_pattern10 = require("ts-pattern");
|
|
@@ -5121,12 +5246,12 @@ var ZodSchemaFactory = class {
|
|
|
5121
5246
|
}
|
|
5122
5247
|
makeEnumSchema(_enum) {
|
|
5123
5248
|
const enumDef = getEnum(this.schema, _enum);
|
|
5124
|
-
(0,
|
|
5249
|
+
(0, import_common_helpers9.invariant)(enumDef, `Enum "${_enum}" not found in schema`);
|
|
5125
5250
|
return import_zod2.z.enum(Object.keys(enumDef.values));
|
|
5126
5251
|
}
|
|
5127
5252
|
makeTypeDefSchema(type) {
|
|
5128
5253
|
const typeDef = getTypeDef(this.schema, type);
|
|
5129
|
-
(0,
|
|
5254
|
+
(0, import_common_helpers9.invariant)(typeDef, `Type definition "${type}" not found in schema`);
|
|
5130
5255
|
const schema = import_zod2.z.looseObject(Object.fromEntries(Object.entries(typeDef.fields).map(([field, def]) => {
|
|
5131
5256
|
let fieldSchema = this.makeScalarSchema(def.type);
|
|
5132
5257
|
if (def.array) {
|
|
@@ -5210,7 +5335,7 @@ var ZodSchemaFactory = class {
|
|
|
5210
5335
|
for (const uniqueField of uniqueFields) {
|
|
5211
5336
|
if ("defs" in uniqueField) {
|
|
5212
5337
|
fields[uniqueField.name] = import_zod2.z.object(Object.fromEntries(Object.entries(uniqueField.defs).map(([key, def]) => {
|
|
5213
|
-
(0,
|
|
5338
|
+
(0, import_common_helpers9.invariant)(!def.relation, "unique field cannot be a relation");
|
|
5214
5339
|
let fieldSchema;
|
|
5215
5340
|
const enumDef = getEnum(this.schema, def.type);
|
|
5216
5341
|
if (enumDef) {
|
|
@@ -5261,7 +5386,7 @@ var ZodSchemaFactory = class {
|
|
|
5261
5386
|
const optional = !!fieldInfo.optional;
|
|
5262
5387
|
const array = !!fieldInfo.array;
|
|
5263
5388
|
const typeDef = getTypeDef(this.schema, type);
|
|
5264
|
-
(0,
|
|
5389
|
+
(0, import_common_helpers9.invariant)(typeDef, `Type definition "${type}" not found in schema`);
|
|
5265
5390
|
const candidates = [];
|
|
5266
5391
|
if (!array) {
|
|
5267
5392
|
const fieldSchemas = {};
|
|
@@ -5313,7 +5438,7 @@ var ZodSchemaFactory = class {
|
|
|
5313
5438
|
const optional = !!fieldInfo.optional;
|
|
5314
5439
|
const array = !!fieldInfo.array;
|
|
5315
5440
|
const enumDef = getEnum(this.schema, enumName);
|
|
5316
|
-
(0,
|
|
5441
|
+
(0, import_common_helpers9.invariant)(enumDef, `Enum "${enumName}" not found in schema`);
|
|
5317
5442
|
const baseSchema = import_zod2.z.enum(Object.keys(enumDef.values));
|
|
5318
5443
|
if (array) {
|
|
5319
5444
|
return this.internalMakeArrayFilterSchema(model, fieldInfo.name, baseSchema);
|
|
@@ -5606,7 +5731,7 @@ var ZodSchemaFactory = class {
|
|
|
5606
5731
|
for (const plugin of this.plugins) {
|
|
5607
5732
|
const resultConfig = plugin.result;
|
|
5608
5733
|
if (resultConfig) {
|
|
5609
|
-
const modelConfig = resultConfig[(0,
|
|
5734
|
+
const modelConfig = resultConfig[(0, import_common_helpers9.lowerCaseFirst)(model)];
|
|
5610
5735
|
if (modelConfig) {
|
|
5611
5736
|
for (const field of Object.keys(modelConfig)) {
|
|
5612
5737
|
fields[field] = import_zod2.z.boolean().optional();
|
|
@@ -6149,7 +6274,7 @@ var ZodSchemaFactory = class {
|
|
|
6149
6274
|
});
|
|
6150
6275
|
let schema = this.mergePluginArgsSchema(baseSchema, "groupBy");
|
|
6151
6276
|
schema = schema.refine((value) => {
|
|
6152
|
-
const bys = (0,
|
|
6277
|
+
const bys = (0, import_common_helpers9.enumerate)(value.by);
|
|
6153
6278
|
if (value.having && typeof value.having === "object") {
|
|
6154
6279
|
for (const [key, val] of Object.entries(value.having)) {
|
|
6155
6280
|
if (AggregateOperators.includes(key)) {
|
|
@@ -6169,8 +6294,8 @@ var ZodSchemaFactory = class {
|
|
|
6169
6294
|
return true;
|
|
6170
6295
|
}, 'fields in "having" must be in "by"');
|
|
6171
6296
|
schema = schema.refine((value) => {
|
|
6172
|
-
const bys = (0,
|
|
6173
|
-
for (const orderBy of (0,
|
|
6297
|
+
const bys = (0, import_common_helpers9.enumerate)(value.by);
|
|
6298
|
+
for (const orderBy of (0, import_common_helpers9.enumerate)(value.orderBy)) {
|
|
6174
6299
|
if (orderBy && Object.keys(orderBy).filter((f) => !AggregateOperators.includes(f)).some((key) => !bys.includes(key))) {
|
|
6175
6300
|
return false;
|
|
6176
6301
|
}
|
|
@@ -6185,7 +6310,7 @@ var ZodSchemaFactory = class {
|
|
|
6185
6310
|
continue;
|
|
6186
6311
|
}
|
|
6187
6312
|
if (LOGICAL_COMBINATORS.includes(key)) {
|
|
6188
|
-
if ((0,
|
|
6313
|
+
if ((0, import_common_helpers9.enumerate)(value).every((v) => this.onlyAggregationFields(v))) {
|
|
6189
6314
|
continue;
|
|
6190
6315
|
}
|
|
6191
6316
|
}
|
|
@@ -6245,8 +6370,8 @@ var ZodSchemaFactory = class {
|
|
|
6245
6370
|
const createSchema = "$create" in plugin.queryArgs && plugin.queryArgs["$create"] ? plugin.queryArgs["$create"] : void 0;
|
|
6246
6371
|
const updateSchema = "$update" in plugin.queryArgs && plugin.queryArgs["$update"] ? plugin.queryArgs["$update"] : void 0;
|
|
6247
6372
|
if (createSchema && updateSchema) {
|
|
6248
|
-
(0,
|
|
6249
|
-
(0,
|
|
6373
|
+
(0, import_common_helpers9.invariant)(createSchema instanceof import_zod2.ZodObject, "Plugin extended query args schema must be a Zod object");
|
|
6374
|
+
(0, import_common_helpers9.invariant)(updateSchema instanceof import_zod2.ZodObject, "Plugin extended query args schema must be a Zod object");
|
|
6250
6375
|
result = createSchema.extend(updateSchema.shape);
|
|
6251
6376
|
} else if (createSchema) {
|
|
6252
6377
|
result = createSchema;
|
|
@@ -6267,7 +6392,7 @@ var ZodSchemaFactory = class {
|
|
|
6267
6392
|
} else if ("$all" in plugin.queryArgs && plugin.queryArgs["$all"]) {
|
|
6268
6393
|
result = plugin.queryArgs["$all"];
|
|
6269
6394
|
}
|
|
6270
|
-
(0,
|
|
6395
|
+
(0, import_common_helpers9.invariant)(result === void 0 || result instanceof import_zod2.ZodObject, "Plugin extended query args schema must be a Zod object");
|
|
6271
6396
|
return result;
|
|
6272
6397
|
}
|
|
6273
6398
|
// #endregion
|
|
@@ -6321,7 +6446,7 @@ var ZodSchemaFactory = class {
|
|
|
6321
6446
|
return void 0;
|
|
6322
6447
|
}
|
|
6323
6448
|
const modelsRecord = slicing.models;
|
|
6324
|
-
const modelConfig = modelsRecord[(0,
|
|
6449
|
+
const modelConfig = modelsRecord[(0, import_common_helpers9.lowerCaseFirst)(model)];
|
|
6325
6450
|
if (modelConfig?.fields) {
|
|
6326
6451
|
const fieldConfig = modelConfig.fields[field];
|
|
6327
6452
|
if (fieldConfig) {
|
|
@@ -6928,7 +7053,7 @@ var InputValidator = class {
|
|
|
6928
7053
|
return input;
|
|
6929
7054
|
}
|
|
6930
7055
|
const procDef = (this.client.$schema.procedures ?? {})[proc];
|
|
6931
|
-
(0,
|
|
7056
|
+
(0, import_common_helpers10.invariant)(procDef, `Procedure "${proc}" not found in schema`);
|
|
6932
7057
|
const params = Object.values(procDef.params ?? {});
|
|
6933
7058
|
if (typeof input === "undefined") {
|
|
6934
7059
|
if (params.length === 0) {
|
|
@@ -7189,12 +7314,12 @@ function performanceNow() {
|
|
|
7189
7314
|
__name(performanceNow, "performanceNow");
|
|
7190
7315
|
|
|
7191
7316
|
// src/client/executor/zenstack-query-executor.ts
|
|
7192
|
-
var
|
|
7317
|
+
var import_common_helpers12 = require("@zenstackhq/common-helpers");
|
|
7193
7318
|
var import_kysely9 = require("kysely");
|
|
7194
7319
|
var import_ts_pattern12 = require("ts-pattern");
|
|
7195
7320
|
|
|
7196
7321
|
// src/client/executor/name-mapper.ts
|
|
7197
|
-
var
|
|
7322
|
+
var import_common_helpers11 = require("@zenstackhq/common-helpers");
|
|
7198
7323
|
var import_kysely7 = require("kysely");
|
|
7199
7324
|
var QueryNameMapper = class extends import_kysely7.OperationNodeTransformer {
|
|
7200
7325
|
static {
|
|
@@ -7267,7 +7392,7 @@ var QueryNameMapper = class extends import_kysely7.OperationNodeTransformer {
|
|
|
7267
7392
|
return super.transformInsertQuery(node, queryId);
|
|
7268
7393
|
}
|
|
7269
7394
|
const model = extractModelName(node.into);
|
|
7270
|
-
(0,
|
|
7395
|
+
(0, import_common_helpers11.invariant)(model, 'InsertQueryNode must have a model name in the "into" clause');
|
|
7271
7396
|
return this.withScope({
|
|
7272
7397
|
model
|
|
7273
7398
|
}, () => {
|
|
@@ -7350,7 +7475,7 @@ var QueryNameMapper = class extends import_kysely7.OperationNodeTransformer {
|
|
|
7350
7475
|
return super.transformUpdateQuery(node);
|
|
7351
7476
|
}
|
|
7352
7477
|
const model = extractModelName(innerTable);
|
|
7353
|
-
(0,
|
|
7478
|
+
(0, import_common_helpers11.invariant)(model, 'UpdateQueryNode must have a model name in the "table" clause');
|
|
7354
7479
|
return this.withScope({
|
|
7355
7480
|
model,
|
|
7356
7481
|
alias
|
|
@@ -7654,7 +7779,7 @@ var QueryNameMapper = class extends import_kysely7.OperationNodeTransformer {
|
|
|
7654
7779
|
}
|
|
7655
7780
|
requireCurrentScope() {
|
|
7656
7781
|
const scope = this.scopes[this.scopes.length - 1];
|
|
7657
|
-
(0,
|
|
7782
|
+
(0, import_common_helpers11.invariant)(scope, "No scope available");
|
|
7658
7783
|
return scope;
|
|
7659
7784
|
}
|
|
7660
7785
|
// #endregion
|
|
@@ -8121,7 +8246,7 @@ In such cases, ZenStack cannot reliably determine the IDs of the mutated entitie
|
|
|
8121
8246
|
for (const valuesItem of values.values) {
|
|
8122
8247
|
const rowIds = {};
|
|
8123
8248
|
if (import_kysely9.PrimitiveValueListNode.is(valuesItem)) {
|
|
8124
|
-
(0,
|
|
8249
|
+
(0, import_common_helpers12.invariant)(valuesItem.values.length === columns.length, "Values count must match columns count");
|
|
8125
8250
|
for (const idField of idFields) {
|
|
8126
8251
|
const colIndex = columns.findIndex((col) => col.column.name === idField);
|
|
8127
8252
|
if (colIndex === -1) {
|
|
@@ -8130,7 +8255,7 @@ In such cases, ZenStack cannot reliably determine the IDs of the mutated entitie
|
|
|
8130
8255
|
rowIds[idField] = valuesItem.values[colIndex];
|
|
8131
8256
|
}
|
|
8132
8257
|
} else {
|
|
8133
|
-
(0,
|
|
8258
|
+
(0, import_common_helpers12.invariant)(valuesItem.values.length === columns.length, "Values count must match columns count");
|
|
8134
8259
|
for (const idField of idFields) {
|
|
8135
8260
|
const colIndex = columns.findIndex((col) => col.column.name === idField);
|
|
8136
8261
|
if (colIndex === -1) {
|
|
@@ -8187,17 +8312,17 @@ In such cases, ZenStack cannot reliably determine the IDs of the mutated entitie
|
|
|
8187
8312
|
}
|
|
8188
8313
|
getMutationModel(queryNode) {
|
|
8189
8314
|
return (0, import_ts_pattern12.match)(queryNode).when(import_kysely9.InsertQueryNode.is, (node) => {
|
|
8190
|
-
(0,
|
|
8315
|
+
(0, import_common_helpers12.invariant)(node.into, "InsertQueryNode must have an into clause");
|
|
8191
8316
|
return node.into.table.identifier.name;
|
|
8192
8317
|
}).when(import_kysely9.UpdateQueryNode.is, (node) => {
|
|
8193
|
-
(0,
|
|
8318
|
+
(0, import_common_helpers12.invariant)(node.table, "UpdateQueryNode must have a table");
|
|
8194
8319
|
const { node: tableNode } = stripAlias(node.table);
|
|
8195
|
-
(0,
|
|
8320
|
+
(0, import_common_helpers12.invariant)(import_kysely9.TableNode.is(tableNode), "UpdateQueryNode must use a TableNode");
|
|
8196
8321
|
return tableNode.table.identifier.name;
|
|
8197
8322
|
}).when(import_kysely9.DeleteQueryNode.is, (node) => {
|
|
8198
|
-
(0,
|
|
8323
|
+
(0, import_common_helpers12.invariant)(node.from.froms.length === 1, "Delete query must have exactly one from table");
|
|
8199
8324
|
const { node: tableNode } = stripAlias(node.from.froms[0]);
|
|
8200
|
-
(0,
|
|
8325
|
+
(0, import_common_helpers12.invariant)(import_kysely9.TableNode.is(tableNode), "DeleteQueryNode must use a TableNode");
|
|
8201
8326
|
return tableNode.table.identifier.name;
|
|
8202
8327
|
}).otherwise((node) => {
|
|
8203
8328
|
throw createInternalError(`Invalid query node: ${node}`);
|
|
@@ -8342,7 +8467,7 @@ __export(functions_exports, {
|
|
|
8342
8467
|
search: () => search,
|
|
8343
8468
|
startsWith: () => startsWith
|
|
8344
8469
|
});
|
|
8345
|
-
var
|
|
8470
|
+
var import_common_helpers13 = require("@zenstackhq/common-helpers");
|
|
8346
8471
|
var import_kysely10 = require("kysely");
|
|
8347
8472
|
var import_ts_pattern13 = require("ts-pattern");
|
|
8348
8473
|
var contains = /* @__PURE__ */ __name((eb, args, context) => textMatch(eb, args, context, "contains"), "contains");
|
|
@@ -8452,8 +8577,8 @@ var currentOperation = /* @__PURE__ */ __name((_eb, args, { operation }) => {
|
|
|
8452
8577
|
}, "currentOperation");
|
|
8453
8578
|
function processCasing(casing, result, model) {
|
|
8454
8579
|
const opNode = casing.toOperationNode();
|
|
8455
|
-
(0,
|
|
8456
|
-
result = (0, import_ts_pattern13.match)(opNode.value).with("original", () => model).with("upper", () => result.toUpperCase()).with("lower", () => result.toLowerCase()).with("capitalize", () => (0,
|
|
8580
|
+
(0, import_common_helpers13.invariant)(import_kysely10.ValueNode.is(opNode) && typeof opNode.value === "string", '"casting" parameter must be a string value');
|
|
8581
|
+
result = (0, import_ts_pattern13.match)(opNode.value).with("original", () => model).with("upper", () => result.toUpperCase()).with("lower", () => result.toLowerCase()).with("capitalize", () => (0, import_common_helpers13.upperCaseFirst)(result)).with("uncapitalize", () => (0, import_common_helpers13.lowerCaseFirst)(result)).otherwise(() => {
|
|
8457
8582
|
throw new Error(`Invalid casing value: ${opNode.value}. Must be "original", "upper", "lower", "capitalize", or "uncapitalize".`);
|
|
8458
8583
|
});
|
|
8459
8584
|
return result;
|
|
@@ -8464,13 +8589,13 @@ function readBoolean(expr, defaultValue) {
|
|
|
8464
8589
|
return defaultValue;
|
|
8465
8590
|
}
|
|
8466
8591
|
const opNode = expr.toOperationNode();
|
|
8467
|
-
(0,
|
|
8592
|
+
(0, import_common_helpers13.invariant)(import_kysely10.ValueNode.is(opNode), "expression must be a literal value");
|
|
8468
8593
|
return !!opNode.value;
|
|
8469
8594
|
}
|
|
8470
8595
|
__name(readBoolean, "readBoolean");
|
|
8471
8596
|
|
|
8472
8597
|
// src/client/helpers/schema-db-pusher.ts
|
|
8473
|
-
var
|
|
8598
|
+
var import_common_helpers14 = require("@zenstackhq/common-helpers");
|
|
8474
8599
|
var import_kysely11 = require("kysely");
|
|
8475
8600
|
var import_toposort = __toESM(require("toposort"), 1);
|
|
8476
8601
|
var import_ts_pattern14 = require("ts-pattern");
|
|
@@ -8496,7 +8621,7 @@ var SchemaDbPusher = class {
|
|
|
8496
8621
|
return f.name;
|
|
8497
8622
|
} else {
|
|
8498
8623
|
const mappedName = schema_exports.ExpressionUtils.getLiteralValue(mapAttr.args[0].value);
|
|
8499
|
-
(0,
|
|
8624
|
+
(0, import_common_helpers14.invariant)(mappedName && typeof mappedName === "string", `Invalid @map attribute for enum field ${f.name}`);
|
|
8500
8625
|
return mappedName;
|
|
8501
8626
|
}
|
|
8502
8627
|
});
|
|
@@ -8623,7 +8748,7 @@ var SchemaDbPusher = class {
|
|
|
8623
8748
|
}
|
|
8624
8749
|
addUniqueConstraint(table, modelDef) {
|
|
8625
8750
|
for (const [key, value] of Object.entries(modelDef.uniqueFields)) {
|
|
8626
|
-
(0,
|
|
8751
|
+
(0, import_common_helpers14.invariant)(typeof value === "object", "expecting an object");
|
|
8627
8752
|
if ("type" in value) {
|
|
8628
8753
|
const fieldDef = modelDef.fields[key];
|
|
8629
8754
|
if (fieldDef.unique) {
|
|
@@ -8698,7 +8823,7 @@ var SchemaDbPusher = class {
|
|
|
8698
8823
|
return f.name;
|
|
8699
8824
|
} else {
|
|
8700
8825
|
const mappedName = schema_exports.ExpressionUtils.getLiteralValue(mapAttr.args[0].value);
|
|
8701
|
-
(0,
|
|
8826
|
+
(0, import_common_helpers14.invariant)(mappedName && typeof mappedName === "string", `Invalid @map attribute for enum field ${f.name}`);
|
|
8702
8827
|
return mappedName;
|
|
8703
8828
|
}
|
|
8704
8829
|
});
|
|
@@ -8733,7 +8858,7 @@ var SchemaDbPusher = class {
|
|
|
8733
8858
|
return fieldDef.default && schema_exports.ExpressionUtils.isCall(fieldDef.default) && fieldDef.default.function === "autoincrement";
|
|
8734
8859
|
}
|
|
8735
8860
|
addForeignKeyConstraint(table, model, fieldName, fieldDef) {
|
|
8736
|
-
(0,
|
|
8861
|
+
(0, import_common_helpers14.invariant)(fieldDef.relation, "field must be a relation");
|
|
8737
8862
|
if (!fieldDef.relation.fields || !fieldDef.relation.references) {
|
|
8738
8863
|
return table;
|
|
8739
8864
|
}
|
|
@@ -9054,7 +9179,7 @@ var ClientImpl = class _ClientImpl {
|
|
|
9054
9179
|
for (const [modelName, modelDef] of Object.entries(this.$schema.models)) {
|
|
9055
9180
|
if (modelDef.computedFields) {
|
|
9056
9181
|
for (const fieldName of Object.keys(modelDef.computedFields)) {
|
|
9057
|
-
const modelConfig = computedFieldsConfig?.[(0,
|
|
9182
|
+
const modelConfig = computedFieldsConfig?.[(0, import_common_helpers15.lowerCaseFirst)(modelName)] ?? computedFieldsConfig?.[modelName];
|
|
9058
9183
|
const fieldConfig = modelConfig?.[fieldName];
|
|
9059
9184
|
if (fieldConfig === null || fieldConfig === void 0) {
|
|
9060
9185
|
throw createConfigError(`Computed field "${fieldName}" in model "${modelName}" does not have a configuration. Please provide an implementation in the computedFields option.`);
|
|
@@ -9086,7 +9211,7 @@ var ClientImpl = class _ClientImpl {
|
|
|
9086
9211
|
}
|
|
9087
9212
|
// implementation
|
|
9088
9213
|
async $transaction(input, options) {
|
|
9089
|
-
(0,
|
|
9214
|
+
(0, import_common_helpers15.invariant)(typeof input === "function" || Array.isArray(input) && input.every((p) => p.then && p.cb), "Invalid transaction input, expected a function or an array of ZenStackPromise");
|
|
9090
9215
|
if (typeof input === "function") {
|
|
9091
9216
|
return this.interactiveTransaction(input, options);
|
|
9092
9217
|
} else {
|
|
@@ -9485,7 +9610,7 @@ function createModelCrudHandler(client, model, inputValidator, resultProcessor)
|
|
|
9485
9610
|
};
|
|
9486
9611
|
const slicing = client.$options.slicing;
|
|
9487
9612
|
if (slicing?.models) {
|
|
9488
|
-
const modelSlicing = slicing.models[(0,
|
|
9613
|
+
const modelSlicing = slicing.models[(0, import_common_helpers15.lowerCaseFirst)(model)];
|
|
9489
9614
|
const allSlicing = slicing.models.$all;
|
|
9490
9615
|
const includedOperations = modelSlicing?.includedOperations ?? allSlicing?.includedOperations;
|
|
9491
9616
|
const excludedOperations = modelSlicing?.excludedOperations ?? allSlicing?.excludedOperations;
|
|
@@ -9536,7 +9661,7 @@ function collectExtResultFieldDefs(model, schema, plugins) {
|
|
|
9536
9661
|
for (const plugin of plugins) {
|
|
9537
9662
|
const resultConfig = plugin.result;
|
|
9538
9663
|
if (resultConfig) {
|
|
9539
|
-
const modelConfig = resultConfig[(0,
|
|
9664
|
+
const modelConfig = resultConfig[(0, import_common_helpers15.lowerCaseFirst)(model)];
|
|
9540
9665
|
if (modelConfig) {
|
|
9541
9666
|
for (const [fieldName, fieldDef] of Object.entries(modelConfig)) {
|
|
9542
9667
|
if (getField(schema, model, fieldName)) {
|