Skip to content

fixed some code for #132 (withObjectType) #136

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jul 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,12 @@ type: `ScalarSchemas`

Extends or overrides validation schema for the built-in scalars and custom GraphQL scalars.

### `withObjectType`

type: `boolean` default: `false`

Generates validation schema with GraphQL type objects. But excludes `Query`, `Mutation`, `Subscription` objects.

#### yup schema

```yml
Expand Down
6 changes: 3 additions & 3 deletions codegen.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ generates:
- ./dist/main/index.js:
schema: yup
importFrom: ../types
useObjectTypes: true
withObjectType: true
directives:
required:
msg: required
Expand Down Expand Up @@ -43,7 +43,7 @@ generates:
- ./dist/main/index.js:
schema: zod
importFrom: ../types
useObjectTypes: true
withObjectType: true
directives:
# Write directives like
#
Expand All @@ -64,7 +64,7 @@ generates:
- ./dist/main/index.js:
schema: myzod
importFrom: ../types
useObjectTypes: true
withObjectType: true
directives:
constraint:
minLength: min
Expand Down
37 changes: 19 additions & 18 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,25 @@ export interface ValidationSchemaPluginConfig extends TypeScriptPluginConfig {
* ```
*/
scalarSchemas?: ScalarSchemas;
/**
* @description Generates validation schema with GraphQL type objects.
* but excludes "Query", "Mutation", "Subscription" objects.
*
* @exampleMarkdown
* ```yml
* generates:
* path/to/types.ts:
* plugins:
* - typescript
* path/to/schemas.ts:
* plugins:
* - graphql-codegen-validation-schema
* config:
* schema: yup
* withObjectType: true
* ```
*/
withObjectType?: boolean;
/**
* @description Generates validation schema with more API based on directive schema.
* @exampleMarkdown
Expand Down Expand Up @@ -193,22 +212,4 @@ export interface ValidationSchemaPluginConfig extends TypeScriptPluginConfig {
* ```
*/
directives?: DirectiveConfig;
/**
* @description Converts the regular graphql type into a zod validation function.
*
* @exampleMarkdown
* ```yml
* generates:
* path/to/types.ts:
* plugins:
* - typescript
* path/to/schemas.ts:
* plugins:
* - graphql-codegen-validation-schema
* config:
* schema: yup
* useObjectTypes: true
* ```
*/
useObjectTypes?: boolean;
}
17 changes: 16 additions & 1 deletion src/graphql.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,22 @@
import { ListTypeNode, NonNullTypeNode, NamedTypeNode, TypeNode } from 'graphql';
import { ListTypeNode, NonNullTypeNode, NamedTypeNode, TypeNode, ObjectTypeDefinitionNode } from 'graphql';

export const isListType = (typ?: TypeNode): typ is ListTypeNode => typ?.kind === 'ListType';
export const isNonNullType = (typ?: TypeNode): typ is NonNullTypeNode => typ?.kind === 'NonNullType';
export const isNamedType = (typ?: TypeNode): typ is NamedTypeNode => typ?.kind === 'NamedType';

export const isInput = (kind: string) => kind.includes('Input');

type ObjectTypeDefinitionFn = (node: ObjectTypeDefinitionNode) => any;

