GitHub - Code-Hex/graphql-codegen-typescript-validation-schema: GraphQL Code Generator plugin to generate form validation schema from your GraphQL schema

Test npm version

GraphQL code generator plugin to generate form validation schema from your GraphQL schema.

Quick Start

Start by installing this plugin and write simple plugin config;

$ npm i graphql-codegen-typescript-validation-schema
generates:
  path/to/graphql.ts:
    plugins:
      - typescript
      - typescript-validation-schema # specify to use this plugin
    config:
      # You can put the config for typescript plugin here
      # see: https://www.graphql-code-generator.com/plugins/typescript
      strictScalars: true
      # Overrides built-in ID scalar to both input and output types as string.
      # see: https://the-guild.dev/graphql/codegen/plugins/typescript/typescript#scalars
      scalars:
        ID: string
      # You can also write the config for this plugin together
      schema: yup # or zod

It is recommended to write scalars config for built-in type ID, as in the yaml example shown above. For more information: #375

You can check example directory if you want to see more complex config example or how is generated some files.

The Q&A for each schema is written in the README in the respective example directory.

Config API Reference

schema

type: ValidationSchema default: 'yup'

Specify generete validation schema you want.

You can specify yup or zod or zodv4 or myzod or valibot.

generates:
  path/to/graphql.ts:
    plugins:
      - typescript
      - typescript-validation-schema
    config:
      schema: yup

zodImportPath

type: string default: 'zod'

Specifies a custom import path for the zod package. This is useful when you want to use a specific version or subpath of zod, such as the v3 compatibility layer in zod v4 ('zod/v3'). Only applies when schema is set to 'zod'.

generates:
  path/to/schemas.ts:
    plugins:
      - typescript
      - typescript-validation-schema
    config:
      schema: zod
      # Use zod v3 compatibility layer when using zod v4
      zodImportPath: zod/v3

importFrom

type: string

When provided, import types from the generated typescript types file path. if not given, omit import statement.

generates:
  path/to/graphql.ts:
    plugins:
      - typescript
  path/to/validation.ts:
    plugins:
      - typescript-validation-schema
    config:
      importFrom: ./graphql # path for generated ts code

Then the generator generates code with import statement like below.

import { GeneratedInput } from './graphql'

/* generates validation schema here */

schemaNamespacedImportName

type: string

If defined, will use named imports from the specified module (defined in importFrom) rather than individual imports for each type.

generates:
  path/to/types.ts:
    plugins:
      - typescript
  path/to/schemas.ts:
    plugins:
      - graphql-codegen-validation-schema
    config:
      schema: yup
      importFrom: ./path/to/types
      schemaNamespacedImportName: types

Then the generator generates code with import statement like below.

import * as types from './graphql'

/* generates validation schema here */

useTypeImports

type: boolean default: false

Will use import type {} rather than import {} when importing generated TypeScript types. This gives compatibility with TypeScript's "importsNotUsedAsValues": "error" option. Should used in conjunction with importFrom option.

typesPrefix

type: string default: (empty)

Prefixes all import types from generated typescript type.

generates:
  path/to/graphql.ts:
    plugins:
      - typescript
  path/to/validation.ts:
    plugins:
      - typescript-validation-schema
    config:
      typesPrefix: I
      importFrom: ./graphql # path for generated ts code

Then the generator generates code with import statement like below.

import { IGeneratedInput } from './graphql'

/* generates validation schema here */

typesSuffix

type: string default: (empty)

Suffixes all import types from generated typescript type.

generates:
  path/to/graphql.ts:
    plugins:
      - typescript
  path/to/validation.ts:
    plugins:
      - typescript-validation-schema
    config:
      typesSuffix: I
      importFrom: ./graphql # path for generated ts code

Then the generator generates code with import statement like below.

import { GeneratedInputI } from './graphql'

/* generates validation schema here */

enumsAsTypes

type: boolean default: false

Generates enum as TypeScript type instead of enum.

notAllowEmptyString

type: boolean default: false

Generates validation string schema as do not allow empty characters by default.

scalarSchemas

type: ScalarSchemas

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

yup schema

config:
  schema: yup
  scalarSchemas:
    Date: yup.date()
    Email: yup.string().email()

zod schema

config:
  schema: zod
  scalarSchemas:
    Date: z.date()
    Email: z.string().email()

zodv4 schema

config:
  schema: zodv4
  scalarSchemas:
    Date: z.date()
    Email: z.string().email()

