Skip to content

Commit 153ab4e

Browse files
authored
Merge pull request #847 from jocisneros/jcisneros/default-scalarTypeSchema
2 parents ee9f2e1 + 75a2f09 commit 153ab4e

File tree

10 files changed

+200
-0
lines changed

10 files changed

+200
-0
lines changed

README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,26 @@ config:
215215
Email: z.string().email()
216216
```
217217

218+
### `defaultScalarTypeSchema`
219+
220+
type: `string`
221+
222+
Fallback scalar type for undefined scalar types in the schema not found in `scalarSchemas`.
223+
224+
#### yup schema
225+
```yml
226+
config:
227+
schema: yup
228+
defaultScalarSchema: yup.unknown()
229+
```
230+
231+
#### zod schema
232+
```yml
233+
config:
234+
schema: zod
235+
defaultScalarSchema: z.unknown()
236+
```
237+
218238
### `withObjectType`
219239

220240
type: `boolean` default: `false`

src/config.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,24 @@ export interface ValidationSchemaPluginConfig extends TypeScriptPluginConfig {
196196
* ```
197197
*/
198198
scalarSchemas?: ScalarSchemas
199+
/**
200+
* @description Fallback scalar type for undefined scalar types in the schema not found in `scalarSchemas`.
201+
*
202+
* @exampleMarkdown
203+
* ```yml
204+
* config:
205+
* schema: yup
206+
* defaultScalarSchema: yup.unknown()
207+
* ```
208+
*
209+
* @exampleMarkdown
210+
* ```yml
211+
* config:
212+
* schema: zod
213+
* defaultScalarSchema: z.unknown()
214+
* ```
215+
*/
216+
defaultScalarTypeSchema?: string
199217
/**
200218
* @description Generates validation schema with GraphQL type objects.
201219
* but excludes "Query", "Mutation", "Subscription" objects.

src/myzod/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,11 @@ function myzod4Scalar(config: ValidationSchemaPluginConfig, visitor: Visitor, sc
378378
case 'boolean':
379379
return `myzod.boolean()`;
380380
}
381+
382+
if (config.defaultScalarTypeSchema) {
383+
return config.defaultScalarTypeSchema;
384+
}
385+
381386
console.warn('unhandled name:', scalarName);
382387
return anySchema;
383388
}

src/valibot/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,11 @@ function valibot4Scalar(config: ValidationSchemaPluginConfig, visitor: Visitor,
303303
case 'boolean':
304304
return `v.boolean()`;
305305
}
306+
307+
if (config.defaultScalarTypeSchema) {
308+
return config.defaultScalarTypeSchema;
309+
}
310+
306311
console.warn('unhandled scalar name:', scalarName);
307312
return 'v.any()';
308313
}

src/yup/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,11 @@ function yup4Scalar(config: ValidationSchemaPluginConfig, visitor: Visitor, scal
401401
case 'boolean':
402402
return `yup.boolean().defined()`;
403403
}
404+
405+
if (config.defaultScalarTypeSchema) {
406+
return config.defaultScalarTypeSchema
407+
}
408+
404409
console.warn('unhandled name:', scalarName);
405410
return `yup.mixed()`;
406411
}

src/zod/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,11 @@ function zod4Scalar(config: ValidationSchemaPluginConfig, visitor: Visitor, scal
394394
case 'boolean':
395395
return `z.boolean()`;
396396
}
397+
398+
if (config.defaultScalarTypeSchema) {
399+
return config.defaultScalarTypeSchema;
400+
}
401+
397402
console.warn('unhandled scalar name:', scalarName);
398403
return anySchema;
399404
}

tests/myzod.spec.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -587,6 +587,41 @@ describe('myzod', () => {
587587
"
588588
`)
589589
});
590+
591+
it('with defaultScalarTypeSchema', async () => {
592+
const schema = buildSchema(/* GraphQL */ `
593+
input ScalarsInput {
594+
date: Date!
595+
email: Email
596+
str: String!
597+
}
598+
scalar Date
599+
scalar Email
600+
`);
601+
const result = await plugin(
602+
schema,
603+
[],
604+
{
605+
schema: 'myzod',
606+
scalarSchemas: {
607+
Email: 'myzod.string()', // generate the basic type. User can later extend it using `withPredicate(fn: (val: string) => boolean), errMsg?: string }`
608+
},
609+
defaultScalarTypeSchema: 'myzod.string()',
610+
},
611+
{},
612+
);
613+
expect(removedInitialEmitValue(result.content)).toMatchInlineSnapshot(`
614+
"
615+
export function ScalarsInputSchema(): myzod.Type<ScalarsInput> {
616+
return myzod.object({
617+
date: myzod.string(),
618+
email: myzod.string().optional().nullable(),
619+
str: myzod.string()
620+
})
621+
}
622+
"
623+
`)
624+
});
590625
it('with typesPrefix', async () => {
591626
const schema = buildSchema(/* GraphQL */ `
592627
input Say {

tests/valibot.spec.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,43 @@ describe('valibot', () => {
551551
"
552552
`)
553553
});
554+
555+
it('with defaultScalarTypeSchema', async () => {
556+
const schema = buildSchema(/* GraphQL */ `
557+
input ScalarsInput {
558+
date: Date!
559+
email: Email
560+
str: String!
561+
}
562+
scalar Date
563+
scalar Email
564+
`);
565+
const result = await plugin(
566+
schema,
567+
[],
568+
{
569+
schema: 'valibot',
570+
scalarSchemas: {
571+
Email: 'v.string([v.email()])',
572+
},
573+
defaultScalarTypeSchema: 'v.string()',
574+
},
575+
{},
576+
);
577+
expect(result.content).toMatchInlineSnapshot(`
578+
"
579+
580+
export function ScalarsInputSchema(): v.GenericSchema<ScalarsInput> {
581+
return v.object({
582+
date: v.string(),
583+
email: v.nullish(v.string([v.email()])),
584+
str: v.string()
585+
})
586+
}
587+
"
588+
`)
589+
});
590+
554591
it('with typesPrefix', async () => {
555592
const schema = buildSchema(/* GraphQL */ `
556593
input Say {

tests/yup.spec.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -602,6 +602,41 @@ describe('yup', () => {
602602
`)
603603
});
604604

