Skip to content

Commit

Permalink
added support for new zod bigint and additional string validators
Browse files Browse the repository at this point in the history
  • Loading branch information
chrishoermann committed Mar 7, 2023
1 parent f2aee2d commit 0a61621
Show file tree
Hide file tree
Showing 9 changed files with 480 additions and 48 deletions.
4 changes: 2 additions & 2 deletions Readme.md
Expand Up @@ -868,11 +868,11 @@ model MyModel {

## BigInt validators

To add custom validators to the prisma `BigInt` field you can use the `@zod.bigint` key. Due to the fact that there are no custom validators provided by `zod` on `z.bigint()` you can only add customized type errors to the field.
To add custom validators to the prisma `BigInt` field you can use the `@zod.bigint` key. On this key you can use all string-specific validators that are mentioned in the [`zod-docs`](https://github.com/colinhacks/zod#bigints). You can also add a custom error message to each validator as stated in the docs.

```prisma
model MyModel {
myField BigInt /// @zod.bigint({ invalid_type_error: "error", ... })
myField BigInt /// @zod.bigintlt(5n, { message: "lt error" }).gt(6n, { message: "gt error" })({ invalid_type_error: "error", ... }).[...chain more validators]
}
```

Expand Down
8 changes: 4 additions & 4 deletions packages/generator/Readme.md
Expand Up @@ -277,7 +277,7 @@ export const ModelWithDefaultValuesOptionalDefaultsSchema =

> default: `false`
If you need a separate model type that includes all the relation fields you can pass the following option. Due do the type annotation, that is needed to have recursive types, this model has some limitations since `z.ZodType<myType>` does not allow some object methods like `.merge()`, `.omit()`, etc.
If you need a separate model type that includes all the relation fields you can pass the following option. Due to the type annotation, that is needed to have recursive types, this model has some limitations since `z.ZodType<myType>` does not allow some object methods like `.merge()`, `.omit()`, etc.

```prisma
generator zod {
Expand Down Expand Up @@ -310,7 +310,7 @@ export const UserSchema = z.object({
enum: AnotherEnumSchema,
id: z.string().cuid(),
email: z.string(),
name: z.string(),
name: z.string().optional(),
scalarList: z.string().array(),
lat: z.number(),
lng: z.number(),
Expand Down Expand Up @@ -868,11 +868,11 @@ model MyModel {

## BigInt validators

To add custom validators to the prisma `BigInt` field you can use the `@zod.bigint` key. Due to the fact that there are no custom validators provided by `zod` on `z.bigint()` you can only add customized type errors to the field.
To add custom validators to the prisma `BigInt` field you can use the `@zod.bigint` key. On this key you can use all string-specific validators that are mentioned in the [`zod-docs`](https://github.com/colinhacks/zod#bigints). You can also add a custom error message to each validator as stated in the docs.

```prisma
model MyModel {
myField BigInt /// @zod.bigint({ invalid_type_error: "error", ... })
myField BigInt /// @zod.bigintlt(5n, { message: "lt error" }).gt(6n, { message: "gt error" })({ invalid_type_error: "error", ... }).[...chain more validators]
}
```

Expand Down
4 changes: 2 additions & 2 deletions packages/generator/package.json
@@ -1,6 +1,6 @@
{
"name": "zod-prisma-types",
"version": "2.3.6",
"version": "2.4.0",
"description": "Generates zod schemas from Prisma models with advanced validation",
"author": "Chris Hörmann",
"license": "MIT",
Expand Down Expand Up @@ -49,6 +49,6 @@
"@prisma/generator-helper": "^4.10.1",
"code-block-writer": "^11.0.3",
"lodash": "^4.17.21",
"zod": "^3.20.6"
"zod": "^3.21.4"
}
}
Expand Up @@ -386,6 +386,12 @@ describe(`ExtendedDMMFFieldValidatorMap test _validatorMap`, () => {
pattern: '.url()',
}),
).toBe(true);
expect(
map({
key: 'emoji',
pattern: '.emoji()',
}),
).toBe(true);
expect(
map({
key: 'uuid',
Expand All @@ -398,6 +404,30 @@ describe(`ExtendedDMMFFieldValidatorMap test _validatorMap`, () => {
pattern: '.cuid()',
}),
).toBe(true);
expect(
map({
key: 'cuid2',
pattern: '.cuid2()',
}),
).toBe(true);
expect(
map({
key: 'ulid',
pattern: '.ulid()',
}),
).toBe(true);
expect(
map({
key: 'regex',
pattern: '.regex(/^\\d+\\s*\\d+$/)',
}),
).toBe(true);
expect(
map({
key: 'includes',
pattern: '.includes("some")',
}),
).toBe(true);
expect(
map({
key: 'startsWith',
Expand All @@ -410,6 +440,18 @@ describe(`ExtendedDMMFFieldValidatorMap test _validatorMap`, () => {
pattern: '.startsWith("some")',
}),
).toBe(true);
expect(
map({
key: 'datetime',
pattern: '.datetime()',
}),
).toBe(true);
expect(
map({
key: 'ip',
pattern: '.ip()',
}),
).toBe(true);
expect(
map({
key: 'trim',
Expand All @@ -418,8 +460,14 @@ describe(`ExtendedDMMFFieldValidatorMap test _validatorMap`, () => {
).toBe(true);
expect(
map({
key: 'datetime',
pattern: '.datetime()',
key: 'toLowerCase',
pattern: '.toLowerCase()',
}),
).toBe(true);
expect(
map({
key: 'toUpperCase',
pattern: '.toUpperCase()',
}),
).toBe(true);
expect(
Expand Down Expand Up @@ -468,6 +516,12 @@ describe(`ExtendedDMMFFieldValidatorMap test _validatorMap`, () => {
pattern: '.url({ message: "someMessage" })',
}),
).toBe(true);
expect(
map({
key: 'emoji',
pattern: '.emoji({ message: "someMessage" })',
}),
).toBe(true);
expect(
map({
key: 'uuid',
Expand All @@ -480,6 +534,30 @@ describe(`ExtendedDMMFFieldValidatorMap test _validatorMap`, () => {
pattern: '.cuid({ message: "someMessage" })',
}),
).toBe(true);
expect(
map({
key: 'cuid2',
pattern: '.cuid2({ message: "someMessage" })',
}),
).toBe(true);
expect(
map({
key: 'ulid',
pattern: '.ulid({ message: "someMessage" })',
}),
).toBe(true);
// expect(
// map({
// key: 'regex',
// pattern: '.regex(/^\\d+\\s*\\d+$/)',
// }),
// ).toBe(true);
expect(
map({
key: 'includes',
pattern: '.includes("some", { message: "someMessage" })',
}),
).toBe(true);
expect(
map({
key: 'startsWith',
Expand All @@ -492,6 +570,12 @@ describe(`ExtendedDMMFFieldValidatorMap test _validatorMap`, () => {
pattern: '.startsWith("some", { message: "someMessage" })',
}),
).toBe(true);
expect(
map({
key: 'datetime',
pattern: '.datetime({ message: "someMessage" })',
}),
).toBe(true);
expect(
map({
key: 'trim',
Expand All @@ -500,8 +584,14 @@ describe(`ExtendedDMMFFieldValidatorMap test _validatorMap`, () => {
).toBe(true);
expect(
map({
key: 'datetime',
pattern: '.datetime({ message: "someMessage" })',
key: 'toLowerCase',
pattern: '.toLowerCase({ message: "someMessage" })',
}),
).toBe(true);
expect(
map({
key: 'toUpperCase',
pattern: '.toUpperCase({ message: "someMessage" })',
}),
).toBe(true);
expect(map({ key: 'noDefault', pattern: '.noDefault()' })).toBe(true);
Expand Down Expand Up @@ -805,6 +895,60 @@ describe(`ExtendedDMMFFieldValidatorMap test _validatorMap`, () => {

it(`should pass valid bigint data to validator map`, async () => {
const map = field?.['_validatorMap']['bigint'];
expect(
map({
key: 'gt',
pattern: '.gt(2n)',
}),
).toBe(true);
expect(
map({
key: 'gte',
pattern: '.gte(2n)',
}),
).toBe(true);
expect(
map({
key: 'lt',
pattern: '.lt(2n)',
}),
).toBe(true);
expect(
map({
key: 'lte',
pattern: '.lte(2n)',
}),
).toBe(true);
expect(
map({
key: 'multipleOf',
pattern: '.multipleOf(2n)',
}),
).toBe(true);
expect(
map({
key: 'positive',
pattern: '.positive()',
}),
).toBe(true);
expect(
map({
key: 'nonpositive',
pattern: '.nonpositive()',
}),
).toBe(true);
expect(
map({
key: 'negative',
pattern: '.negative()',
}),
).toBe(true);
expect(
map({
key: 'nonnegative',
pattern: '.nonnegative()',
}),
).toBe(true);
expect(
map({
key: 'array',
Expand All @@ -815,7 +959,60 @@ describe(`ExtendedDMMFFieldValidatorMap test _validatorMap`, () => {

it(`should pass ivalid data to to validator map`, async () => {
const map = field?.['_validatorMap']['bigint'];

expect(
map({
key: 'gt',
pattern: '.gt(2n, { message: "someMessage" })',
}),
).toBe(true);
expect(
map({
key: 'gte',
pattern: '.gte(2n, { message: "someMessage" })',
}),
).toBe(true);
expect(
map({
key: 'lt',
pattern: '.lt(2n, { message: "someMessage" })',
}),
).toBe(true);
expect(
map({
key: 'lte',
pattern: '.lte(2n, { message: "someMessage" })',
}),
).toBe(true);
expect(
map({
key: 'multipleOf',
pattern: '.multipleOf(2n, { message: "someMessage" })',
}),
).toBe(true);
expect(
map({
key: 'positive',
pattern: '.positive({ message: "someMessage" })',
}),
).toBe(true);
expect(
map({
key: 'nonpositive',
pattern: '.nonpositive({ message: "someMessage" })',
}),
).toBe(true);
expect(
map({
key: 'negative',
pattern: '.negative({ message: "someMessage" })',
}),
).toBe(true);
expect(
map({
key: 'nonnegative',
pattern: '.nonnegative({ message: "someMessage" })',
}),
).toBe(true);
expect(() =>
map({
key: 'array',
Expand Down

0 comments on commit 0a61621

Please sign in to comment.