@eddeee888/gcg-typescript-resolver-files
TypeScript icon, indicating that this package has built-in type declarations

0.7.5 • Public • Published

@eddeee888/gcg-typescript-resolver-files

This GraphQL Code Generator plugin creates resolvers given GraphQL schema.

This relies on types generated from @graphql-codegen/typescript and @graphql-codegen/typescript-resolvers plugins.

yarn add -D @graphql-codegen/cli @eddeee888/gcg-typescript-resolver-files
yarn add graphql-scalars

Features

  • Generates opinionated folder/file structure with type-safety in mind to help finding query, mutation or object types easily
  • Does NOT overwrite existing resolver logic
  • Detects missing / wrong resolver exports and adds them to resolver files
  • Automatically sets up GraphQL Scalars with types and config from graphql-scalars with ability to opt-out
  • Automatically extracts object type mapper interfaces and types (marked with Mapper suffix) from accompanying .mappers.ts files in each module. For example, if the schema file is /path/to/schema.graphql, the mapper file is /path/to/schema.mappers.ts.

Getting Started

Setup

Files

# src/schema/base/schema.graphql
type Query

# src/schema/user/schema.graphql
extend type Query {
  user(id: ID!): User
}

type User {
  id: ID!
  fullName: String!
}

type Address {
  id: ID!
  address: String!
}
// src/schema/user/schema.mappers.ts

// Exporting the following Mapper interfaces and types is the equivalent of this codegen config:
// ```yml
// mappers:
//   Address: './user/schema.mappers#AddressMapper'
//   User: './user/schema.mappers#UserMapper'
// ```

export { Address as AddressMapper } from 'address-package';

export interface UserMapper {
  id: string;
  firstName: string;
  lastName: string;
}

Codegen Config

// codegen.ts
import type { CodegenConfig } from '@graphql-codegen/cli';
import { defineConfig } from '@eddeee888/gcg-typescript-resolver-files';

const config: CodegenConfig = {
  schema: '**/schema.graphql',
  generates: {
    'src/schema': defineConfig(),
  },
};

export default config;

OR

# codegen.yml
schema: '**/*.graphql'
generates:
  src/schema:
    preset: '@eddeee888/gcg-typescript-resolver-files'
    watchPattern: '**/*.mappers.ts'

Result

Running codegen will generate the following files:

  • src/schema/user/resolvers/Query/user.ts
  • src/schema/user/resolvers/User.ts
  • src/schema/user/resolvers/Address.ts
  • src/schema/resolvers.generated.ts
  • src/schema/typeDefs.generated.ts
  • src/schema/types.generated.ts

Config Options

mode

merged or modules (Default: modules)

How files are collocated. modules detects containing dir of a schema file as "modules", then split resolvers into those modules. merged treats baseOutputDir as the one and only module and generates resolvers.

resolverTypesPath

string (Default: ./types.generated.ts)

Relative path to type file generated by typescript-resolvers plugin.

resolverRelativeTargetDir

string (Default: resolvers)

Relative path to target dir. For config.mode=merged, files will be generated into <baseOutputDir>/<resolverRelativeTargetDir>. For config.mode=modules, files will be generated into <baseOutputDir>/**/<moduleName>/<resolverRelativeTargetDir>.

resolverMainFileMode

merged or modules (Default: merged)

How to generate file/s that put resolvers map together:

  • merged: one file
  • modules: one file per module

resolverMainFile

string (Default: resolvers.generated.ts)

File that puts all generated resolvers together. Relative from baseOutputDir.

resolverGeneration

disabled or recommended or all (Default: recommended)

Decides which resolvers to generate:

  • disabled: generates no resolvers. Use this if you want to use your own structures. Note: if custom scalars are detected and used, resolver main files are still generated.
  • recommended: generates the minimal amount of resolvers. Use this if you want a managed experience.
    • no union/interface resolvers are generated because we rely on certain settings in typescript-resolvers that make these not required.
  • all: generates all resolvers. Use this if you want all resolvers to be generated and use the ones you need.

typeDefsFileMode

merged or mergedWhitelisted or modules (Default: merged)

How to generate typeDefs file/s:

  • merged: one file
  • mergedWhitelisted: one file but only contains whitelisted modules
  • modules: one file per module

If config.mode=merged, this config is always merged

typeDefsFilePath

string or false (Default: ./typeDefs.generated.ts)

Where to generate typeDefs files. If value is false or empty string, the file/s are not generated.

If typeDefsFileMode=merged or typeDefsFileMode=mergedWhitelisted, this path is relative from baseOutputDir.

If typeDefsFileMode=modules, this path is relative from each module directory.

