Skip to content

Commit

Permalink
add path arg to @@Validate and implement gencode (#1641)
Browse files Browse the repository at this point in the history
  • Loading branch information
j0rdanba1n authored Aug 12, 2024
1 parent 9124d13 commit 9017a13
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 7 deletions.
11 changes: 9 additions & 2 deletions packages/schema/src/plugins/zod/utils/schema-gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
getAttributeArg,
getAttributeArgLiteral,
getLiteral,
getLiteralArray,
isDataModelFieldReference,
isFromStdlib,
} from '@zenstackhq/sdk';
Expand All @@ -14,6 +15,7 @@ import {
DataModelField,
DataModelFieldAttribute,
isDataModel,
isArrayExpr,
isEnum,
isInvocationExpr,
isNumberLiteral,
Expand Down Expand Up @@ -221,7 +223,12 @@ export function makeValidationRefinements(model: DataModel) {
}

const messageArg = getAttributeArgLiteral<string>(attr, 'message');
const message = messageArg ? `, { message: ${JSON.stringify(messageArg)} }` : '';
const message = messageArg ? `message: ${JSON.stringify(messageArg)},` : '';

const pathArg = getAttributeArg(attr, 'path');
const path = pathArg && isArrayExpr(pathArg) ? `path: ['${getLiteralArray<string>(pathArg)?.join(`', '`)}'],` : '';

const options = `, { ${message} ${path} }`;

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

return `.refine((value: any) => ${expr}${message})`;
return `.refine((value: any) => ${expr}${options})`;
} catch (err) {
if (err instanceof TypeScriptExpressionTransformerError) {
throw new PluginError(name, err.message);
Expand Down
2 changes: 1 addition & 1 deletion packages/schema/src/res/stdlib.zmodel
Original file line number Diff line number Diff line change
Expand Up @@ -633,7 +633,7 @@ attribute @lte(_ value: Int, _ message: String?) @@@targetField([IntField, Float
/**
* Validates the entity with a complex condition.
*/
attribute @@validate(_ value: Boolean, _ message: String?) @@@validation
attribute @@validate(_ value: Boolean, _ message: String?, _ path: String[]?) @@@validation

/**
* Validates length of a string field.
Expand Down
8 changes: 4 additions & 4 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

41 changes: 41 additions & 0 deletions tests/integration/tests/plugins/zod.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,47 @@ describe('Zod plugin tests', () => {
expect(schema.safeParse({ arr: [1, 2, 3] }).success).toBeTruthy();
});

it('refinement with path', async () => {
const model = `
datasource db {
provider = 'postgresql'
url = env('DATABASE_URL')
}
generator js {
provider = 'prisma-client-js'
}
plugin zod {
provider = "@core/zod"
}
model M {
id Int @id @default(autoincrement())
arr Int[]
@@validate(!isEmpty(arr), 'condition1', ['array'])
@@validate(has(arr, 1), 'condition2', ['arr'])
@@validate(hasEvery(arr, [1, 2]), 'condition3', ['arr', 'every'])
@@validate(hasSome(arr, [1, 2]), 'condition4', ['arr', 'some'])
}
`;

const { zodSchemas } = await loadSchema(model, { addPrelude: false, pushDb: false });

const schema = zodSchemas.models.MCreateSchema;
expect(schema.safeParse({}).error.issues[0].path).toEqual(['array']);
expect(schema.safeParse({ arr: [] }).error.issues[0].path).toEqual(['array']);
expect(schema.safeParse({ arr: [3] }).error.issues[0].path).toEqual(['arr']);
expect(schema.safeParse({ arr: [3] }).error.issues[1].path).toEqual(['arr', 'every']);
expect(schema.safeParse({ arr: [3] }).error.issues[2].path).toEqual(['arr', 'some']);
expect(schema.safeParse({ arr: [1] }).error.issues[0].path).toEqual(['arr', 'every']);
expect(schema.safeParse({ arr: [4] }).error.issues[0].path).toEqual(['arr']);
expect(schema.safeParse({ arr: [4] }).error.issues[1].path).toEqual(['arr', 'every']);
expect(schema.safeParse({ arr: [4] }).error.issues[2].path).toEqual(['arr', 'some']);
expect(schema.safeParse({ arr: [1, 2, 3] }).success).toBeTruthy();
})

it('full-text search', async () => {
const model = `
datasource db {
Expand Down

0 comments on commit 9017a13

Please sign in to comment.