export const ObjectTypeDefinitionBuilder = (
useObjectTypes: boolean | undefined,
callback: ObjectTypeDefinitionFn
): ObjectTypeDefinitionFn | undefined => {
if (!useObjectTypes) return undefined;
return node => {
if (/^Query|Mutation|Subscription$/.test(node.name.value)) {
return;
}
return callback(node);
};
};
19 changes: 12 additions & 7 deletions src/myzod/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { isInput, isNonNullType, isListType, isNamedType } from './../graphql';
import { isInput, isNonNullType, isListType, isNamedType, ObjectTypeDefinitionBuilder } from './../graphql';
import { ValidationSchemaPluginConfig } from '../config';
import {
InputValueDefinitionNode,
Expand Down Expand Up @@ -49,8 +49,7 @@ export const MyZodSchemaVisitor = (schema: GraphQLSchema, config: ValidationSche
.withName(`${name}Schema(): myzod.Type<${name}>`)
.withBlock([indent(`return myzod.object({`), shape, indent('})')].join('\n')).string;
},
ObjectTypeDefinition: (node: ObjectTypeDefinitionNode) => {
if (!config.useObjectTypes) return;
ObjectTypeDefinition: ObjectTypeDefinitionBuilder(config.withObjectType, (node: ObjectTypeDefinitionNode) => {
const name = tsVisitor.convertName(node.name.value);
importTypes.push(name);

Expand All @@ -65,11 +64,12 @@ export const MyZodSchemaVisitor = (schema: GraphQLSchema, config: ValidationSche
.withBlock(
[
indent(`return myzod.object({`),
` __typename: myzod.literal('${node.name.value}').optional(),\n${shape}`,
indent(`__typename: myzod.literal('${node.name.value}').optional(),`, 2),
shape,
indent('})'),
].join('\n')
).string;
},
}),
EnumTypeDefinition: (node: EnumTypeDefinitionNode) => {
const enumname = tsVisitor.convertName(node.name.value);
importTypes.push(enumname);
Expand Down Expand Up @@ -166,12 +166,17 @@ const generateNameNodeMyZodSchema = (
): string => {
const typ = schema.getType(node.value);

if (typ && typ.astNode?.kind === 'InputObjectTypeDefinition') {
if (typ?.astNode?.kind === 'InputObjectTypeDefinition') {
const enumName = tsVisitor.convertName(typ.astNode.name.value);
return `${enumName}Schema()`;
}

if (typ?.astNode?.kind === 'ObjectTypeDefinition') {
const enumName = tsVisitor.convertName(typ.astNode.name.value);
return `${enumName}Schema()`;
}

if (typ && typ.astNode?.kind === 'EnumTypeDefinition') {
if (typ?.astNode?.kind === 'EnumTypeDefinition') {
const enumName = tsVisitor.convertName(typ.astNode.name.value);
return `${enumName}Schema`;
}
Expand Down
26 changes: 18 additions & 8 deletions src/yup/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { isInput, isNonNullType, isListType, isNamedType } from './../graphql';
import { isInput, isNonNullType, isListType, isNamedType, ObjectTypeDefinitionBuilder } from './../graphql';
import { ValidationSchemaPluginConfig } from '../config';
import {
InputValueDefinitionNode,
Expand Down Expand Up @@ -41,8 +41,7 @@ export const YupSchemaVisitor = (schema: GraphQLSchema, config: ValidationSchema
.withName(`${name}Schema(): yup.SchemaOf<${name}>`)
.withBlock([indent(`return yup.object({`), shape, indent('})')].join('\n')).string;
},
ObjectTypeDefinition: (node: ObjectTypeDefinitionNode) => {
if (!config.useObjectTypes) return;
ObjectTypeDefinition: ObjectTypeDefinitionBuilder(config.withObjectType, (node: ObjectTypeDefinitionNode) => {
const name = tsVisitor.convertName(node.name.value);
importTypes.push(name);

Expand All @@ -55,11 +54,12 @@ export const YupSchemaVisitor = (schema: GraphQLSchema, config: ValidationSchema
.withBlock(
[
indent(`return yup.object({`),
` __typename: yup.mixed().oneOf(['${node.name.value}', undefined]),\n${shape}`,
indent(`__typename: yup.mixed().oneOf(['${node.name.value}', undefined]),`, 2),
shape,
indent('})'),
].join('\n')
).string;
},
}),
EnumTypeDefinition: (node: EnumTypeDefinitionNode) => {
const enumname = tsVisitor.convertName(node.name.value);
importTypes.push(enumname);
Expand Down Expand Up @@ -146,7 +146,12 @@ const generateFieldTypeYupSchema = (
return maybeLazy(type.type, nonNullGen);
}
if (isNamedType(type)) {
return generateNameNodeYupSchema(config, tsVisitor, schema, type.name);
const gen = generateNameNodeYupSchema(config, tsVisitor, schema, type.name);
const typ = schema.getType(type.name.value);
if (typ?.astNode?.kind === 'ObjectTypeDefinition') {
return `${gen}.optional()`;
}
return gen;
}
console.warn('unhandled type:', type);
return '';
Expand All @@ -160,12 +165,17 @@ const generateNameNodeYupSchema = (
): string => {
const typ = schema.getType(node.value);

if (typ && typ.astNode?.kind === 'InputObjectTypeDefinition') {
if (typ?.astNode?.kind === 'InputObjectTypeDefinition') {
const enumName = tsVisitor.convertName(typ.astNode.name.value);
return `${enumName}Schema()`;
}

if (typ?.astNode?.kind === 'ObjectTypeDefinition') {
const enumName = tsVisitor.convertName(typ.astNode.name.value);
return `${enumName}Schema()`;
}

if (typ && typ.astNode?.kind === 'EnumTypeDefinition') {
if (typ?.astNode?.kind === 'EnumTypeDefinition') {
const enumName = tsVisitor.convertName(typ.astNode.name.value);
return `${enumName}Schema`;
}
Expand Down
21 changes: 13 additions & 8 deletions src/zod/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { isInput, isNonNullType, isListType, isNamedType } from './../graphql';
import { isInput, isNonNullType, isListType, isNamedType, ObjectTypeDefinitionBuilder } from './../graphql';
import { ValidationSchemaPluginConfig } from '../config';
import {
InputValueDefinitionNode,
Expand Down Expand Up @@ -63,8 +63,7 @@ export const ZodSchemaVisitor = (schema: GraphQLSchema, config: ValidationSchema
.withName(`${name}Schema(): z.ZodObject<Properties<${name}>>`)
.withBlock([indent(`return z.object({`), shape, indent('})')].join('\n')).string;
},
ObjectTypeDefinition: (node: ObjectTypeDefinitionNode) => {
if (!config.useObjectTypes) return;
ObjectTypeDefinition: ObjectTypeDefinitionBuilder(config.withObjectType, (node: ObjectTypeDefinitionNode) => {
const name = tsVisitor.convertName(node.name.value);
importTypes.push(name);

Expand All @@ -77,11 +76,12 @@ export const ZodSchemaVisitor = (schema: GraphQLSchema, config: ValidationSchema
.withBlock(
[
indent(`return z.object({`),
` __typename: z.literal('${node.name.value}').optional(),\n${shape}`,
indent(`__typename: z.literal('${node.name.value}').optional(),`, 2),
shape,
indent('})'),
].join('\n')
).string;
},
}),
EnumTypeDefinition: (node: EnumTypeDefinitionNode) => {
const enumname = tsVisitor.convertName(node.name.value);
importTypes.push(enumname);
Expand Down Expand Up @@ -177,12 +177,17 @@ const generateNameNodeZodSchema = (
): string => {
const typ = schema.getType(node.value);

if (typ && typ.astNode?.kind === 'InputObjectTypeDefinition') {
if (typ?.astNode?.kind === 'InputObjectTypeDefinition') {
const enumName = tsVisitor.convertName(typ.astNode.name.value);
return `${enumName}Schema()`;
}

if (typ?.astNode?.kind === 'ObjectTypeDefinition') {
const enumName = tsVisitor.convertName(typ.astNode.name.value);
return `${enumName}Schema()`;
}

if (typ && typ.astNode?.kind === 'EnumTypeDefinition') {
if (typ?.astNode?.kind === 'EnumTypeDefinition') {
const enumName = tsVisitor.convertName(typ.astNode.name.value);
return `${enumName}Schema`;
}
Expand Down Expand Up @@ -210,6 +215,6 @@ const zod4Scalar = (config: ValidationSchemaPluginConfig, tsVisitor: TsVisitor,
case 'boolean':
return `z.boolean()`;
}
console.warn('unhandled name:', scalarName);
console.warn('unhandled scalar name:', scalarName);
return anySchema;
};
Loading