add

Record<string, (@graphql-codegen/add).AddPluginConfig> (Default: undefined) (EXPERIMENTAL)

Allows using add plugin on a given file.

Note: Currently only supports resolverTypesPath file i.e. types.generated.ts

Example:

// codegen.ts
{
  generates: {
    'src/schema': defineConfig({
      add: {
        './types.generated.ts': { content: '/* eslint-disable */' },
      },
    })
  }
}

whitelistedModules

Array<string> (Only works with config.mode=modules)

Whitelists modules to generate files and entries in main file. By default all modules are whitelisted. Useful for gradual migrations.

blacklistedModules

Array<string> (Only works with config.mode=modules)

Blacklists modules to avoid generate files and entries in main file. Useful for gradual migrations.

externalResolvers

Record<string, string>

Map of relative or absolute path (prefixed with ~) to external or existing resolvers.

Examples:

  • DateTime: ~graphql-scalars#DateTimeResolver
  • Query.me: '~@org/meResolver#default as meResolver'
  • User: 'otherResolvers#User as UserResolver'.

typesPluginsConfig

(@graphql-codegen/typescript).TypeScriptPluginConfig & (@graphql-codegen/typescript-resolvers).TypeScriptResolversPluginConfig

Takes typescript config and typescript-resolvers config to override the defaults.

Experimental options:

  • namingConvention

mappersFileExtension

string (Default: .mappers.ts)

The files with this extension provides mappers interfaces and types for the schema files in the same module.

mappersSuffix

string (Default: Mapper)

Exported interfaces and types with this suffix from mappersFile in each module are put into the mappers object of @graphql-codegen/typescript-resolvers.

scalarsModule

string or false (Default: graphql-scalars)

Where Scalar implementation and codegen types come from. Use false to implement your own Scalars.

If using an module that is not graphql-scalars, the module must export resolver implementation and codegen type the same way graphql-scalars does e.g.

{
  resolvers: {
    DateTime: DateTimeResolver,
  },
  DateTimeResolver: {
    // ... resolver implementation
    extensions: {
      codegenScalarType: 'Date | string',
    },
  }
}

scalarsOverrides

Record<string, { resolver?: string; type?: string | { input: string; output: string } }> (Default: {})

Overrides scalars' resolver implementation, type or both.

Example:

// codegen.ts
{
  generates: {
    'src/schema': defineConfig({
      scalarsOverrides: {
        DateTime: {
          resolver: './localDateTimeResolver#Resolver',
        }
        Currency: {
          type: 'unknown'
        },
        BigInt: {
          resolver: '@other/scalars#BigIntResolver',
          type: {
            input: 'bigint',
            output: 'number | string'
          }
        }
      }
    })
  }
}

tsConfigFilePath

string (Default: ./tsconfig.json)

Project's TypeScript config, relative from project root. This helps type analysis such as resolving custom module paths.

fixObjectTypeResolvers

smart or disabled (Default: smart) (Experimental)

Statically compares object type's mapper types' field against schema types' fields, creating resolvers if required

emitLegacyCommonJSImports

bool (Default: true)

Determines whether imports emitted should use CommonJS syntax or ESM syntax (with .js file endings)

Config Examples

1. Custom Config

Custom preset config can be set using the presetConfig option:

# codegen.yml
schema: '**/*.graphql'
generates:
  src/schema:
    preset: '@eddeee888/gcg-typescript-resolver-files'
    presetConfig:
      mode: 'modules'
      resolverTypesPath: './types.gen.ts'
      typeDefsFilePath: false
      typesPluginsConfig: # Pass config you'd normally use for `typescript` and `typescript-resolvers` here
        nonOptionalTypename: false
        federation: true

2. Using TypeScript Config File

If you use codegen.ts, you can use the exported defineConfig function to get better TypeScript support:

import type { CodegenConfig } from '@graphql-codegen/cli';
import { defineConfig } from '@eddeee888/gcg-typescript-resolver-files';

const config: CodegenConfig = {
  schema: '**/schema.graphql',
  generates: {
    'src/schema': defineConfig({
      mode: 'modules',
      resolverTypesPath: './types.gen.ts',
      typeDefsFilePath: false,
      typesPluginsConfig: {
        // Pass config you'd normally use for `typescript` and `typescript-resolvers` here
        nonOptionalTypename: false,
        federation: true,
      },
    }),
  },
};
export default config;

Package Sidebar

Install

npm i @eddeee888/gcg-typescript-resolver-files

Weekly Downloads

5,705

Version

0.7.5

License

MIT

Unpacked Size

203 kB

Total Files

146

Last publish

Collaborators

  • eddeee888