defaultScalarTypeSchema

type: string

Fallback scalar type for undefined scalar types in the schema not found in scalarSchemas.

yup schema

config:
  schema: yup
  defaultScalarSchema: yup.unknown()

zod schema

config:
  schema: zod
  defaultScalarSchema: z.unknown()

zodv4 schema

config:
  schema: zodv4
  defaultScalarSchema: z.unknown()

withObjectType

type: boolean default: false

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

It is currently added for the purpose of using simple objects. See also #20, #107.

This option currently does not support fragment generation. If you are interested, send me PR would be greatly appreciated!

validationSchemaExportType

type: ValidationSchemaExportType default: 'function'

Specify validation schema export type.

useEnumTypeAsDefaultValue

type: boolean default: false

Uses the full path of the enum type as the default value instead of the stringified value.

namingConvention

type: NamingConventionMap default: { enumValues: "change-case-all#pascalCase" }

Uses the full path of the enum type as the default value instead of the stringified value.

Related: https://the-guild.dev/graphql/codegen/docs/config-reference/naming-convention#namingconvention

directives

type: DirectiveConfig

Generates validation schema with more API based on directive schema. For example, yaml config and GraphQL schema is here.

input ExampleInput {
  email: String! @required(msg: "Hello, World!") @constraint(minLength: 50, format: "email")
  message: String! @constraint(startsWith: "Hello")
}

yup schema

generates:
  path/to/graphql.ts:
    plugins:
      - typescript
      - typescript-validation-schema
    config:
      schema: yup
      directives:
        # Write directives like
        #
        # directive:
        #   arg1: schemaApi
        #   arg2: ["schemaApi2", "Hello $1"]
        #
        # See more examples in `./tests/directive.spec.ts`
        # https://github.com/Code-Hex/graphql-codegen-typescript-validation-schema/blob/main/tests/directive.spec.ts
        required:
          msg: required
        constraint:
          minLength: min
          # Replace $1 with specified `startsWith` argument value of the constraint directive
          startsWith: [matches, /^$1/]
          format:
            # This example means `validation-schema: directive-arg`
            # directive-arg is supported String and Enum.
            email: email

Then generates yup validation schema like below.

export function ExampleInputSchema(): yup.SchemaOf<ExampleInput> {
  return yup.object({
    email: yup.string().defined().required('Hello, World!').min(50).email(),
    message: yup.string().defined().matches(/^Hello/)
  })
}

zod schema

generates:
  path/to/graphql.ts:
    plugins:
      - typescript
      - typescript-validation-schema
    config:
      schema: zod
      directives:
        # Write directives like
        #
        # directive:
        #   arg1: schemaApi
        #   arg2: ["schemaApi2", "Hello $1"]
        #
        # See more examples in `./tests/directive.spec.ts`
        # https://github.com/Code-Hex/graphql-codegen-typescript-validation-schema/blob/main/tests/directive.spec.ts
        constraint:
          minLength: min
          # Replace $1 with specified `startsWith` argument value of the constraint directive
          startsWith: [regex, /^$1/, message]
          format:
            # This example means `validation-schema: directive-arg`
            # directive-arg is supported String and Enum.
            email: email

Then generates zod validation schema like below.

export function ExampleInputSchema(): z.ZodSchema<ExampleInput> {
  return z.object({
    email: z.string().min(50).email(),
    message: z.string().regex(/^Hello/, 'message')
  })
}

zodv4 schema

generates:
  path/to/graphql.ts:
    plugins:
      - typescript
      - typescript-validation-schema
    config:
      schema: zodv4
      directives:
        constraint:
          minLength: min
          # Replace $1 with specified `startsWith` argument value of the constraint directive
          startsWith: [regex, /^$1/, message]
          format:
            # This example means `validation-schema: directive-arg`
            # directive-arg is supported String and Enum.
            email: email

Then generates zodv4 validation schema like below.

export function ExampleInputSchema(): z.ZodObject<Properties<ExampleInput>> {
  return z.object({
    email: z.string().min(50).email(),
    message: z.string().regex(/^Hello/, 'message')
  })
}

other schema

Please see example directory.

Notes

Their is currently a compatibility issue with the client-preset. A workaround for this is to split the generation into two (one for client-preset and one for typescript-validation-schema).

generates:
  path/to/graphql.ts:
    plugins:
      - typescript-validation-schema
  /path/to/graphql/:
    preset: 'client',
      plugins:
      ...