prisma-guard 1.14.1 → 1.16.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 +8 -13
- package/dist/generator/index.js.map +1 -1
- package/dist/runtime/index.cjs +136 -62
- package/dist/runtime/index.cjs.map +1 -1
- package/dist/runtime/index.d.cts +4 -1
- package/dist/runtime/index.d.ts +4 -1
- package/dist/runtime/index.js +134 -61
- package/dist/runtime/index.js.map +1 -1
- package/package.json +1 -1
package/dist/runtime/index.cjs
CHANGED
|
@@ -24,7 +24,8 @@ __export(runtime_exports, {
|
|
|
24
24
|
PolicyError: () => PolicyError,
|
|
25
25
|
ShapeError: () => ShapeError,
|
|
26
26
|
createGuard: () => createGuard,
|
|
27
|
-
force: () => force
|
|
27
|
+
force: () => force,
|
|
28
|
+
unsupported: () => unsupported
|
|
28
29
|
});
|
|
29
30
|
module.exports = __toCommonJS(runtime_exports);
|
|
30
31
|
|
|
@@ -114,10 +115,7 @@ function isJsonSafe(value) {
|
|
|
114
115
|
return true;
|
|
115
116
|
}
|
|
116
117
|
var DECIMAL_REGEX = /^-?(\d+\.?\d*|\.\d+)([eE]-?\d+)?$/;
|
|
117
|
-
var decimalStringSchema = import_zod.z.string().refine(
|
|
118
|
-
(s) => DECIMAL_REGEX.test(s),
|
|
119
|
-
"Invalid decimal string"
|
|
120
|
-
);
|
|
118
|
+
var decimalStringSchema = import_zod.z.string().refine((s) => DECIMAL_REGEX.test(s), "Invalid decimal string");
|
|
121
119
|
var decimalObjectSchema = import_zod.z.custom(
|
|
122
120
|
(v) => v !== null && typeof v === "object" && typeof v.toFixed === "function" && typeof v.toNumber === "function",
|
|
123
121
|
"Expected Decimal-compatible object"
|
|
@@ -143,18 +141,39 @@ function createScalarBase(strictDecimal) {
|
|
|
143
141
|
import_zod.z.string().regex(/^-?\d+$/).transform((v) => BigInt(v))
|
|
144
142
|
]),
|
|
145
143
|
Boolean: () => import_zod.z.boolean(),
|
|
146
|
-
DateTime: () => import_zod.z.union([
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
Bytes: () => import_zod.z.union([
|
|
152
|
-
import_zod.z.string(),
|
|
153
|
-
import_zod.z.custom((v) => v instanceof Uint8Array)
|
|
154
|
-
])
|
|
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)])
|
|
155
150
|
};
|
|
156
151
|
}
|
|
157
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
|
+
}
|
|
158
177
|
|
|
159
178
|
// src/runtime/schema-builder.ts
|
|
160
179
|
var import_zod3 = require("zod");
|
|
@@ -203,7 +222,19 @@ function coerceToArray(value) {
|
|
|
203
222
|
|
|
204
223
|
// src/runtime/zod-type-map.ts
|
|
205
224
|
var SCALAR_OPERATORS = {
|
|
206
|
-
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
|
+
]),
|
|
207
238
|
Int: /* @__PURE__ */ new Set(["equals", "not", "gt", "gte", "lt", "lte", "in", "notIn"]),
|
|
208
239
|
Float: /* @__PURE__ */ new Set(["equals", "not", "gt", "gte", "lt", "lte", "in", "notIn"]),
|
|
209
240
|
Decimal: /* @__PURE__ */ new Set(["equals", "not", "gt", "gte", "lt", "lte", "in", "notIn"]),
|
|
@@ -212,10 +243,23 @@ var SCALAR_OPERATORS = {
|
|
|
212
243
|
DateTime: /* @__PURE__ */ new Set(["equals", "not", "gt", "gte", "lt", "lte", "in", "notIn"]),
|
|
213
244
|
Bytes: /* @__PURE__ */ new Set([])
|
|
214
245
|
};
|
|
215
|
-
var SCALAR_LIST_OPERATORS = /* @__PURE__ */ new Set([
|
|
246
|
+
var SCALAR_LIST_OPERATORS = /* @__PURE__ */ new Set([
|
|
247
|
+
"has",
|
|
248
|
+
"hasEvery",
|
|
249
|
+
"hasSome",
|
|
250
|
+
"isEmpty",
|
|
251
|
+
"equals"
|
|
252
|
+
]);
|
|
216
253
|
var ENUM_OPERATORS = /* @__PURE__ */ new Set(["equals", "not", "in", "notIn"]);
|
|
217
254
|
var NUMERIC_TYPES = /* @__PURE__ */ new Set(["Int", "Float", "Decimal", "BigInt"]);
|
|
218
|
-
var COMPARABLE_TYPES = /* @__PURE__ */ new Set([
|
|
255
|
+
var COMPARABLE_TYPES = /* @__PURE__ */ new Set([
|
|
256
|
+
"Int",
|
|
257
|
+
"Float",
|
|
258
|
+
"Decimal",
|
|
259
|
+
"BigInt",
|
|
260
|
+
"String",
|
|
261
|
+
"DateTime"
|
|
262
|
+
]);
|
|
219
263
|
function getSupportedOperators(fieldMeta) {
|
|
220
264
|
if (fieldMeta.isList)
|
|
221
265
|
return [...SCALAR_LIST_OPERATORS];
|
|
@@ -250,7 +294,9 @@ function createBaseType(fieldMeta, enumMap, scalarBase) {
|
|
|
250
294
|
}
|
|
251
295
|
function createScalarListOperatorSchema(fieldMeta, operator, enumMap, scalarBase) {
|
|
252
296
|
if (!SCALAR_LIST_OPERATORS.has(operator)) {
|
|
253
|
-
throw new ShapeError(
|
|
297
|
+
throw new ShapeError(
|
|
298
|
+
`Operator "${operator}" not supported for scalar list fields`
|
|
299
|
+
);
|
|
254
300
|
}
|
|
255
301
|
if (operator === "isEmpty") {
|
|
256
302
|
return import_zod2.z.boolean();
|
|
@@ -268,7 +314,12 @@ function createScalarListOperatorSchema(fieldMeta, operator, enumMap, scalarBase
|
|
|
268
314
|
}
|
|
269
315
|
function createOperatorSchema(fieldMeta, operator, enumMap, scalarBase) {
|
|
270
316
|
if (fieldMeta.isList) {
|
|
271
|
-
return createScalarListOperatorSchema(
|
|
317
|
+
return createScalarListOperatorSchema(
|
|
318
|
+
fieldMeta,
|
|
319
|
+
operator,
|
|
320
|
+
enumMap,
|
|
321
|
+
scalarBase
|
|
322
|
+
);
|
|
272
323
|
}
|
|
273
324
|
if (fieldMeta.isEnum) {
|
|
274
325
|
const values = enumMap[fieldMeta.type];
|
|
@@ -276,7 +327,9 @@ function createOperatorSchema(fieldMeta, operator, enumMap, scalarBase) {
|
|
|
276
327
|
throw new ShapeError(`Unknown enum: ${fieldMeta.type}`);
|
|
277
328
|
}
|
|
278
329
|
if (!ENUM_OPERATORS.has(operator)) {
|
|
279
|
-
throw new ShapeError(
|
|
330
|
+
throw new ShapeError(
|
|
331
|
+
`Operator "${operator}" not supported for enum fields`
|
|
332
|
+
);
|
|
280
333
|
}
|
|
281
334
|
const enumSchema = import_zod2.z.enum(values);
|
|
282
335
|
if (operator === "equals" || operator === "not") {
|
|
@@ -290,24 +343,29 @@ function createOperatorSchema(fieldMeta, operator, enumMap, scalarBase) {
|
|
|
290
343
|
throw new ShapeError(`Unknown scalar type for operator: ${fieldMeta.type}`);
|
|
291
344
|
}
|
|
292
345
|
if (supportedOps.size === 0) {
|
|
293
|
-
throw new ShapeError(
|
|
346
|
+
throw new ShapeError(
|
|
347
|
+
`Type "${fieldMeta.type}" does not support filter operators`
|
|
348
|
+
);
|
|
294
349
|
}
|
|
295
350
|
if (!supportedOps.has(operator)) {
|
|
296
|
-
throw new ShapeError(
|
|
351
|
+
throw new ShapeError(
|
|
352
|
+
`Operator "${operator}" not supported for type "${fieldMeta.type}"`
|
|
353
|
+
);
|
|
297
354
|
}
|
|
298
355
|
const factory = scalarBase[fieldMeta.type];
|
|
299
356
|
if (!factory) {
|
|
300
357
|
throw new ShapeError(`Unknown scalar type: ${fieldMeta.type}`);
|
|
301
358
|
}
|
|
302
359
|
const scalar = factory();
|
|
360
|
+
const coerced = wrapWithInputCoercion(fieldMeta.type, false, scalar);
|
|
303
361
|
if (operator === "equals" || operator === "not") {
|
|
304
|
-
return !fieldMeta.isRequired ? import_zod2.z.union([
|
|
362
|
+
return !fieldMeta.isRequired ? import_zod2.z.union([coerced, import_zod2.z.null()]) : coerced;
|
|
305
363
|
}
|
|
306
364
|
if (operator === "in" || operator === "notIn") {
|
|
307
|
-
const itemSchema = !fieldMeta.isRequired ? import_zod2.z.union([
|
|
365
|
+
const itemSchema = !fieldMeta.isRequired ? import_zod2.z.union([coerced, import_zod2.z.null()]) : coerced;
|
|
308
366
|
return import_zod2.z.preprocess(coerceToArray, import_zod2.z.array(itemSchema));
|
|
309
367
|
}
|
|
310
|
-
return
|
|
368
|
+
return coerced;
|
|
311
369
|
}
|
|
312
370
|
|
|
313
371
|
// src/runtime/schema-builder.ts
|
|
@@ -357,6 +415,9 @@ function createSchemaBuilder(typeMap, zodChains, enumMap, scalarBase, zodDefault
|
|
|
357
415
|
);
|
|
358
416
|
}
|
|
359
417
|
}
|
|
418
|
+
if (!fieldMeta.isEnum && !fieldMeta.isRelation && !fieldMeta.isUnsupported) {
|
|
419
|
+
result = wrapWithInputCoercion(fieldMeta.type, fieldMeta.isList, result);
|
|
420
|
+
}
|
|
360
421
|
lruSet(chainCache, cacheKey, result, DEFAULT_MAX_CACHE);
|
|
361
422
|
return result;
|
|
362
423
|
}
|
|
@@ -389,9 +450,13 @@ function createSchemaBuilder(typeMap, zodChains, enumMap, scalarBase, zodDefault
|
|
|
389
450
|
if (!modelFields[name])
|
|
390
451
|
throw new ShapeError(`Unknown field "${name}" on model "${model}"`);
|
|
391
452
|
if (modelFields[name].isRelation)
|
|
392
|
-
throw new ShapeError(
|
|
453
|
+
throw new ShapeError(
|
|
454
|
+
`Field "${name}" cannot be used in input schema (relation field)`
|
|
455
|
+
);
|
|
393
456
|
if (modelFields[name].isUpdatedAt)
|
|
394
|
-
throw new ShapeError(
|
|
457
|
+
throw new ShapeError(
|
|
458
|
+
`Field "${name}" cannot be used in input schema (updatedAt field)`
|
|
459
|
+
);
|
|
395
460
|
}
|
|
396
461
|
fieldNames = fieldNames.filter((n) => opts.pick.includes(n));
|
|
397
462
|
} else if (opts.omit) {
|
|
@@ -465,7 +530,9 @@ function createSchemaBuilder(typeMap, zodChains, enumMap, scalarBase, zodDefault
|
|
|
465
530
|
}
|
|
466
531
|
const effectiveMaxDepth = maxDepth ?? opts.maxDepth ?? DEFAULT_MAX_DEPTH;
|
|
467
532
|
if (depth > effectiveMaxDepth) {
|
|
468
|
-
throw new ShapeError(
|
|
533
|
+
throw new ShapeError(
|
|
534
|
+
`Maximum include depth (${effectiveMaxDepth}) exceeded`
|
|
535
|
+
);
|
|
469
536
|
}
|
|
470
537
|
const modelFields = typeMap[model];
|
|
471
538
|
if (!modelFields)
|
|
@@ -476,7 +543,9 @@ function createSchemaBuilder(typeMap, zodChains, enumMap, scalarBase, zodDefault
|
|
|
476
543
|
if (!modelFields[name])
|
|
477
544
|
throw new ShapeError(`Unknown field "${name}" on model "${model}"`);
|
|
478
545
|
if (modelFields[name].isRelation && !includeKeys.has(name)) {
|
|
479
|
-
throw new ShapeError(
|
|
546
|
+
throw new ShapeError(
|
|
547
|
+
`Field "${name}" is a relation on model "${model}". Use include: { ${name}: ... } instead of pick.`
|
|
548
|
+
);
|
|
480
549
|
}
|
|
481
550
|
}
|
|
482
551
|
}
|
|
@@ -509,10 +578,14 @@ function createSchemaBuilder(typeMap, zodChains, enumMap, scalarBase, zodDefault
|
|
|
509
578
|
if (!fieldMeta)
|
|
510
579
|
throw new ShapeError(`Unknown field "${relName}" on model "${model}"`);
|
|
511
580
|
if (!fieldMeta.isRelation)
|
|
512
|
-
throw new ShapeError(
|
|
581
|
+
throw new ShapeError(
|
|
582
|
+
`Field "${relName}" is not a relation on model "${model}"`
|
|
583
|
+
);
|
|
513
584
|
const relatedModel = fieldMeta.type;
|
|
514
585
|
if (!typeMap[relatedModel]) {
|
|
515
|
-
throw new ShapeError(
|
|
586
|
+
throw new ShapeError(
|
|
587
|
+
`Related model "${relatedModel}" not found in type map`
|
|
588
|
+
);
|
|
516
589
|
}
|
|
517
590
|
let relSchema = buildModelSchema(
|
|
518
591
|
relatedModel,
|
|
@@ -541,11 +614,17 @@ function createSchemaBuilder(typeMap, zodChains, enumMap, scalarBase, zodDefault
|
|
|
541
614
|
const countFields = {};
|
|
542
615
|
for (const relName of Object.keys(opts._count)) {
|
|
543
616
|
if (!modelFields[relName])
|
|
544
|
-
throw new ShapeError(
|
|
617
|
+
throw new ShapeError(
|
|
618
|
+
`Unknown field "${relName}" on model "${model}" in _count`
|
|
619
|
+
);
|
|
545
620
|
if (!modelFields[relName].isRelation)
|
|
546
|
-
throw new ShapeError(
|
|
621
|
+
throw new ShapeError(
|
|
622
|
+
`Field "${relName}" is not a relation on model "${model}" in _count`
|
|
623
|
+
);
|
|
547
624
|
if (!modelFields[relName].isList)
|
|
548
|
-
throw new ShapeError(
|
|
625
|
+
throw new ShapeError(
|
|
626
|
+
`Field "${relName}" is a to-one relation on model "${model}" in _count. Only to-many relations support _count.`
|
|
627
|
+
);
|
|
549
628
|
countFields[relName] = import_zod3.z.number().int().min(0);
|
|
550
629
|
}
|
|
551
630
|
schemaMap["_count"] = import_zod3.z.object(countFields);
|
|
@@ -557,7 +636,12 @@ function createSchemaBuilder(typeMap, zodChains, enumMap, scalarBase, zodDefault
|
|
|
557
636
|
}
|
|
558
637
|
return schema;
|
|
559
638
|
}
|
|
560
|
-
return {
|
|
639
|
+
return {
|
|
640
|
+
buildFieldSchema,
|
|
641
|
+
buildBaseFieldSchema,
|
|
642
|
+
buildInputSchema,
|
|
643
|
+
buildModelSchema
|
|
644
|
+
};
|
|
561
645
|
}
|
|
562
646
|
|
|
563
647
|
// src/runtime/query-builder.ts
|
|
@@ -603,6 +687,15 @@ function force(value) {
|
|
|
603
687
|
wrapper[FORCED_MARKER] = true;
|
|
604
688
|
return wrapper;
|
|
605
689
|
}
|
|
690
|
+
var UNSUPPORTED_MARKER = Symbol.for("prisma-guard.unsupported");
|
|
691
|
+
function isUnsupportedMarker(v) {
|
|
692
|
+
return v !== null && typeof v === "object" && v[UNSUPPORTED_MARKER] === true;
|
|
693
|
+
}
|
|
694
|
+
function unsupported() {
|
|
695
|
+
const marker = {};
|
|
696
|
+
marker[UNSUPPORTED_MARKER] = true;
|
|
697
|
+
return marker;
|
|
698
|
+
}
|
|
606
699
|
|
|
607
700
|
// src/shared/match-caller.ts
|
|
608
701
|
function matchCallerPattern(patterns, caller) {
|
|
@@ -3189,31 +3282,6 @@ function buildRelationWriteSchema(model, fieldName, relatedModelName, isList, co
|
|
|
3189
3282
|
);
|
|
3190
3283
|
}
|
|
3191
3284
|
}
|
|
3192
|
-
if (config.delete !== void 0) {
|
|
3193
|
-
if (config.delete === true) {
|
|
3194
|
-
if (isList) {
|
|
3195
|
-
throw new ShapeError(
|
|
3196
|
-
`delete on to-many relation "${model}.${fieldName}" requires field config, not true`
|
|
3197
|
-
);
|
|
3198
|
-
}
|
|
3199
|
-
opSchemas["delete"] = import_zod8.z.literal(true).optional();
|
|
3200
|
-
} else if (isPlainObject(config.delete)) {
|
|
3201
|
-
const deleteSchema = buildWhereFieldsSchema(
|
|
3202
|
-
relatedModelName,
|
|
3203
|
-
config.delete,
|
|
3204
|
-
typeMap,
|
|
3205
|
-
schemaBuilder
|
|
3206
|
-
);
|
|
3207
|
-
opSchemas["delete"] = isList ? import_zod8.z.union([
|
|
3208
|
-
deleteSchema,
|
|
3209
|
-
import_zod8.z.preprocess(coerceToArray, import_zod8.z.array(deleteSchema))
|
|
3210
|
-
]).optional() : deleteSchema.optional();
|
|
3211
|
-
} else {
|
|
3212
|
-
throw new ShapeError(
|
|
3213
|
-
`delete config on "${model}.${fieldName}" must be true (to-one) or an object of field names`
|
|
3214
|
-
);
|
|
3215
|
-
}
|
|
3216
|
-
}
|
|
3217
3285
|
if (config.set !== void 0) {
|
|
3218
3286
|
if (!isList) {
|
|
3219
3287
|
throw new ShapeError(
|
|
@@ -3420,8 +3488,13 @@ function buildDataSchema(model, dataConfig, mode, typeMap, schemaBuilder, zodDef
|
|
|
3420
3488
|
const forced = {};
|
|
3421
3489
|
for (const [fieldName, value] of Object.entries(dataConfig)) {
|
|
3422
3490
|
const fieldMeta = modelFields[fieldName];
|
|
3423
|
-
if (!fieldMeta)
|
|
3491
|
+
if (!fieldMeta) {
|
|
3492
|
+
if (isUnsupportedMarker(value)) {
|
|
3493
|
+
schemaMap[fieldName] = import_zod8.z.unknown().optional();
|
|
3494
|
+
continue;
|
|
3495
|
+
}
|
|
3424
3496
|
throw new ShapeError(`Unknown field "${fieldName}" on model "${model}"`);
|
|
3497
|
+
}
|
|
3425
3498
|
if (fieldMeta.isRelation) {
|
|
3426
3499
|
if (!isPlainObject(value)) {
|
|
3427
3500
|
throw new ShapeError(
|
|
@@ -4630,6 +4703,7 @@ function createGuard(config) {
|
|
|
4630
4703
|
PolicyError,
|
|
4631
4704
|
ShapeError,
|
|
4632
4705
|
createGuard,
|
|
4633
|
-
force
|
|
4706
|
+
force,
|
|
4707
|
+
unsupported
|
|
4634
4708
|
});
|
|
4635
4709
|
//# sourceMappingURL=index.cjs.map
|