Skip to content

Commit e9c3067

Browse files
authored
Merge pull request #13 from Code-Hex/add/notAllowEmptyString
added notAllowEmptyString option in config
2 parents d45d3ce + babacae commit e9c3067

File tree

6 files changed

+107
-1
lines changed

6 files changed

+107
-1
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,12 @@ type: `boolean` default: `false`
8585

8686
Generates enum as TypeScript `type` instead of `enum`.
8787

88+
### `notAllowEmptyString`
89+
90+
type: `boolean` default: `false`
91+
92+
Generates validation string schema as do not allow empty characters by default.
93+
8894
### `directives`
8995

9096
type: `DirectiveConfig`

src/config.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,21 @@ export interface ValidationSchemaPluginConfig extends TypeScriptPluginConfig {
7373
* ```
7474
*/
7575
enumsAsTypes?: boolean;
76+
/**
77+
* @description Generates validation string schema as do not allow empty characters by default.
78+
* @default false
79+
*
80+
* @exampleMarkdown
81+
* ```yml
82+
* generates:
83+
* path/to/file.ts:
84+
* plugins:
85+
* - graphql-codegen-validation-schema
86+
* config:
87+
* notAllowEmptyString: true
88+
* ```
89+
*/
90+
notAllowEmptyString?: boolean;
7691
/**
7792
* @description Generates validation schema with more API based on directive schema.
7893
* @exampleMarkdown

src/yup/index.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,8 @@ const generateInputObjectFieldTypeYupSchema = (
123123
}
124124
if (isNonNullType(type)) {
125125
const gen = generateInputObjectFieldTypeYupSchema(config, tsVisitor, schema, type.type, type);
126-
return maybeLazy(type.type, `${gen}.defined()`);
126+
const nonNullGen = maybeNonEmptyString(config, tsVisitor, gen, type.type);
127+
return maybeLazy(type.type, nonNullGen);
127128
}
128129
if (isNamedType(type)) {
129130
return generateNameNodeYupSchema(config, tsVisitor, schema, type.name);
@@ -162,6 +163,23 @@ const maybeLazy = (type: TypeNode, schema: string): string => {
162163
return schema;
163164
};
164165

166+
const maybeNonEmptyString = (
167+
config: ValidationSchemaPluginConfig,
168+
tsVisitor: TsVisitor,
169+
schema: string,
170+
childType: TypeNode
171+
): string => {
172+
if (config.notAllowEmptyString === true && isNamedType(childType)) {
173+
const maybeScalarName = childType.name.value;
174+
const tsType = tsVisitor.scalars[maybeScalarName];
175+
if (tsType === 'string') {
176+
return `${schema}.required()`;
177+
}
178+
}
179+
// fallback
180+
return `${schema}.defined()`;
181+
};
182+
165183
const yup4Scalar = (tsVisitor: TsVisitor, scalarName: string): string => {
166184
const tsType = tsVisitor.scalars[scalarName];
167185
switch (tsType) {

src/zod/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,10 @@ const generateInputObjectFieldTypeZodSchema = (
116116
if (isNamedType(type)) {
117117
const gen = generateNameNodeZodSchema(tsVisitor, schema, type.name);
118118
if (isNonNullType(parentType)) {
119+
if (config.notAllowEmptyString === true) {
120+
const tsType = tsVisitor.scalars[type.name.value];
121+
if (tsType === 'string') return `${gen}.min(1)`;
122+
}
119123
return gen;
120124
}
121125
if (isListType(parentType)) {

tests/yup.spec.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,4 +212,35 @@ describe('yup', () => {
212212
);
213213
expect(result.content).toContain("export const PageTypeSchema = yup.mixed().oneOf(['PUBLIC', 'BASIC_AUTH'])");
214214
});
215+
216+
it('with notAllowEmptyString', async () => {
217+
const schema = buildSchema(/* GraphQL */ `
218+
input PrimitiveInput {
219+
a: ID!
220+
b: String!
221+
c: Boolean!
222+
d: Int!
223+
e: Float!
224+
}
225+
`);
226+
const result = await plugin(
227+
schema,
228+
[],
229+
{
230+
notAllowEmptyString: true,
231+
},
232+
{}
233+
);
234+
const wantContains = [
235+
'export function PrimitiveInputSchema(): yup.SchemaOf<PrimitiveInput>',
236+
'a: yup.string().required(),',
237+
'b: yup.string().required(),',
238+
'c: yup.boolean().defined(),',
239+
'd: yup.number().defined(),',
240+
'e: yup.number().defined()',
241+
];
242+
for (const wantContain of wantContains) {
243+
expect(result.content).toContain(wantContain);
244+
}
245+
});
215246
});

tests/zod.spec.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,4 +215,36 @@ describe('zod', () => {
215215
);
216216
expect(result.content).toContain("export const PageTypeSchema = z.enum(['PUBLIC', 'BASIC_AUTH'])");
217217
});
218+
219+
it('with notAllowEmptyString', async () => {
220+
const schema = buildSchema(/* GraphQL */ `
221+
input PrimitiveInput {
222+
a: ID!
223+
b: String!
224+
c: Boolean!
225+
d: Int!
226+
e: Float!
227+
}
228+
`);
229+
const result = await plugin(
230+
schema,
231+
[],
232+
{
233+
schema: 'zod',
234+
notAllowEmptyString: true,
235+
},
236+
{}
237+
);
238+
const wantContains = [
239+
'export function PrimitiveInputSchema(): z.ZodSchema<PrimitiveInput>',
240+
'a: z.string().min(1),',
241+
'b: z.string().min(1),',
242+
'c: z.boolean(),',
243+
'd: z.number(),',
244+
'e: z.number()',
245+
];
246+
for (const wantContain of wantContains) {
247+
expect(result.content).toContain(wantContain);
248+
}
249+
});
218250
});

0 commit comments

Comments
 (0)