File tree Expand file tree Collapse file tree 7 files changed +121
-12
lines changed Expand file tree Collapse file tree 7 files changed +121
-12
lines changed Original file line number Diff line number Diff line change @@ -212,9 +212,8 @@ const generateFieldTypeMyZodSchema = (
212212 }
213213 const appliedDirectivesGen = applyDirectives ( config , field , gen ) ;
214214 if ( isNonNullType ( parentType ) ) {
215- if ( config . notAllowEmptyString === true ) {
216- const tsType = visitor . getScalarType ( type . name . value ) ;
217- if ( tsType === 'string' ) return `${ gen } .min(1)` ;
215+ if ( visitor . shouldEmitAsNotAllowEmptyString ( type . name . value ) ) {
216+ return `${ gen } .min(1)` ;
218217 }
219218 return appliedDirectivesGen ;
220219 }
Original file line number Diff line number Diff line change 11import { TsVisitor } from '@graphql-codegen/typescript' ;
2- import { GraphQLSchema , NameNode } from 'graphql' ;
2+ import { GraphQLSchema , NameNode , specifiedScalarTypes } from 'graphql' ;
33
44import { ValidationSchemaPluginConfig } from './config' ;
55
66export class Visitor extends TsVisitor {
77 constructor (
88 private scalarDirection : 'input' | 'output' | 'both' ,
99 private schema : GraphQLSchema ,
10- config : ValidationSchemaPluginConfig
10+ private pluginConfig : ValidationSchemaPluginConfig
1111 ) {
12- super ( schema , config ) ;
12+ super ( schema , pluginConfig ) ;
13+ }
14+
15+ private isSpecifiedScalarName ( scalarName : string ) {
16+ return specifiedScalarTypes . some ( ( { name } ) => name === scalarName ) ;
1317 }
1418
1519 public getType ( name : string ) {
@@ -34,4 +38,16 @@ export class Visitor extends TsVisitor {
3438 }
3539 return this . scalars [ scalarName ] [ this . scalarDirection ] ;
3640 }
41+
42+ public shouldEmitAsNotAllowEmptyString ( name : string ) : boolean {
43+ if ( this . pluginConfig . notAllowEmptyString !== true ) {
44+ return false ;
45+ }
46+ const typ = this . getType ( name ) ;
47+ if ( typ ?. astNode ?. kind !== 'ScalarTypeDefinition' && ! this . isSpecifiedScalarName ( name ) ) {
48+ return false ;
49+ }
50+ const tsType = this . getScalarType ( name ) ;
51+ return tsType === 'string' ;
52+ }
3753}
Original file line number Diff line number Diff line change @@ -262,9 +262,8 @@ const generateFieldTypeYupSchema = (
262262 if ( isNamedType ( type ) ) {
263263 const gen = generateNameNodeYupSchema ( config , visitor , type . name ) ;
264264 if ( isNonNullType ( parentType ) ) {
265- if ( config . notAllowEmptyString === true ) {
266- const tsType = visitor . getScalarType ( type . name . value ) ;
267- if ( tsType === 'string' ) return `${ gen } .required()` ;
265+ if ( visitor . shouldEmitAsNotAllowEmptyString ( type . name . value ) ) {
266+ return `${ gen } .required()` ;
268267 }
269268 return `${ gen } .nonNullable()` ;
270269 }
Original file line number Diff line number Diff line change @@ -222,9 +222,8 @@ const generateFieldTypeZodSchema = (
222222 }
223223 const appliedDirectivesGen = applyDirectives ( config , field , gen ) ;
224224 if ( isNonNullType ( parentType ) ) {
225- if ( config . notAllowEmptyString === true ) {
226- const tsType = visitor . getScalarType ( type . name . value ) ;
227- if ( tsType === 'string' ) return `${ appliedDirectivesGen } .min(1)` ;
225+ if ( visitor . shouldEmitAsNotAllowEmptyString ( type . name . value ) ) {
226+ return `${ appliedDirectivesGen } .min(1)` ;
228227 }
229228 return appliedDirectivesGen ;
230229 }
Original file line number Diff line number Diff line change 11import { buildSchema } from 'graphql' ;
2+ import dedent from 'ts-dedent' ;
23
34import { plugin } from '../src/index' ;
45
@@ -297,6 +298,37 @@ describe('myzod', () => {
297298 }
298299 } ) ;
299300
301+ it ( 'with notAllowEmptyString issue #386' , async ( ) => {
302+ const schema = buildSchema ( /* GraphQL */ `
303+ input InputOne {
304+ field: InputNested!
305+ }
306+
307+ input InputNested {
308+ field: String!
309+ }
310+ ` ) ;
311+ const result = await plugin (
312+ schema ,
313+ [ ] ,
314+ {
315+ schema : 'myzod' ,
316+ notAllowEmptyString : true ,
317+ scalars : {
318+ ID : 'string' ,
319+ } ,
320+ } ,
321+ { }
322+ ) ;
323+ const wantContain = dedent `
324+ export function InputNestedSchema(): myzod.Type<InputNested> {
325+ return myzod.object({
326+ field: myzod.string().min(1)
327+ })
328+ }` ;
329+ expect ( result . content ) . toContain ( wantContain ) ;
330+ } ) ;
331+
300332 it ( 'with scalarSchemas' , async ( ) => {
301333 const schema = buildSchema ( /* GraphQL */ `
302334 input ScalarsInput {
Original file line number Diff line number Diff line change 11import { buildSchema } from 'graphql' ;
2+ import dedent from 'ts-dedent' ;
23
34import { plugin } from '../src/index' ;
45
@@ -294,6 +295,37 @@ describe('yup', () => {
294295 }
295296 } ) ;
296297
298+ it ( 'with notAllowEmptyString issue #386' , async ( ) => {
299+ const schema = buildSchema ( /* GraphQL */ `
300+ input InputOne {
301+ field: InputNested!
302+ }
303+
304+ input InputNested {
305+ field: String!
306+ }
307+ ` ) ;
308+ const result = await plugin (
309+ schema ,
310+ [ ] ,
311+ {
312+ schema : 'yup' ,
313+ notAllowEmptyString : true ,
314+ scalars : {
315+ ID : 'string' ,
316+ } ,
317+ } ,
318+ { }
319+ ) ;
320+ const wantContain = dedent `
321+ export function InputNestedSchema(): yup.ObjectSchema<InputNested> {
322+ return yup.object({
323+ field: yup.string().defined().required()
324+ })
325+ }` ;
326+ expect ( result . content ) . toContain ( wantContain ) ;
327+ } ) ;
328+
297329 it ( 'with scalarSchemas' , async ( ) => {
298330 const schema = buildSchema ( /* GraphQL */ `
299331 input ScalarsInput {
Original file line number Diff line number Diff line change 11import { buildSchema } from 'graphql' ;
2+ import { dedent } from 'ts-dedent' ;
23
34import { plugin } from '../src/index' ;
45
@@ -297,6 +298,37 @@ describe('zod', () => {
297298 }
298299 } ) ;
299300
301+ it ( 'with notAllowEmptyString issue #386' , async ( ) => {
302+ const schema = buildSchema ( /* GraphQL */ `
303+ input InputOne {
304+ field: InputNested!
305+ }
306+
307+ input InputNested {
308+ field: String!
309+ }
310+ ` ) ;
311+ const result = await plugin (
312+ schema ,
313+ [ ] ,
314+ {
315+ schema : 'zod' ,
316+ notAllowEmptyString : true ,
317+ scalars : {
318+ ID : 'string' ,
319+ } ,
320+ } ,
321+ { }
322+ ) ;
323+ const wantContain = dedent `
324+ export function InputNestedSchema(): z.ZodObject<Properties<InputNested>> {
325+ return z.object({
326+ field: z.string().min(1)
327+ })
328+ }` ;
329+ expect ( result . content ) . toContain ( wantContain ) ;
330+ } ) ;
331+
300332 it ( 'with scalarSchemas' , async ( ) => {
301333 const schema = buildSchema ( /* GraphQL */ `
302334 input ScalarsInput {
You can’t perform that action at this time.
0 commit comments