Skip to content

Commit 9017a13

Browse files
authored
add path arg to @@Validate and implement gencode (#1641)
1 parent 9124d13 commit 9017a13

File tree

4 files changed

+55
-7
lines changed

4 files changed

+55
-7
lines changed

packages/schema/src/plugins/zod/utils/schema-gen.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
getAttributeArg,
77
getAttributeArgLiteral,
88
getLiteral,
9+
getLiteralArray,
910
isDataModelFieldReference,
1011
isFromStdlib,
1112
} from '@zenstackhq/sdk';
@@ -14,6 +15,7 @@ import {
1415
DataModelField,
1516
DataModelFieldAttribute,
1617
isDataModel,
18+
isArrayExpr,
1719
isEnum,
1820
isInvocationExpr,
1921
isNumberLiteral,
@@ -221,7 +223,12 @@ export function makeValidationRefinements(model: DataModel) {
221223
}
222224

223225
const messageArg = getAttributeArgLiteral<string>(attr, 'message');
224-
const message = messageArg ? `, { message: ${JSON.stringify(messageArg)} }` : '';
226+
const message = messageArg ? `message: ${JSON.stringify(messageArg)},` : '';
227+
228+
const pathArg = getAttributeArg(attr, 'path');
229+
const path = pathArg && isArrayExpr(pathArg) ? `path: ['${getLiteralArray<string>(pathArg)?.join(`', '`)}'],` : '';
230+
231+
const options = `, { ${message} ${path} }`;
225232

226233
try {
227234
let expr = new TypeScriptExpressionTransformer({
@@ -235,7 +242,7 @@ export function makeValidationRefinements(model: DataModel) {
235242
expr = `${expr} ?? true`;
236243
}
237244

238-
return `.refine((value: any) => ${expr}${message})`;
245+
return `.refine((value: any) => ${expr}${options})`;
239246
} catch (err) {
240247
if (err instanceof TypeScriptExpressionTransformerError) {
241248
throw new PluginError(name, err.message);

packages/schema/src/res/stdlib.zmodel

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -633,7 +633,7 @@ attribute @lte(_ value: Int, _ message: String?) @@@targetField([IntField, Float
633633
/**
634634
* Validates the entity with a complex condition.
635635
*/
636-
attribute @@validate(_ value: Boolean, _ message: String?) @@@validation
636+
attribute @@validate(_ value: Boolean, _ message: String?, _ path: String[]?) @@@validation
637637

638638
/**
639639
* Validates length of a string field.

pnpm-lock.yaml

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/integration/tests/plugins/zod.test.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,47 @@ describe('Zod plugin tests', () => {
458458
expect(schema.safeParse({ arr: [1, 2, 3] }).success).toBeTruthy();
459459
});
460460

461+
it('refinement with path', async () => {
462+
const model = `
463+
datasource db {
464+
provider = 'postgresql'
465+
url = env('DATABASE_URL')
466+
}
467+
468+
generator js {
469+
provider = 'prisma-client-js'
470+
}
471+
472+
plugin zod {
473+
provider = "@core/zod"
474+
}
475+
476+
model M {
477+
id Int @id @default(autoincrement())
478+
arr Int[]
479+
480+
@@validate(!isEmpty(arr), 'condition1', ['array'])
481+
@@validate(has(arr, 1), 'condition2', ['arr'])
482+
@@validate(hasEvery(arr, [1, 2]), 'condition3', ['arr', 'every'])
483+
@@validate(hasSome(arr, [1, 2]), 'condition4', ['arr', 'some'])
484+
}
485+
`;
486+
487+
const { zodSchemas } = await loadSchema(model, { addPrelude: false, pushDb: false });
488+
489+
const schema = zodSchemas.models.MCreateSchema;
490+
expect(schema.safeParse({}).error.issues[0].path).toEqual(['array']);
491+
expect(schema.safeParse({ arr: [] }).error.issues[0].path).toEqual(['array']);
492+
expect(schema.safeParse({ arr: [3] }).error.issues[0].path).toEqual(['arr']);
493+
expect(schema.safeParse({ arr: [3] }).error.issues[1].path).toEqual(['arr', 'every']);
494+
expect(schema.safeParse({ arr: [3] }).error.issues[2].path).toEqual(['arr', 'some']);
495+
expect(schema.safeParse({ arr: [1] }).error.issues[0].path).toEqual(['arr', 'every']);
496+
expect(schema.safeParse({ arr: [4] }).error.issues[0].path).toEqual(['arr']);
497+
expect(schema.safeParse({ arr: [4] }).error.issues[1].path).toEqual(['arr', 'every']);
498+
expect(schema.safeParse({ arr: [4] }).error.issues[2].path).toEqual(['arr', 'some']);
499+
expect(schema.safeParse({ arr: [1, 2, 3] }).success).toBeTruthy();
500+
})
501+
461502
it('full-text search', async () => {
462503
const model = `
463504
datasource db {

0 commit comments

Comments
 (0)