Skip to content

Commit

Permalink
fix(zod): make typing of Bytes field compatible with both Buffer
Browse files Browse the repository at this point in the history
…and `Uint8Array`

Fixes #1268
  • Loading branch information
ymc9 committed Apr 24, 2024
1 parent 7c4d86c commit 13061aa
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 23 deletions.
13 changes: 7 additions & 6 deletions packages/schema/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,13 @@
"configuration": {
"title": "ZenStack",
"properties": {
"zmodel.format.usePrismaStyle": {
"type": "boolean",
"default": true,
"description": "Use Prisma style indentation."
}
"zmodel.format.usePrismaStyle": {
"type": "boolean",
"default": true,
"description": "Use Prisma style indentation."
}
}
}
}
},
"activationEvents": [
"onLanguage:zmodel"
Expand All @@ -90,6 +90,7 @@
},
"dependencies": {
"@paralleldrive/cuid2": "^2.2.0",
"@types/node": "^20.12.7",
"@zenstackhq/language": "workspace:*",
"@zenstackhq/sdk": "workspace:*",
"async-exit-hook": "^2.0.1",
Expand Down
10 changes: 9 additions & 1 deletion packages/schema/src/plugins/zod/transformer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ export default class Transformer {
return result;
}

// TODO: unify the following with `schema-gen.ts`

if (inputType.type === 'String') {
result.push(this.wrapWithZodValidators('z.string()', field, inputType));
} else if (inputType.type === 'Int' || inputType.type === 'Float') {
Expand All @@ -131,7 +133,13 @@ export default class Transformer {
} else if (inputType.type === 'DateTime') {
result.push(this.wrapWithZodValidators(['z.date()', 'z.string().datetime()'], field, inputType));
} else if (inputType.type === 'Bytes') {
result.push(this.wrapWithZodValidators(`z.instanceof(Uint8Array)`, field, inputType));
result.push(
this.wrapWithZodValidators(
`z.custom<Buffer | Uint8Array>(data => data instanceof Uint8Array)`,
field,
inputType
)
);
} else if (inputType.type === 'Json') {
this.hasJson = true;
result.push(this.wrapWithZodValidators('jsonSchema', field, inputType));
Expand Down
2 changes: 1 addition & 1 deletion packages/schema/src/plugins/zod/utils/schema-gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ function makeZodSchema(field: DataModelField) {
schema = 'z.coerce.date()';
break;
case 'Bytes':
schema = 'z.union([z.string(), z.instanceof(Uint8Array)])';
schema = 'z.union([z.string(), z.custom<Buffer | Uint8Array>(data => data instanceof Uint8Array)])';
break;
default:
schema = 'z.any()';
Expand Down
6 changes: 4 additions & 2 deletions packages/testtools/src/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,12 @@ generator js {
plugin enhancer {
provider = '@core/enhancer'
preserveTsFiles = true
${options.preserveTsFiles ? 'preserveTsFiles = true' : ''}
}
plugin zod {
provider = '@core/zod'
// preserveTsFiles = true
${options.preserveTsFiles ? 'preserveTsFiles = true' : ''}
modelOnly = ${!options.fullZod}
}
`;
Expand All @@ -130,6 +130,7 @@ export type SchemaLoadOptions = {
enhanceOptions?: Partial<EnhancementOptions>;
extraSourceFiles?: { name: string; content: string }[];
projectDir?: string;
preserveTsFiles?: boolean;
};

const defaultOptions: SchemaLoadOptions = {
Expand All @@ -140,6 +141,7 @@ const defaultOptions: SchemaLoadOptions = {
compile: false,
logPrismaQuery: false,
provider: 'sqlite',
preserveTsFiles: false,
};

export async function loadSchemaFromFile(schemaFile: string, options?: SchemaLoadOptions) {
Expand Down
32 changes: 20 additions & 12 deletions pnpm-lock.yaml

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

2 changes: 1 addition & 1 deletion script/test-scaffold.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ function run(cmd: string) {
}

run('npm init -y');
run('npm i --no-audit --no-fund typescript prisma @prisma/client zod decimal.js');
run('npm i --no-audit --no-fund typescript prisma @prisma/client zod decimal.js @types/node');

console.log('Test scaffold setup complete.');
32 changes: 32 additions & 0 deletions tests/regression/tests/issue-1268.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { loadSchema } from '@zenstackhq/testtools';

describe('issue 1268', () => {
it('regression', async () => {
const { zodSchemas } = await loadSchema(
`
model Model {
id String @id @default(uuid())
bytes Bytes
}
`,
{
fullZod: true,
pushDb: false,
compile: true,
extraSourceFiles: [
{
name: 'test.ts',
content: `
import { ModelCreateInputObjectSchema } from '.zenstack/zod/objects';
ModelCreateInputObjectSchema.parse({ bytes: new Uint8Array(0) });
`,
},
],
}
);

expect(
zodSchemas.objects.ModelCreateInputObjectSchema.safeParse({ bytes: new Uint8Array(0) }).success
).toBeTruthy();
});
});

0 comments on commit 13061aa

Please sign in to comment.