prisma-guard 1.15.0 → 1.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/generator/index.js +7 -13
- package/dist/generator/index.js.map +1 -1
- package/dist/runtime/index.cjs +189 -46
- package/dist/runtime/index.cjs.map +1 -1
- package/dist/runtime/index.js +189 -46
- package/dist/runtime/index.js.map +1 -1
- package/package.json +1 -1
package/dist/runtime/index.cjs
CHANGED
|
@@ -115,10 +115,7 @@ function isJsonSafe(value) {
|
|
|
115
115
|
return true;
|
|
116
116
|
}
|
|
117
117
|
var DECIMAL_REGEX = /^-?(\d+\.?\d*|\.\d+)([eE]-?\d+)?$/;
|
|
118
|
-
var decimalStringSchema = import_zod.z.string().refine(
|
|
119
|
-
(s) => DECIMAL_REGEX.test(s),
|
|
120
|
-
"Invalid decimal string"
|
|
121
|
-
);
|
|
118
|
+
var decimalStringSchema = import_zod.z.string().refine((s) => DECIMAL_REGEX.test(s), "Invalid decimal string");
|
|
122
119
|
var decimalObjectSchema = import_zod.z.custom(
|
|
123
120
|
(v) => v !== null && typeof v === "object" && typeof v.toFixed === "function" && typeof v.toNumber === "function",
|
|
124
121
|
"Expected Decimal-compatible object"
|
|
@@ -144,18 +141,39 @@ function createScalarBase(strictDecimal) {
|
|
|
144
141
|
import_zod.z.string().regex(/^-?\d+$/).transform((v) => BigInt(v))
|
|
145
142
|
]),
|
|
146
143
|
Boolean: () => import_zod.z.boolean(),
|
|
147
|
-
DateTime: () => import_zod.z.union([
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
Bytes: () => import_zod.z.union([
|
|
153
|
-
import_zod.z.string(),
|
|
154
|
-
import_zod.z.custom((v) => v instanceof Uint8Array)
|
|
155
|
-
])
|
|
144
|
+
DateTime: () => import_zod.z.union([import_zod.z.date(), import_zod.z.string().datetime({ offset: true })]).pipe(import_zod.z.coerce.date()),
|
|
145
|
+
Json: () => import_zod.z.unknown().refine(
|
|
146
|
+
isJsonSafe,
|
|
147
|
+
"Value must be JSON-serializable (no undefined, functions, symbols, class instances, NaN, Infinity, or circular references)"
|
|
148
|
+
),
|
|
149
|
+
Bytes: () => import_zod.z.union([import_zod.z.string(), import_zod.z.custom((v) => v instanceof Uint8Array)])
|
|
156
150
|
};
|
|
157
151
|
}
|
|
158
152
|
var SCALAR_BASE = createScalarBase(false);
|
|
153
|
+
function wrapWithInputCoercion(fieldType, isList, schema) {
|
|
154
|
+
let itemCoercion = null;
|
|
155
|
+
switch (fieldType) {
|
|
156
|
+
case "String":
|
|
157
|
+
itemCoercion = import_zod.z.union([import_zod.z.string(), import_zod.z.number().transform(String)]);
|
|
158
|
+
break;
|
|
159
|
+
case "Int":
|
|
160
|
+
itemCoercion = import_zod.z.union([
|
|
161
|
+
import_zod.z.number().int(),
|
|
162
|
+
import_zod.z.string().regex(/^-?\d+$/).transform(Number)
|
|
163
|
+
]);
|
|
164
|
+
break;
|
|
165
|
+
case "Float":
|
|
166
|
+
itemCoercion = import_zod.z.union([
|
|
167
|
+
import_zod.z.number(),
|
|
168
|
+
import_zod.z.string().regex(/^-?(\d+\.?\d*|\.\d+)([eE][+-]?\d+)?$/).transform(Number)
|
|
169
|
+
]);
|
|
170
|
+
break;
|
|
171
|
+
default:
|
|
172
|
+
return schema;
|
|
173
|
+
}
|
|
174
|
+
const coercion = isList ? import_zod.z.array(itemCoercion) : itemCoercion;
|
|
175
|
+
return coercion.pipe(schema);
|
|
176
|
+
}
|
|
159
177
|
|
|
160
178
|
// src/runtime/schema-builder.ts
|
|
161
179
|
var import_zod3 = require("zod");
|
|
@@ -204,19 +222,65 @@ function coerceToArray(value) {
|
|
|
204
222
|
|
|
205
223
|
// src/runtime/zod-type-map.ts
|
|
206
224
|
var SCALAR_OPERATORS = {
|
|
207
|
-
String: /* @__PURE__ */ new Set([
|
|
225
|
+
String: /* @__PURE__ */ new Set([
|
|
226
|
+
"equals",
|
|
227
|
+
"not",
|
|
228
|
+
"contains",
|
|
229
|
+
"startsWith",
|
|
230
|
+
"endsWith",
|
|
231
|
+
"in",
|
|
232
|
+
"notIn",
|
|
233
|
+
"gt",
|
|
234
|
+
"gte",
|
|
235
|
+
"lt",
|
|
236
|
+
"lte"
|
|
237
|
+
]),
|
|
208
238
|
Int: /* @__PURE__ */ new Set(["equals", "not", "gt", "gte", "lt", "lte", "in", "notIn"]),
|
|
209
239
|
Float: /* @__PURE__ */ new Set(["equals", "not", "gt", "gte", "lt", "lte", "in", "notIn"]),
|
|
210
240
|
Decimal: /* @__PURE__ */ new Set(["equals", "not", "gt", "gte", "lt", "lte", "in", "notIn"]),
|
|
211
241
|
BigInt: /* @__PURE__ */ new Set(["equals", "not", "gt", "gte", "lt", "lte", "in", "notIn"]),
|
|
212
242
|
Boolean: /* @__PURE__ */ new Set(["equals", "not"]),
|
|
213
243
|
DateTime: /* @__PURE__ */ new Set(["equals", "not", "gt", "gte", "lt", "lte", "in", "notIn"]),
|
|
214
|
-
Bytes: /* @__PURE__ */ new Set([])
|
|
244
|
+
Bytes: /* @__PURE__ */ new Set([]),
|
|
245
|
+
Json: /* @__PURE__ */ new Set([
|
|
246
|
+
"equals",
|
|
247
|
+
"not",
|
|
248
|
+
"path",
|
|
249
|
+
"string_contains",
|
|
250
|
+
"string_starts_with",
|
|
251
|
+
"string_ends_with",
|
|
252
|
+
"array_contains",
|
|
253
|
+
"array_starts_with",
|
|
254
|
+
"array_ends_with"
|
|
255
|
+
])
|
|
215
256
|
};
|
|
216
|
-
var SCALAR_LIST_OPERATORS = /* @__PURE__ */ new Set([
|
|
257
|
+
var SCALAR_LIST_OPERATORS = /* @__PURE__ */ new Set([
|
|
258
|
+
"has",
|
|
259
|
+
"hasEvery",
|
|
260
|
+
"hasSome",
|
|
261
|
+
"isEmpty",
|
|
262
|
+
"equals"
|
|
263
|
+
]);
|
|
217
264
|
var ENUM_OPERATORS = /* @__PURE__ */ new Set(["equals", "not", "in", "notIn"]);
|
|
218
265
|
var NUMERIC_TYPES = /* @__PURE__ */ new Set(["Int", "Float", "Decimal", "BigInt"]);
|
|
219
|
-
var COMPARABLE_TYPES = /* @__PURE__ */ new Set([
|
|
266
|
+
var COMPARABLE_TYPES = /* @__PURE__ */ new Set([
|
|
267
|
+
"Int",
|
|
268
|
+
"Float",
|
|
269
|
+
"Decimal",
|
|
270
|
+
"BigInt",
|
|
271
|
+
"String",
|
|
272
|
+
"DateTime"
|
|
273
|
+
]);
|
|
274
|
+
var JSON_STRING_OPERATORS = /* @__PURE__ */ new Set([
|
|
275
|
+
"string_contains",
|
|
276
|
+
"string_starts_with",
|
|
277
|
+
"string_ends_with"
|
|
278
|
+
]);
|
|
279
|
+
var JSON_ARRAY_OPERATORS = /* @__PURE__ */ new Set([
|
|
280
|
+
"array_contains",
|
|
281
|
+
"array_starts_with",
|
|
282
|
+
"array_ends_with"
|
|
283
|
+
]);
|
|
220
284
|
function getSupportedOperators(fieldMeta) {
|
|
221
285
|
if (fieldMeta.isList)
|
|
222
286
|
return [...SCALAR_LIST_OPERATORS];
|
|
@@ -251,7 +315,9 @@ function createBaseType(fieldMeta, enumMap, scalarBase) {
|
|
|
251
315
|
}
|
|
252
316
|
function createScalarListOperatorSchema(fieldMeta, operator, enumMap, scalarBase) {
|
|
253
317
|
if (!SCALAR_LIST_OPERATORS.has(operator)) {
|
|
254
|
-
throw new ShapeError(
|
|
318
|
+
throw new ShapeError(
|
|
319
|
+
`Operator "${operator}" not supported for scalar list fields`
|
|
320
|
+
);
|
|
255
321
|
}
|
|
256
322
|
if (operator === "isEmpty") {
|
|
257
323
|
return import_zod2.z.boolean();
|
|
@@ -267,9 +333,32 @@ function createScalarListOperatorSchema(fieldMeta, operator, enumMap, scalarBase
|
|
|
267
333
|
}
|
|
268
334
|
return import_zod2.z.preprocess(coerceToArray, import_zod2.z.array(itemBase));
|
|
269
335
|
}
|
|
336
|
+
function createJsonOperatorSchema(fieldMeta, operator) {
|
|
337
|
+
const jsonValue = import_zod2.z.unknown();
|
|
338
|
+
if (operator === "equals" || operator === "not") {
|
|
339
|
+
return !fieldMeta.isRequired ? import_zod2.z.union([jsonValue, import_zod2.z.null()]) : jsonValue;
|
|
340
|
+
}
|
|
341
|
+
if (operator === "path") {
|
|
342
|
+
return import_zod2.z.preprocess(coerceToArray, import_zod2.z.array(import_zod2.z.string()).min(1));
|
|
343
|
+
}
|
|
344
|
+
if (JSON_STRING_OPERATORS.has(operator)) {
|
|
345
|
+
return import_zod2.z.string();
|
|
346
|
+
}
|
|
347
|
+
if (JSON_ARRAY_OPERATORS.has(operator)) {
|
|
348
|
+
return jsonValue;
|
|
349
|
+
}
|
|
350
|
+
throw new ShapeError(
|
|
351
|
+
`Operator "${operator}" not supported for Json fields`
|
|
352
|
+
);
|
|
353
|
+
}
|
|
270
354
|
function createOperatorSchema(fieldMeta, operator, enumMap, scalarBase) {
|
|
271
355
|
if (fieldMeta.isList) {
|
|
272
|
-
return createScalarListOperatorSchema(
|
|
356
|
+
return createScalarListOperatorSchema(
|
|
357
|
+
fieldMeta,
|
|
358
|
+
operator,
|
|
359
|
+
enumMap,
|
|
360
|
+
scalarBase
|
|
361
|
+
);
|
|
273
362
|
}
|
|
274
363
|
if (fieldMeta.isEnum) {
|
|
275
364
|
const values = enumMap[fieldMeta.type];
|
|
@@ -277,7 +366,9 @@ function createOperatorSchema(fieldMeta, operator, enumMap, scalarBase) {
|
|
|
277
366
|
throw new ShapeError(`Unknown enum: ${fieldMeta.type}`);
|
|
278
367
|
}
|
|
279
368
|
if (!ENUM_OPERATORS.has(operator)) {
|
|
280
|
-
throw new ShapeError(
|
|
369
|
+
throw new ShapeError(
|
|
370
|
+
`Operator "${operator}" not supported for enum fields`
|
|
371
|
+
);
|
|
281
372
|
}
|
|
282
373
|
const enumSchema = import_zod2.z.enum(values);
|
|
283
374
|
if (operator === "equals" || operator === "not") {
|
|
@@ -286,29 +377,43 @@ function createOperatorSchema(fieldMeta, operator, enumMap, scalarBase) {
|
|
|
286
377
|
const itemSchema = !fieldMeta.isRequired ? import_zod2.z.union([enumSchema, import_zod2.z.null()]) : enumSchema;
|
|
287
378
|
return import_zod2.z.preprocess(coerceToArray, import_zod2.z.array(itemSchema));
|
|
288
379
|
}
|
|
380
|
+
if (fieldMeta.type === "Json") {
|
|
381
|
+
const supportedOps2 = SCALAR_OPERATORS["Json"];
|
|
382
|
+
if (!supportedOps2 || !supportedOps2.has(operator)) {
|
|
383
|
+
throw new ShapeError(
|
|
384
|
+
`Operator "${operator}" not supported for type "Json"`
|
|
385
|
+
);
|
|
386
|
+
}
|
|
387
|
+
return createJsonOperatorSchema(fieldMeta, operator);
|
|
388
|
+
}
|
|
289
389
|
const supportedOps = SCALAR_OPERATORS[fieldMeta.type];
|
|
290
390
|
if (!supportedOps) {
|
|
291
391
|
throw new ShapeError(`Unknown scalar type for operator: ${fieldMeta.type}`);
|
|
292
392
|
}
|
|
293
393
|
if (supportedOps.size === 0) {
|
|
294
|
-
throw new ShapeError(
|
|
394
|
+
throw new ShapeError(
|
|
395
|
+
`Type "${fieldMeta.type}" does not support filter operators`
|
|
396
|
+
);
|
|
295
397
|
}
|
|
296
398
|
if (!supportedOps.has(operator)) {
|
|
297
|
-
throw new ShapeError(
|
|
399
|
+
throw new ShapeError(
|
|
400
|
+
`Operator "${operator}" not supported for type "${fieldMeta.type}"`
|
|
401
|
+
);
|
|
298
402
|
}
|
|
299
403
|
const factory = scalarBase[fieldMeta.type];
|
|
300
404
|
if (!factory) {
|
|
301
405
|
throw new ShapeError(`Unknown scalar type: ${fieldMeta.type}`);
|
|
302
406
|
}
|
|
303
407
|
const scalar = factory();
|
|
408
|
+
const coerced = wrapWithInputCoercion(fieldMeta.type, false, scalar);
|
|
304
409
|
if (operator === "equals" || operator === "not") {
|
|
305
|
-
return !fieldMeta.isRequired ? import_zod2.z.union([
|
|
410
|
+
return !fieldMeta.isRequired ? import_zod2.z.union([coerced, import_zod2.z.null()]) : coerced;
|
|
306
411
|
}
|
|
307
412
|
if (operator === "in" || operator === "notIn") {
|
|
308
|
-
const itemSchema = !fieldMeta.isRequired ? import_zod2.z.union([
|
|
413
|
+
const itemSchema = !fieldMeta.isRequired ? import_zod2.z.union([coerced, import_zod2.z.null()]) : coerced;
|
|
309
414
|
return import_zod2.z.preprocess(coerceToArray, import_zod2.z.array(itemSchema));
|
|
310
415
|
}
|
|
311
|
-
return
|
|
416
|
+
return coerced;
|
|
312
417
|
}
|
|
313
418
|
|
|
314
419
|
// src/runtime/schema-builder.ts
|
|
@@ -358,6 +463,9 @@ function createSchemaBuilder(typeMap, zodChains, enumMap, scalarBase, zodDefault
|
|
|
358
463
|
);
|
|
359
464
|
}
|
|
360
465
|
}
|
|
466
|
+
if (!fieldMeta.isEnum && !fieldMeta.isRelation && !fieldMeta.isUnsupported) {
|
|
467
|
+
result = wrapWithInputCoercion(fieldMeta.type, fieldMeta.isList, result);
|
|
468
|
+
}
|
|
361
469
|
lruSet(chainCache, cacheKey, result, DEFAULT_MAX_CACHE);
|
|
362
470
|
return result;
|
|
363
471
|
}
|
|
@@ -390,9 +498,13 @@ function createSchemaBuilder(typeMap, zodChains, enumMap, scalarBase, zodDefault
|
|
|
390
498
|
if (!modelFields[name])
|
|
391
499
|
throw new ShapeError(`Unknown field "${name}" on model "${model}"`);
|
|
392
500
|
if (modelFields[name].isRelation)
|
|
393
|
-
throw new ShapeError(
|
|
501
|
+
throw new ShapeError(
|
|
502
|
+
`Field "${name}" cannot be used in input schema (relation field)`
|
|
503
|
+
);
|
|
394
504
|
if (modelFields[name].isUpdatedAt)
|
|
395
|
-
throw new ShapeError(
|
|
505
|
+
throw new ShapeError(
|
|
506
|
+
`Field "${name}" cannot be used in input schema (updatedAt field)`
|
|
507
|
+
);
|
|
396
508
|
}
|
|
397
509
|
fieldNames = fieldNames.filter((n) => opts.pick.includes(n));
|
|
398
510
|
} else if (opts.omit) {
|
|
@@ -466,7 +578,9 @@ function createSchemaBuilder(typeMap, zodChains, enumMap, scalarBase, zodDefault
|
|
|
466
578
|
}
|
|
467
579
|
const effectiveMaxDepth = maxDepth ?? opts.maxDepth ?? DEFAULT_MAX_DEPTH;
|
|
468
580
|
if (depth > effectiveMaxDepth) {
|
|
469
|
-
throw new ShapeError(
|
|
581
|
+
throw new ShapeError(
|
|
582
|
+
`Maximum include depth (${effectiveMaxDepth}) exceeded`
|
|
583
|
+
);
|
|
470
584
|
}
|
|
471
585
|
const modelFields = typeMap[model];
|
|
472
586
|
if (!modelFields)
|
|
@@ -477,7 +591,9 @@ function createSchemaBuilder(typeMap, zodChains, enumMap, scalarBase, zodDefault
|
|
|
477
591
|
if (!modelFields[name])
|
|
478
592
|
throw new ShapeError(`Unknown field "${name}" on model "${model}"`);
|
|
479
593
|
if (modelFields[name].isRelation && !includeKeys.has(name)) {
|
|
480
|
-
throw new ShapeError(
|
|
594
|
+
throw new ShapeError(
|
|
595
|
+
`Field "${name}" is a relation on model "${model}". Use include: { ${name}: ... } instead of pick.`
|
|
596
|
+
);
|
|
481
597
|
}
|
|
482
598
|
}
|
|
483
599
|
}
|
|
@@ -510,10 +626,14 @@ function createSchemaBuilder(typeMap, zodChains, enumMap, scalarBase, zodDefault
|
|
|
510
626
|
if (!fieldMeta)
|
|
511
627
|
throw new ShapeError(`Unknown field "${relName}" on model "${model}"`);
|
|
512
628
|
if (!fieldMeta.isRelation)
|
|
513
|
-
throw new ShapeError(
|
|
629
|
+
throw new ShapeError(
|
|
630
|
+
`Field "${relName}" is not a relation on model "${model}"`
|
|
631
|
+
);
|
|
514
632
|
const relatedModel = fieldMeta.type;
|
|
515
633
|
if (!typeMap[relatedModel]) {
|
|
516
|
-
throw new ShapeError(
|
|
634
|
+
throw new ShapeError(
|
|
635
|
+
`Related model "${relatedModel}" not found in type map`
|
|
636
|
+
);
|
|
517
637
|
}
|
|
518
638
|
let relSchema = buildModelSchema(
|
|
519
639
|
relatedModel,
|
|
@@ -542,11 +662,17 @@ function createSchemaBuilder(typeMap, zodChains, enumMap, scalarBase, zodDefault
|
|
|
542
662
|
const countFields = {};
|
|
543
663
|
for (const relName of Object.keys(opts._count)) {
|
|
544
664
|
if (!modelFields[relName])
|
|
545
|
-
throw new ShapeError(
|
|
665
|
+
throw new ShapeError(
|
|
666
|
+
`Unknown field "${relName}" on model "${model}" in _count`
|
|
667
|
+
);
|
|
546
668
|
if (!modelFields[relName].isRelation)
|
|
547
|
-
throw new ShapeError(
|
|
669
|
+
throw new ShapeError(
|
|
670
|
+
`Field "${relName}" is not a relation on model "${model}" in _count`
|
|
671
|
+
);
|
|
548
672
|
if (!modelFields[relName].isList)
|
|
549
|
-
throw new ShapeError(
|
|
673
|
+
throw new ShapeError(
|
|
674
|
+
`Field "${relName}" is a to-one relation on model "${model}" in _count. Only to-many relations support _count.`
|
|
675
|
+
);
|
|
550
676
|
countFields[relName] = import_zod3.z.number().int().min(0);
|
|
551
677
|
}
|
|
552
678
|
schemaMap["_count"] = import_zod3.z.object(countFields);
|
|
@@ -558,7 +684,12 @@ function createSchemaBuilder(typeMap, zodChains, enumMap, scalarBase, zodDefault
|
|
|
558
684
|
}
|
|
559
685
|
return schema;
|
|
560
686
|
}
|
|
561
|
-
return {
|
|
687
|
+
return {
|
|
688
|
+
buildFieldSchema,
|
|
689
|
+
buildBaseFieldSchema,
|
|
690
|
+
buildInputSchema,
|
|
691
|
+
buildModelSchema
|
|
692
|
+
};
|
|
562
693
|
}
|
|
563
694
|
|
|
564
695
|
// src/runtime/query-builder.ts
|
|
@@ -1012,13 +1143,18 @@ function validateUniqueEquality(model, where, method, uniqueMap, typeMap) {
|
|
|
1012
1143
|
}
|
|
1013
1144
|
|
|
1014
1145
|
// src/runtime/query-builder-where.ts
|
|
1015
|
-
var UNSUPPORTED_WHERE_TYPES = /* @__PURE__ */ new Set(["
|
|
1146
|
+
var UNSUPPORTED_WHERE_TYPES = /* @__PURE__ */ new Set(["Bytes"]);
|
|
1016
1147
|
var STRING_MODE_OPS = /* @__PURE__ */ new Set([
|
|
1017
1148
|
"contains",
|
|
1018
1149
|
"startsWith",
|
|
1019
1150
|
"endsWith",
|
|
1020
1151
|
"equals"
|
|
1021
1152
|
]);
|
|
1153
|
+
var JSON_STRING_MODE_OPS = /* @__PURE__ */ new Set([
|
|
1154
|
+
"string_contains",
|
|
1155
|
+
"string_starts_with",
|
|
1156
|
+
"string_ends_with"
|
|
1157
|
+
]);
|
|
1022
1158
|
var MAX_WHERE_DEPTH = 10;
|
|
1023
1159
|
function safeStringify(v) {
|
|
1024
1160
|
if (typeof v === "bigint")
|
|
@@ -1114,6 +1250,13 @@ function mergeRelationForcedMaps(target, source) {
|
|
|
1114
1250
|
}
|
|
1115
1251
|
}
|
|
1116
1252
|
}
|
|
1253
|
+
function isModeCompatibleOp(fieldType, op) {
|
|
1254
|
+
if (fieldType === "String")
|
|
1255
|
+
return STRING_MODE_OPS.has(op);
|
|
1256
|
+
if (fieldType === "Json")
|
|
1257
|
+
return JSON_STRING_MODE_OPS.has(op);
|
|
1258
|
+
return false;
|
|
1259
|
+
}
|
|
1117
1260
|
function createWhereBuilder(typeMap, enumMap, scalarBase) {
|
|
1118
1261
|
function buildWhereSchema(model, whereConfig, depth) {
|
|
1119
1262
|
const currentDepth = depth ?? 0;
|
|
@@ -1316,7 +1459,7 @@ function createWhereBuilder(typeMap, enumMap, scalarBase) {
|
|
|
1316
1459
|
const opSchemas = {};
|
|
1317
1460
|
const fieldForced = {};
|
|
1318
1461
|
let hasClientOps = false;
|
|
1319
|
-
let
|
|
1462
|
+
let hasModeCompatibleOp = false;
|
|
1320
1463
|
const clientOpKeys = [];
|
|
1321
1464
|
let modeConfigValue = void 0;
|
|
1322
1465
|
let hasModeConfig = false;
|
|
@@ -1335,8 +1478,8 @@ function createWhereBuilder(typeMap, enumMap, scalarBase) {
|
|
|
1335
1478
|
).optional();
|
|
1336
1479
|
hasClientOps = true;
|
|
1337
1480
|
clientOpKeys.push(op);
|
|
1338
|
-
if (fieldMeta.
|
|
1339
|
-
|
|
1481
|
+
if (!fieldMeta.isList && isModeCompatibleOp(fieldMeta.type, op)) {
|
|
1482
|
+
hasModeCompatibleOp = true;
|
|
1340
1483
|
}
|
|
1341
1484
|
} else {
|
|
1342
1485
|
const actualOpValue = isForcedValue(opValue) ? opValue.value : opValue;
|
|
@@ -1355,15 +1498,15 @@ function createWhereBuilder(typeMap, enumMap, scalarBase) {
|
|
|
1355
1498
|
);
|
|
1356
1499
|
}
|
|
1357
1500
|
fieldForced[op] = parsed;
|
|
1358
|
-
if (fieldMeta.
|
|
1359
|
-
|
|
1501
|
+
if (!fieldMeta.isList && isModeCompatibleOp(fieldMeta.type, op)) {
|
|
1502
|
+
hasModeCompatibleOp = true;
|
|
1360
1503
|
}
|
|
1361
1504
|
}
|
|
1362
1505
|
}
|
|
1363
1506
|
if (!hasClientOps && Object.keys(fieldForced).length === 0) {
|
|
1364
1507
|
if (hasModeConfig) {
|
|
1365
1508
|
throw new ShapeError(
|
|
1366
|
-
`Where field "${fieldName}" on model "${model}" has "mode" but no operators. Add at least one operator
|
|
1509
|
+
`Where field "${fieldName}" on model "${model}" has "mode" but no operators. Add at least one compatible operator.`
|
|
1367
1510
|
);
|
|
1368
1511
|
}
|
|
1369
1512
|
throw new ShapeError(
|
|
@@ -1371,9 +1514,9 @@ function createWhereBuilder(typeMap, enumMap, scalarBase) {
|
|
|
1371
1514
|
);
|
|
1372
1515
|
}
|
|
1373
1516
|
if (hasModeConfig) {
|
|
1374
|
-
if (!
|
|
1517
|
+
if (!hasModeCompatibleOp) {
|
|
1375
1518
|
throw new ShapeError(
|
|
1376
|
-
`"mode" on where field "${fieldName}" on model "${model}" requires a compatible
|
|
1519
|
+
`"mode" on where field "${fieldName}" on model "${model}" requires a compatible operator (String: contains, startsWith, endsWith, equals; Json: string_contains, string_starts_with, string_ends_with)`
|
|
1377
1520
|
);
|
|
1378
1521
|
}
|
|
1379
1522
|
if (modeConfigValue === true) {
|
|
@@ -1391,7 +1534,7 @@ function createWhereBuilder(typeMap, enumMap, scalarBase) {
|
|
|
1391
1534
|
}
|
|
1392
1535
|
fieldForced["mode"] = parsed;
|
|
1393
1536
|
}
|
|
1394
|
-
} else if (
|
|
1537
|
+
} else if (hasModeCompatibleOp) {
|
|
1395
1538
|
opSchemas["mode"] = import_zod4.z.enum(["default", "insensitive"]).optional();
|
|
1396
1539
|
}
|
|
1397
1540
|
if (hasClientOps) {
|
|
@@ -1404,7 +1547,7 @@ function createWhereBuilder(typeMap, enumMap, scalarBase) {
|
|
|
1404
1547
|
message: `At least one operator required for where field "${fieldName}"`
|
|
1405
1548
|
}
|
|
1406
1549
|
);
|
|
1407
|
-
if ("equals" in opSchemas) {
|
|
1550
|
+
if ("equals" in opSchemas && fieldMeta.type !== "Json") {
|
|
1408
1551
|
const equalsBase = createOperatorSchema(
|
|
1409
1552
|
fieldMeta,
|
|
1410
1553
|
"equals",
|