605+
it('with defaultScalarTypeSchema', async () => {
606+
const schema = buildSchema(/* GraphQL */ `
607+
input ScalarsInput {
608+
date: Date!
609+
email: Email
610+
str: String!
611+
}
612+
scalar Date
613+
scalar Email
614+
`);
615+
const result = await plugin(
616+
schema,
617+
[],
618+
{
619+
scalarSchemas: {
620+
Email: 'yup.string().email()',
621+
},
622+
defaultScalarTypeSchema: 'yup.string()',
623+
},
624+
{},
625+
);
626+
expect(result.content).toMatchInlineSnapshot(`
627+
"
628+
629+
export function ScalarsInputSchema(): yup.ObjectSchema<ScalarsInput> {
630+
return yup.object({
631+
date: yup.string().nonNullable(),
632+
email: yup.string().email().defined().nullable().optional(),
633+
str: yup.string().defined().nonNullable()
634+
})
635+
}
636+
"
637+
`)
638+
});
639+
605640
it('with typesPrefix', async () => {
606641
const schema = buildSchema(/* GraphQL */ `
607642
input Say {

tests/zod.spec.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,41 @@ describe('zod', () => {
584584
`)
585585
});
586586

587+
it('with defaultScalarTypeSchema', async () => {
588+
const schema = buildSchema(/* GraphQL */ `
589+
input ScalarsInput {
590+
date: Date!
591+
email: Email
592+
str: String!
593+
}
594+
scalar Date
595+
scalar Email
596+
`);
597+
const result = await plugin(
598+
schema,
599+
[],
600+
{
601+
schema: 'zod',
602+
scalarSchemas: {
603+
Email: 'z.string().email()',
604+
},
605+
defaultScalarTypeSchema: 'z.string()',
606+
},
607+
{},
608+
);
609+
expect(removedInitialEmitValue(result.content)).toMatchInlineSnapshot(`
610+
"
611+
export function ScalarsInputSchema(): z.ZodObject<Properties<ScalarsInput>> {
612+
return z.object({
613+
date: z.string(),
614+
email: z.string().email().nullish(),
615+
str: z.string()
616+
})
617+
}
618+
"
619+
`)
620+
});
621+
587622
it('with typesPrefix', async () => {
588623
const schema = buildSchema(/* GraphQL */ `
589624
input Say {

0 commit comments

Comments
 (0)