From 2ed21a471f8de58ecafebf4bf64b3c32cee24d2f Mon Sep 17 00:00:00 2001 From: Charly POLY <1252066+charlypoly@users.noreply.github.com> Date: Wed, 31 Aug 2022 16:33:33 +0200 Subject: [PATCH] GraphQL Code Generator v3: `@graphql-codegen/cli` changes (#8301) Co-authored-by: github-actions[bot] --- .../@graphql-codegen_cli-8301-dependencies.md | 7 + .changeset/fast-pears-wonder.md | 7 + packages/graphql-codegen-cli/package.json | 1 + packages/graphql-codegen-cli/src/codegen.ts | 34 +- packages/graphql-codegen-cli/src/config.ts | 12 +- packages/graphql-codegen-cli/src/index.ts | 1 + packages/graphql-codegen-cli/src/presets.ts | 14 +- .../graphql-modules/tests/integration.spec.ts | 2 +- packages/utils/plugins-helpers/src/index.ts | 1 + packages/utils/plugins-helpers/src/types.ts | 14 +- .../advanced/generated-files-colocation.mdx | 66 +-- .../pages/docs/advanced/how-does-it-work.mdx | 22 +- website/src/pages/docs/advanced/profiler.mdx | 2 +- .../docs/config-reference/codegen-config.mdx | 69 ++- .../docs/config-reference/config-field.mdx | 66 +-- .../docs/config-reference/documents-field.mdx | 224 ++++++--- .../docs/config-reference/lifecycle-hooks.mdx | 54 ++- .../src/pages/docs/config-reference/meta.json | 2 +- .../config-reference/naming-convention.mdx | 103 +++-- .../docs/config-reference/require-field.mdx | 51 ++- .../docs/config-reference/schema-field.mdx | 425 +++++++++++++----- .../getting-started/development-workflow.mdx | 50 ++- .../getting-started/esm-typescript-usage.mdx | 27 +- .../docs/integrations/apollo-local-state.mdx | 11 +- .../pages/docs/integrations/federation.mdx | 22 +- .../src/pages/docs/integrations/prettier.mdx | 80 +++- 26 files changed, 948 insertions(+), 419 deletions(-) create mode 100644 .changeset/@graphql-codegen_cli-8301-dependencies.md create mode 100644 .changeset/fast-pears-wonder.md diff --git a/.changeset/@graphql-codegen_cli-8301-dependencies.md b/.changeset/@graphql-codegen_cli-8301-dependencies.md new file mode 100644 index 00000000000..18a756ea0ac --- /dev/null +++ b/.changeset/@graphql-codegen_cli-8301-dependencies.md @@ -0,0 +1,7 @@ +--- +"@graphql-codegen/cli": patch +--- + +dependencies updates: + +- Added dependency [`cosmiconfig-typescript-loader@^4.0.0` ↗︎](https://www.npmjs.com/package/cosmiconfig-typescript-loader/v/null) (to `dependencies`) diff --git a/.changeset/fast-pears-wonder.md b/.changeset/fast-pears-wonder.md new file mode 100644 index 00000000000..a414dc4cc7c --- /dev/null +++ b/.changeset/fast-pears-wonder.md @@ -0,0 +1,7 @@ +--- +'@graphql-codegen/cli': minor +'@graphql-cli/codegen': minor +'@graphql-codegen/plugin-helpers': minor +--- + +Introduces support for TypeScript config file and a new preset lifecycle (required for `client-preset`) diff --git a/packages/graphql-codegen-cli/package.json b/packages/graphql-codegen-cli/package.json index 2327b0b6ab2..502f1a3dc6d 100644 --- a/packages/graphql-codegen-cli/package.json +++ b/packages/graphql-codegen-cli/package.json @@ -57,6 +57,7 @@ "chalk": "^4.1.0", "chokidar": "^3.5.2", "cosmiconfig": "^7.0.0", + "cosmiconfig-typescript-loader": "^4.0.0", "debounce": "^1.2.0", "detect-indent": "^6.0.0", "graphql-config": "^4.3.5", diff --git a/packages/graphql-codegen-cli/src/codegen.ts b/packages/graphql-codegen-cli/src/codegen.ts index f04deb01c0c..2a6fd003a52 100644 --- a/packages/graphql-codegen-cli/src/codegen.ts +++ b/packages/graphql-codegen-cli/src/codegen.ts @@ -202,21 +202,29 @@ export async function executeCodegen(input: CodegenContext | Types.Config): Prom const outputConfig = generates[filename]; const hasPreset = !!outputConfig.preset; - const title = hasPreset - ? `Generate to ${filename} (using EXPERIMENTAL preset "${outputConfig.preset}")` - : `Generate ${filename}`; + const title = `Generate to ${filename}`; return { title, - task: (_, subTask) => { + task: async (_, subTask) => { let outputSchemaAst: GraphQLSchema; let outputSchema: DocumentNode; const outputFileTemplateConfig = outputConfig.config || {}; let outputDocuments: Types.DocumentFile[] = []; const outputSpecificSchemas = normalizeInstanceOrArray(outputConfig.schema); - const outputSpecificDocuments = normalizeInstanceOrArray( - outputConfig.documents - ); + let outputSpecificDocuments = normalizeInstanceOrArray(outputConfig.documents); + + const preset: Types.OutputPreset | null = hasPreset + ? typeof outputConfig.preset === 'string' + ? await getPresetByName(outputConfig.preset, makeDefaultLoader(context.cwd)) + : outputConfig.preset + : null; + + if (preset) { + if (preset.prepareDocuments) { + outputSpecificDocuments = await preset.prepareDocuments(filename, outputSpecificDocuments); + } + } return subTask.newListr( [ @@ -296,13 +304,9 @@ export async function executeCodegen(input: CodegenContext | Types.Config): Prom normalizedPluginsArray.map(plugin => getPluginByName(Object.keys(plugin)[0], pluginLoader)) ); - const preset: Types.OutputPreset = hasPreset - ? typeof outputConfig.preset === 'string' - ? await getPresetByName(outputConfig.preset, makeDefaultLoader(context.cwd)) - : outputConfig.preset - : null; - - const pluginMap: { [name: string]: CodegenPlugin } = Object.fromEntries( + const pluginMap: { + [name: string]: CodegenPlugin; + } = Object.fromEntries( pluginPackages.map((pkg, i) => { const plugin = normalizedPluginsArray[i]; const name = Object.keys(plugin)[0]; @@ -318,7 +322,7 @@ export async function executeCodegen(input: CodegenContext | Types.Config): Prom emitLegacyCommonJSImports: shouldEmitLegacyCommonJSImports(config, filename), }; - const outputs: Types.GenerateOptions[] = hasPreset + const outputs: Types.GenerateOptions[] = preset ? await context.profiler.run( async () => preset.buildGeneratesSection({ diff --git a/packages/graphql-codegen-cli/src/config.ts b/packages/graphql-codegen-cli/src/config.ts index 2f04dd184db..a3d796331f4 100644 --- a/packages/graphql-codegen-cli/src/config.ts +++ b/packages/graphql-codegen-cli/src/config.ts @@ -1,4 +1,5 @@ import { cosmiconfig, defaultLoaders } from 'cosmiconfig'; +import { TypeScriptLoader } from 'cosmiconfig-typescript-loader'; import { resolve } from 'path'; import { DetailedError, @@ -21,6 +22,8 @@ import { createHash } from 'crypto'; const { lstat } = promises; +export type CodegenConfig = Types.Config; + export type YamlCliFlags = { config: string; watch: boolean | string | string[]; @@ -38,7 +41,7 @@ export type YamlCliFlags = { }; export function generateSearchPlaces(moduleName: string) { - const extensions = ['json', 'yaml', 'yml', 'js', 'config.js']; + const extensions = ['json', 'yaml', 'yml', 'js', 'ts', 'config.js']; // gives codegen.json... const regular = extensions.map(ext => `${moduleName}.${ext}`); // gives .codegenrc.json... but no .codegenrc.config.js @@ -47,7 +50,7 @@ export function generateSearchPlaces(moduleName: string) { return [...regular.concat(dot), 'package.json']; } -function customLoader(ext: 'json' | 'yaml' | 'js') { +function customLoader(ext: 'json' | 'yaml' | 'js' | 'ts') { function loader(filepath: string, content: string) { if (typeof process !== 'undefined' && 'env' in process) { content = env(content); @@ -70,6 +73,10 @@ function customLoader(ext: 'json' | 'yaml' | 'js') { if (ext === 'js') { return defaultLoaders['.js'](filepath, content); } + + if (ext === 'ts') { + return TypeScriptLoader()(filepath, content); + } } return loader; @@ -124,6 +131,7 @@ export async function loadCodegenConfig({ '.yaml': customLoader('yaml'), '.yml': customLoader('yaml'), '.js': customLoader('js'), + '.ts': customLoader('ts'), noExt: customLoader('yaml'), ...customLoaders, }, diff --git a/packages/graphql-codegen-cli/src/index.ts b/packages/graphql-codegen-cli/src/index.ts index fc27d8fffe2..06620346688 100644 --- a/packages/graphql-codegen-cli/src/index.ts +++ b/packages/graphql-codegen-cli/src/index.ts @@ -5,3 +5,4 @@ export * from './init/index.js'; export * from './utils/cli-error.js'; export * from './cli.js'; export * from './graphql-config.js'; +export { CodegenConfig } from './config.js'; diff --git a/packages/graphql-codegen-cli/src/presets.ts b/packages/graphql-codegen-cli/src/presets.ts index 5d3bd6faabd..b98404587b6 100644 --- a/packages/graphql-codegen-cli/src/presets.ts +++ b/packages/graphql-codegen-cli/src/presets.ts @@ -1,4 +1,4 @@ -import { DetailedError, Types } from '@graphql-codegen/plugin-helpers'; +import { Types } from '@graphql-codegen/plugin-helpers'; import { resolve } from 'path'; export async function getPresetByName( @@ -31,9 +31,9 @@ export async function getPresetByName( /** ESM Error code */ err.code !== 'ERR_MODULE_NOT_FOUND' ) { - throw new DetailedError( - `Unable to load preset matching ${name}`, - ` + throw new Error( + `Unable to load preset matching ${name} + Unable to load preset matching '${name}'. Reason: ${err.message} @@ -51,9 +51,9 @@ export async function getPresetByName( ) .join(''); - throw new DetailedError( - `Unable to find preset matching ${name}`, - ` + throw new Error( + `Unable to find preset matching ${name} + Unable to find preset matching '${name}' Install one of the following packages: diff --git a/packages/presets/graphql-modules/tests/integration.spec.ts b/packages/presets/graphql-modules/tests/integration.spec.ts index fe18693471d..f93b14ce905 100644 --- a/packages/presets/graphql-modules/tests/integration.spec.ts +++ b/packages/presets/graphql-modules/tests/integration.spec.ts @@ -11,7 +11,7 @@ const options = { './tests/test-files/modules': { schema: './tests/test-files/modules/*/types/*.graphql', plugins: ['typescript', 'typescript-resolvers'], - preset: 'graphql-modules', + preset: 'graphql-modules' as const, presetConfig: { baseTypesPath: 'global-types.ts', filename: 'module-types.ts', diff --git a/packages/utils/plugins-helpers/src/index.ts b/packages/utils/plugins-helpers/src/index.ts index addaa812e32..633d90d7dba 100644 --- a/packages/utils/plugins-helpers/src/index.ts +++ b/packages/utils/plugins-helpers/src/index.ts @@ -7,3 +7,4 @@ export * from './errors.js'; export * from './getCachedDocumentNodeFromSchema.js'; export * from './oldVisit.js'; export * from './profiler.js'; +export { Types } from './types.js'; diff --git a/packages/utils/plugins-helpers/src/types.ts b/packages/utils/plugins-helpers/src/types.ts index 99f018a6bc4..84612110405 100644 --- a/packages/utils/plugins-helpers/src/types.ts +++ b/packages/utils/plugins-helpers/src/types.ts @@ -218,6 +218,14 @@ export namespace Types { export type NamedPreset = string; export type OutputConfig = NamedPlugin | ConfiguredPlugin; + export type PresetNamesBase = + | 'client' + | 'near-operation-file' + | 'gql-tag-operations' + | 'graphql-modules' + | 'import-types-preset'; + export type PresetNames = `${PresetNamesBase}-preset` | PresetNamesBase; + /** * @additionalProperties false */ @@ -242,7 +250,7 @@ export namespace Types { * * List of available presets: https://graphql-code-generator.com/docs/presets/presets-index */ - preset?: string | OutputPreset; + preset?: PresetNames | OutputPreset; /** * @description If your setup uses Preset to have a more dynamic setup and output, set the configuration object of your preset here. * @@ -330,6 +338,10 @@ export namespace Types { export type OutputPreset = { buildGeneratesSection: (options: PresetFnArgs) => Promisable; + prepareDocuments?: ( + outputFilePath: string, + outputSpecificDocuments: Types.OperationDocument[] + ) => Promisable; }; /* Require Extensions */ diff --git a/website/src/pages/docs/advanced/generated-files-colocation.mdx b/website/src/pages/docs/advanced/generated-files-colocation.mdx index e054b124492..da5d306521c 100644 --- a/website/src/pages/docs/advanced/generated-files-colocation.mdx +++ b/website/src/pages/docs/advanced/generated-files-colocation.mdx @@ -13,19 +13,21 @@ For similar results on a back-end project, please refer to [`@graphql-codegen/gr Most GraphQL Code Generator configuration examples (in guides or plugins documentation) generate types in a single common file, as follows: -```yaml -# Configuration for a React URQL setup - -schema: http://my-graphql-api.com/graphql -documents: './src/**/*.tsx' -generates: - graphql/generated.ts: - plugins: - - typescript - - typescript-operations - - typescript-urql - config: - withHooks: true +```ts +import { CodegenConfig } from '@graphql-codegen/cli'; + +// Configuration for a React URQL setup +const config: CodegenConfig = { + schema: 'http://my-graphql-api.com/graphql', + documents: './src/**/*.tsx', + generates: { + 'graphql/generated.ts': { + plugins: ['typescript', 'typescript-operations', 'typescript-urql'], + config: { withHooks: true }, + }, + }, +}; +export default config; ``` All code is generated in one single `graphql/generated.ts` file. @@ -51,29 +53,29 @@ Just a few configuration steps are required to get this structure of colocated g ### Configure the preset -To use this preset, you need to add 2 outputs to your `codegen.yml` file: +To use this preset, you need to add 2 outputs to your `codegen.ts` file: - The first is the base types, generated by `typescript` plugin. - The second is the one in charge of generating types per operation. -```yaml -schema: http://my-graphql-api.com/graphql -# we are looking for operations in .tsx files, -# but not the generated ones. -documents: 'src/**/!(*.generated).{ts,tsx}' -generates: - src/types.ts: - - typescript - src/: - preset: near-operation-file - presetConfig: - extension: .generated.tsx - baseTypesPath: types.ts - plugins: - - typescript-operations - - typescript-urql - config: - withHooks: true + +```ts filename="codegen.ts" +import { CodegenConfig } from '@graphql-codegen/cli'; + +const config: CodegenConfig = { + schema: 'http://my-graphql-api.com/graphql', + documents: 'src/**/!(*.generated).{ts,tsx}', + generates: { + 'src/types.ts': ['typescript'], + 'src/': { + preset: 'near-operation-file', + presetConfig: { extension: '.generated.tsx', baseTypesPath: 'types.ts' }, + plugins: ['typescript-operations', 'typescript-urql'], + config: { withHooks: true }, + }, + }, +}; +export default config; ``` diff --git a/website/src/pages/docs/advanced/how-does-it-work.mdx b/website/src/pages/docs/advanced/how-does-it-work.mdx index c13d763cd63..54bee75d23f 100644 --- a/website/src/pages/docs/advanced/how-does-it-work.mdx +++ b/website/src/pages/docs/advanced/how-does-it-work.mdx @@ -78,16 +78,18 @@ fragment UserFields on User { } ``` -And with the following `codegen.yml` configuration file: - -```yaml filename="codegen.yml" -schema: http://localhost:3333 -generates: - types-and-hooks.tsx: - plugins: - - typescript - - typescript-operations - - typescript-react-query +And with the following `codegen.ts` configuration file: + +```ts filename="codegen.ts" +import { CodegenConfig } from '@graphql-codegen/cli'; + +const config: CodegenConfig = { + schema: 'http://localhost:3333', + generates: { + 'types-and-hooks.tsx': { plugins: ['typescript', 'typescript-operations', 'typescript-react-query'] }, + }, +}; +export default config; ``` `@graphql-codegen/typescript` plugin can generate the following TypeScript typings and React hooks files based on defined operations: diff --git a/website/src/pages/docs/advanced/profiler.mdx b/website/src/pages/docs/advanced/profiler.mdx index 3cba4154d70..6f4e7ac9c07 100644 --- a/website/src/pages/docs/advanced/profiler.mdx +++ b/website/src/pages/docs/advanced/profiler.mdx @@ -5,7 +5,7 @@ import { PackageCmd } from '@theguild/components' GraphQL Code Generator CLI provides a flag that enables the profiler mode, as follows: GraphQL Code Generator operates as usual (generating your files) but also generates a `codegen-[timestamp].json` profile file. diff --git a/website/src/pages/docs/config-reference/codegen-config.mdx b/website/src/pages/docs/config-reference/codegen-config.mdx index 9625dd38d31..2071dec7eb6 100644 --- a/website/src/pages/docs/config-reference/codegen-config.mdx +++ b/website/src/pages/docs/config-reference/codegen-config.mdx @@ -1,40 +1,38 @@ import { PackageCmd, Callout } from '@theguild/components' -# `codegen.yml` file +# `codegen.ts` file [The plugins' page](/plugins) lists dozens of plugins with their set of options and specific outputs. -GraphQL Code Generator relies on a configuration file named `codegen.yml` or `codegen.json` to manage all possible options, input, and output document types. +GraphQL Code Generator relies on a configuration file named `codegen.ts` to manage all possible options, input, and output document types. The CLI automatically detects the defined config file and generates code accordingly. In addition, you can also define a path to your config file with the `--config` options, like so: - + ## Configuration file format Here's an example for a possible config file: -```yaml -schema: http://localhost:3000/graphql -documents: ./src/**/*.graphql -generates: - ./src/types.ts: - plugins: - - typescript - - typescript-operations +```ts +import { CodegenConfig } from '@graphql-codegen/cli' + +const config: CodegenConfig = { + schema: 'http://localhost:4000/graphql', + documents: ['src/**/*.tsx'], + generates: { + './src/gql/': { + preset: 'client', + plugins: [] + } + } +} + +export default config ``` -If you are looking for a reference file, an example for a [large configuration file can be seen here](https://github.com/dotansimha/graphql-code-generator/blob/master/dev-test/codegen.yml). - - -**For VSCode users** - -Ensure to [install the YAML plugin](https://marketplace.visualstudio.com/items?itemName=redhat.vscode-yaml) to add validation auto-complete capabilities for available plugins configuration files and `codegen.yml` file. - - - ## Configuration options Here are the supported options that you can define in the config file (see [source code](https://github.com/dotansimha/graphql-code-generator/blob/master/packages/utils/plugins-helpers/src/types.ts#L92)): @@ -99,24 +97,23 @@ Here are the supported options that you can define in the config file (see [sour ## Environment Variables -You can use environment variables in your `codegen.yml` file: - -```yaml /${SCHEMA_PATH}/ -schema: ${SCHEMA_PATH} -documents: ./src/**/*.graphql -generates: - ./src/types.ts: - plugins: - - typescript - - typescript-operations -``` +You can use environment variables in your `codegen.ts` file: -You can load a `.env` file by adding the `-r dotenv/config` option to your CLI command and adding `dotenv` as a dependency on your project. +```ts /process.env.SCHEMA_PATH/ +import { CodegenConfig } from '@graphql-codegen/cli' -You can specify a default value in case an environment variable is missing: +const config: CodegenConfig = { + schema: process.env.SCHEMA_PATH, + documents: ['src/**/*.tsx'], + generates: { + './src/gql/': { + preset: 'client', + plugins: [] + } + } +} -```yaml -schema: ${SCHEMA_PATH:schema.graphql} +export default config ``` ## CLI Flags @@ -180,7 +177,7 @@ For more detailed output, you can also enable the `verbose: true` or `--verbose` GraphQL-Codegen is uses [`cosmiconfig`](https://github.com/davidtheclark/cosmiconfig) library to manage configuration loading. -That means you can use `codegen.yml`, `codegen.json`, or `codegen.js` as configuration files. You can also specify the entire configuration under a key called `"codegen"` in your `package.json`. +That means you can use `codegen.yml`, `codegen.json`, `codegen.js`, or `codegen.ts` as configuration files. You can also specify the entire configuration under a key called `"codegen"` in your `package.json`. For more information, [please refer to `cosmiconfig` documentation](https://github.com/davidtheclark/cosmiconfig#cosmiconfig). diff --git a/website/src/pages/docs/config-reference/config-field.mdx b/website/src/pages/docs/config-reference/config-field.mdx index 6a8d5e6cabf..99b8557afe6 100644 --- a/website/src/pages/docs/config-reference/config-field.mdx +++ b/website/src/pages/docs/config-reference/config-field.mdx @@ -10,29 +10,36 @@ The `config` field is used to pass configuration to Plugins. If you specify it in your root level, the options will be passed to every plugin for each output file: -```yaml {2-3} -schema: schema.graphql -config: - configKey: configValue -generates: - output.ts: - - plugin1 - - plugin2 +```ts {5} +import { CodegenConfig } from '@graphql-codegen/cli' + +const config: CodegenConfig = { + schema: 'schema.graphql', + config: { configKey: 'configValue' }, + generates: { 'output.ts': ['plugin1', 'plugin2'] } +} +export default config ``` ### Output Level If you specify it at the output file level, every plugin for specific output will get the config value: -```yaml {4-5} -schema: schema.graphql -generates: - output.ts: - config: - configKey: configValue - plugins: - - plugin1 - - plugin2 +```ts {7-9} +import { CodegenConfig } from '@graphql-codegen/cli' + +const config: CodegenConfig = { + schema: 'schema.graphql', + generates: { + 'output.ts': { + config: { + configKey: 'configValue' + }, + plugins: ['plugin1', 'plugin2'] + } + } +} +export default config ``` Output level configuration overrides root-level configuration. @@ -41,14 +48,23 @@ generates: If you specify it at the plugin level, only that plugin will get the config value: -```yaml {5,7} -schema: schema.graphql -generates: - output.ts: - - plugin1: - configKey: configValue - - plugin2: - configKey: otherValue +```ts {8,11} +import { CodegenConfig } from '@graphql-codegen/cli' + +const config: CodegenConfig = { + schema: 'schema.graphql', + generates: { + 'output.ts': [ + { + plugin1: { configKey: 'configValue' } + }, + { + plugin2: { configKey: 'otherValue' } + } + ] + } +} +export default config ``` Plugin level configuration overrides output-level and root-level configuration. diff --git a/website/src/pages/docs/config-reference/documents-field.mdx b/website/src/pages/docs/config-reference/documents-field.mdx index 8494364b325..1f1ae564735 100644 --- a/website/src/pages/docs/config-reference/documents-field.mdx +++ b/website/src/pages/docs/config-reference/documents-field.mdx @@ -14,28 +14,34 @@ You can specify either a `string` pointing to your documents or `string[]` point You can specify the `documents` field in your root level config: -```yaml {2} -schema: http://localhost:3000/graphql -documents: 'src/**/*.graphql' -generates: - ./src/types.ts: - plugins: - - typescript - - typescript-operations +```ts {5} +import { CodegenConfig } from '@graphql-codegen/cli' + +const config: CodegenConfig = { + schema: 'http://localhost:3000/graphql', + documents: 'src/**/*.graphql', + generates: { './src/types.ts': { plugins: ['typescript', 'typescript-operations'] } } +} +export default config ``` ### Output-file level You can also specify the `documents` field in your generated file level config: -```yaml {4} -schema: http://server1.com/graphql -generates: - ./src/types1.ts: - documents: 'src/**/*.graphql' - plugins: - - typescript - - typescript-operations +```ts {7} +import { CodegenConfig } from '@graphql-codegen/cli' + +const config: CodegenConfig = { + schema: 'http://server1.com/graphql', + generates: { + './src/types1.ts': { + documents: 'src/**/*.graphql', + plugins: ['typescript', 'typescript-operations'] + } + } +} +export default config ``` ### Document Scanner @@ -44,9 +50,14 @@ GraphQL Code Generator has a built-in document scanner, which means you can spec You can tell it to find documents in TypeScript files: -```yaml /!(*.d).{ts,tsx}/ -schema: http://server1.com/graphql -documents: 'src/**/!(*.d).{ts,tsx}' +```ts /!(*.d).{ts,tsx}/ +import { CodegenConfig } from '@graphql-codegen/cli' + +const config: CodegenConfig = { + schema: 'http://server1.com/graphql', + documents: 'src/**/!(*.d).{ts,tsx}' +} +export default config ``` ## Available Formats @@ -57,59 +68,103 @@ The following can be specified as a single value or as an array with mixed value You can specify a `string` to point to a single file: -```yaml -documents: my-query.graphql +```ts {5} +import { CodegenConfig } from '@graphql-codegen/cli' + +const config: CodegenConfig = { + // ... + documents: 'my-query.graphql' + // ... +} +export default config ``` Or `string[]` to point to multiple files: -```yaml -documents: - - my-query.graphql - - my-other-query.graphql +```ts {5} +import { CodegenConfig } from '@graphql-codegen/cli' + +const config: CodegenConfig = { + // ... + documents: ['my-query.graphql', 'my-other-query.graphql'] + // ... +} +export default config ``` - ### Glob Expression You can specify a Glob expression in order to load multiple files: -```yaml -documents: './src/**/*.graphql' +```ts {5} +import { CodegenConfig } from '@graphql-codegen/cli' + +const config: CodegenConfig = { + // ... + documents: './src/**/*.graphql' + // ... +} +export default config ``` You can also specify multiple Glob expressions as an array: -```yaml -documents: - - './src/dir1/*.graphql' - - './src/dir2/*.graphql' +```ts {5} +import { CodegenConfig } from '@graphql-codegen/cli' + +const config: CodegenConfig = { + // ... + documents: ['./src/dir1/*.graphql', './src/dir2/*.graphql'] + // ... +} +export default config ``` You can specify files to exclude by prefixing the Glob expression with `!`: -```yaml {3} -documents: - - './src/**/*.graphql' - - '!*.generated.graphql' +```ts {5} +import { CodegenConfig } from '@graphql-codegen/cli' + +const config: CodegenConfig = { + // ... + documents: ['./src/**/*.graphql', '!*.generated.graphql'] + // ... +} +export default config ``` All provided glob expressions are evaluated together. The usage is similar to `.gitignore`. Additionally, you can use code files, and the codegen will try to extract the GraphQL documents from it: -```yaml -documents: - - './src/*.jsx' +```ts {5} +import { CodegenConfig } from '@graphql-codegen/cli' + +const config: CodegenConfig = { + // ... + documents: ['./src/*.jsx'] + // ... +} +export default config ``` The codegen will try to load the file as an AST and look for exact GraphQL operations strings. Still, if it can't find those, it will try to `require` the file and look for operations in the default export. You can disable the `require` if it causes errors for you (for example, because of different module system): -```yaml {3} -documents: - - './src/*.jsx': - noRequire: true +```ts {7} +import { CodegenConfig } from '@graphql-codegen/cli' + +const config: CodegenConfig = { + // ... + documents: { + './src/*.jsx': { + noRequire: true + } + } + // ... +} +export default config ``` @@ -120,10 +175,15 @@ Your operations should be declared as template strings with the `gql` tag or wit You can specify your GraphQL documents directly as an AST string in your config file. It's very useful for testing. -```yaml -documents: - - 'query { f1 }' - - 'query { f2 }' +```ts {5} +import { CodegenConfig } from '@graphql-codegen/cli' + +const config: CodegenConfig = { + // ... + documents: ['query { f1 }', 'query { f2 }'] + // ... +} +export default config ``` ## GraphQL Tag Pluck @@ -161,38 +221,74 @@ By default, it has a predefined list of popular `gql` tags to look for, in order You can add custom tags if you need by using `pluckConfig` on the root level on your config file: -```yaml -pluckConfig: - modules: - - name: my-custom-module - identifier: gql +```ts {6-13} +import { CodegenConfig } from '@graphql-codegen/cli' + +const config: CodegenConfig = { + // ... + documents: ['./src/*.jsx'], + pluckConfig: { + modules: [ + { + name: 'my-custom-module' + identifier: 'gql' + } + ] + } + // ... +} +export default config ``` You can also customize globally used identifiers, like that: -```yaml {2-5} -pluckConfig: - globalGqlIdentifierName: - - gql - - graphql - - myCustomGlobalGqlTag +```ts {7} +import { CodegenConfig } from '@graphql-codegen/cli' + +const config: CodegenConfig = { + // ... + documents: ['./src/*.jsx'], + pluckConfig: { + globalGqlIdentifierName: ['gql', 'graphql', 'myCustomGlobalGqlTag'] + } + // ... +} +export default config ``` And you can customize the magic GraphQL comment by doing: -```yaml {2} -pluckConfig: - gqlMagicComment: customcomment +```ts {7} +import { CodegenConfig } from '@graphql-codegen/cli' + +const config: CodegenConfig = { + // ... + documents: ['./src/*.jsx'], + pluckConfig: { + gqlMagicComment: 'customcomment' + } + // ... +} +export default config ``` ## Custom Document Loader Suppose your schema has a different or complicated way of loading. In that case, you can specify a custom loader with the `loader` field. -```yaml {3} -documents: - - '**/*.graphql': - loader: my-documents-loader.js +```ts {6-8} +import { CodegenConfig } from '@graphql-codegen/cli' + +const config: CodegenConfig = { + // ... + documents: { + './src/*.jsx': { + loader: 'my-documents-loader.js' + } + } + // ... +} +export default config ``` Your custom loader should export a default function that returns a `DocumentNode`. For example: diff --git a/website/src/pages/docs/config-reference/lifecycle-hooks.mdx b/website/src/pages/docs/config-reference/lifecycle-hooks.mdx index dbbd31bb3fe..ce0f8d3c87b 100644 --- a/website/src/pages/docs/config-reference/lifecycle-hooks.mdx +++ b/website/src/pages/docs/config-reference/lifecycle-hooks.mdx @@ -10,24 +10,48 @@ Each hook has its arguments, and it passes them to your scripts using `argv`. ## How to use? -Add your scripts to your `codegen.yml` file, and specify the scripts you wish to run, for example: - -```yaml -hooks: - afterOneFileWrite: - - prettier --write +Add your scripts to your `codegen.ts` file, and specify the scripts you wish to run, for example: + +```ts +import { CodegenConfig } from '@graphql-codegen/cli' + +const config: CodegenConfig = { + schema: 'http://localhost:4000/graphql', + documents: ['src/**/*.tsx'], + generates: { + './src/gql/': { + preset: 'client', + plugins: [] + } + }, + hooks: { + afterOneFileWrite: ['prettier --write'] + } +} + +export default config ``` Or, for specific output: -```yaml -generates: - ./src/types.ts: - hooks: - afterOneFileWrite: - - prettier --write - plugins: - - typescript +```ts +import { CodegenConfig } from '@graphql-codegen/cli' + +const config: CodegenConfig = { + schema: 'http://localhost:4000/graphql', + documents: ['src/**/*.tsx'], + generates: { + './src/gql/': { + preset: 'client', + plugins: [], + hooks: { + afterOneFileWrite: ['prettier --write'] + } + } + } +} + +export default config ``` ## Root Level @@ -36,7 +60,7 @@ The following lifecycle hooks are supported on the root level: ### `afterStart` -Triggered with no arguments when the codegen starts (after the `codegen.yml` has been parsed). +Triggered with no arguments when the codegen starts (after the `codegen.ts` has been loaded). ### `onWatchTriggered` diff --git a/website/src/pages/docs/config-reference/meta.json b/website/src/pages/docs/config-reference/meta.json index d289c2328d0..f1a5b824d8f 100644 --- a/website/src/pages/docs/config-reference/meta.json +++ b/website/src/pages/docs/config-reference/meta.json @@ -1,5 +1,5 @@ { - "codegen-config": "codegen.yml", + "codegen-config": "codegen.ts", "schema-field": "schema field", "documents-field": "documents field", "config-field": "plugin config", diff --git a/website/src/pages/docs/config-reference/naming-convention.mdx b/website/src/pages/docs/config-reference/naming-convention.mdx index 4ab2d75866d..fd277ae3767 100644 --- a/website/src/pages/docs/config-reference/naming-convention.mdx +++ b/website/src/pages/docs/config-reference/naming-convention.mdx @@ -20,34 +20,64 @@ Additionally, you can set `transformUnderscore` to `true` if you want to overrid ##### Override All Names -```yaml -config: - namingConvention: change-case-all#lowerCase +```ts {5} +import { CodegenConfig } from '@graphql-codegen/cli' + +const config: CodegenConfig = { + // ... + config: { namingConvention: 'change-case-all#lowerCase' } + // ... +} +export default config ``` ##### Upper-case enum values -```yaml -config: - namingConvention: - typeNames: change-case-all#pascalCase - enumValues: change-case-all#upperCase +```ts {6-9} +import { CodegenConfig } from '@graphql-codegen/cli' + +const config: CodegenConfig = { + // ... + config: { + namingConvention: { + typeNames: 'change-case-all#pascalCase', + enumValues: 'change-case-all#upperCase' + } + } + // ... +} +export default config ``` ##### Keep names as is -```yaml -config: - namingConvention: keep +```ts {5} +import { CodegenConfig } from '@graphql-codegen/cli' + +const config: CodegenConfig = { + // ... + config: { namingConvention: 'keep' } + // ... +} +export default config ``` ##### Remove Underscores -```yaml -config: - namingConvention: - typeNames: change-case-all#pascalCase - transformUnderscore: true +```ts {6-9} +import { CodegenConfig } from '@graphql-codegen/cli' + +const config: CodegenConfig = { + // ... + config: { + namingConvention: { + typeNames: 'change-case-all#pascalCase', + transformUnderscore: true + } + } + // ... +} +export default config ``` #### Using external modules @@ -65,9 +95,15 @@ package-name#export-you-want-to-use For example, if you want to use `camelCase` from lodash, given that you have it already installed, you will do it like this: -```yaml -config: - namingConvention: lodash#camelCase +```ts {5} +import { CodegenConfig } from '@graphql-codegen/cli' + +const config: CodegenConfig = { + // ... + config: { namingConvention: 'lodash#camelCase' } + // ... +} +export default config ``` #### Providing your own naming function @@ -101,16 +137,31 @@ module.exports = FixedConstantCase Then, just provide the path to your custom naming module in the configuration: -```yaml -config: - namingConvention: ./my-naming-fn +```ts {5} +import { CodegenConfig } from '@graphql-codegen/cli' + +const config: CodegenConfig = { + // ... + config: { namingConvention: './my-naming-fn' } + // ... +} +export default config ``` This also applies when you want a specific custom naming convention per output. Specify your custom naming function on the output or outputs you want to apply: -```yaml -config: - namingConvention: - typeNames: ./my-naming-fn +```ts {6-8} +import { CodegenConfig } from '@graphql-codegen/cli' + +const config: CodegenConfig = { + // ... + config: { + namingConvention: { + typeNames: './my-naming-fn' + } + } + // ... +} +export default config ``` diff --git a/website/src/pages/docs/config-reference/require-field.mdx b/website/src/pages/docs/config-reference/require-field.mdx index 2e92d05e6d8..dc3079b8cdb 100644 --- a/website/src/pages/docs/config-reference/require-field.mdx +++ b/website/src/pages/docs/config-reference/require-field.mdx @@ -8,10 +8,15 @@ The `require` field allows you to load any external files without the need to tr To use it, install the extensions you wish to use from npm and then specify a list of `require` extensions in your root config: -```yaml -require: - - extension1 - - extension2 +```ts {5} +import { CodegenConfig } from '@graphql-codegen/cli' + +const config: CodegenConfig = { + // ... + require: ['extension1', 'extension2'] + // ... +} +export default config ``` Adding `require` extension is useful if you are loading your `GraphQLSchema` or GraphQL documents from a [code file](./schema-field#javascript-export), if you wish to use [custom plugins](/docs/custom-codegen/write-your-plugin), or use a [custom schema loader](./schema-field#custom-schema-loader) or a [custom document loader](./documents-field#custom-document-loader). @@ -20,9 +25,15 @@ Adding `require` extension is useful if you are loading your `GraphQLSchema` or If you wish to use TypeScript, just add [`ts-node`](https://github.com/TypeStrong/ts-node) from npm and specify its register export in your config file: -```yaml -require: - - ts-node/register +```ts {5} +import { CodegenConfig } from '@graphql-codegen/cli' + +const config: CodegenConfig = { + // ... + require: ['ts-node/register'] + // ... +} +export default config ``` ## Specifying from the command line @@ -42,7 +53,7 @@ It will make sure to load your `.env` file before executing the codegen and load To get started with this integration, make sure you have `.env` file with variables, `dotenv` installed, and codegen is being executed like that: ```sh -graphql-codegen --require dotenv/config --config codegen.yml +graphql-codegen --require dotenv/config --config codegen.ts ``` #### Customize loaded env file @@ -54,7 +65,7 @@ It allows you to specify a custom file path using 2 methods. You can either set an environment variable called `DOTENV_CONFIG_PATH` with the path: ```sh -DOTENV_CONFIG_PATH="./my.env" graphql-codegen --require dotenv/config --config codegen.yml +DOTENV_CONFIG_PATH="./my.env" graphql-codegen --require dotenv/config --config codegen.ts ``` You can use `cross-env` library if you are using Windows. @@ -62,7 +73,7 @@ DOTENV_CONFIG_PATH="./my.env" graphql-codegen --require dotenv/config --config c Or, you can specify it using codegen CLI, like that: ```sh -graphql-codegen --require dotenv/config --config codegen.yml dotenv_config_path=my.env +graphql-codegen --require dotenv/config --config codegen.ts dotenv_config_path=my.env ``` #### `dotenv` Example @@ -72,11 +83,21 @@ SCHEMAURL=https://example.com/graphql APIKEY=ABC123 ``` -```yaml filename="codegen.yml" -schema: - - ${SCHEMAURL}: - headers: - apikey: ${APIKEY} +```ts +import { CodegenConfig } from '@graphql-codegen/cli' + +const config: CodegenConfig = { + schema: { + [process.env.SCHEMAURL]: { + headers: { + apikey: process.env.APIKEY + } + } + } + // ... +} + +export default config ``` diff --git a/website/src/pages/docs/config-reference/schema-field.mdx b/website/src/pages/docs/config-reference/schema-field.mdx index 910d1621f35..08d3cc377b9 100644 --- a/website/src/pages/docs/config-reference/schema-field.mdx +++ b/website/src/pages/docs/config-reference/schema-field.mdx @@ -12,42 +12,62 @@ The `schema` field should point to your `GraphQLSchema` - there are multiple way You can specify the `schema` field in your root level config, as follows: -```yaml {1} -schema: http://localhost:3000/graphql -generates: - ./src/types.ts: - plugins: - - typescript +```ts {4} +import { CodegenConfig } from '@graphql-codegen/cli'; + +const config: CodegenConfig = { + schema: 'http://localhost:3000/graphql', + generates: { + './src/types.ts': { + plugins: ['typescript'] + } + } +}; +export default config; + ``` ### Output-file level Or, you can specify it per-output file level. This way you can -```yaml {3,7} -generates: - ./src/types1.ts: - schema: http://server1.com/graphql - plugins: - - typescript - ./src/types2.ts: - schema: http://server2.com/graphql - plugins: - - typescript +```ts {6,10} +import { CodegenConfig } from '@graphql-codegen/cli'; + +const config: CodegenConfig = { + generates: { + './src/types1.ts': { + schema: 'http://server1.com/graphql', + plugins: ['typescript'] + }, + './src/types2.ts': { + schema: 'http://server2.com/graphql', + plugins: ['typescript'] + } + }, +}; +export default config; + ``` ### Multiple schemas and client-side schema You can also specify `schema` on both levels: root and output-file, and then GraphQL Code Generator will merge both schemas into one: -```yaml {1,4} -schema: http://localhost:3000/graphql -generates: - ./src/types.ts: - schema: ./schema.graphql - plugins: - - typescript - - typescript-operations +```ts {4,7} +import { CodegenConfig } from '@graphql-codegen/cli'; + +const config: CodegenConfig = { + schema: 'http://localhost:3000/graphql', + generates: { + './src/types.ts': { + schema: './schema.graphql', + plugins: ['typescript', 'typescript-operations'] + } + } +}; +export default config; + ``` @@ -62,8 +82,14 @@ The following can be specified as a single value or an array with mixed values. You can specify a URL to load your `GraphQLSchema` from: -```yaml -schema: http://localhost:3000/graphql +```ts {4} +import { CodegenConfig } from '@graphql-codegen/cli'; + +const config: CodegenConfig = { + schema: 'http://localhost:3000/graphql', + // ... +}; +export default config; ``` #### Supported Configuration @@ -72,11 +98,22 @@ schema: http://localhost:3000/graphql You can also specify custom HTTP headers to be sent with the request: -```yaml {3-4} -schema: - - http://localhost:3000/graphql: - headers: - Authorization: YOUR-TOKEN-HERE +```ts {7-9} +import { CodegenConfig } from '@graphql-codegen/cli'; + +const config: CodegenConfig = { + schema: [ + { + 'http://localhost:3000/graphql': { + headers: { + Authorization: 'YOUR-TOKEN-HERE', + }, + }, + }, + ], +}; +export default config; + ``` **Spacing and indentation are important in YAML**, make sure it matches the examples above. @@ -85,58 +122,112 @@ schema: You can specify a custom fetch function for the HTTP request, using the module name you wish to use: -```yaml {3} -schema: - - http://localhost:3000/graphql: - customFetch: 'my-custom-fetch' + + +```ts {7} +import { CodegenConfig } from '@graphql-codegen/cli'; + +const config: CodegenConfig = { + schema: [ + { + 'http://localhost:3000/graphql': { + customFetch: 'my-custom-fetch', + } + } + ] +}; +export default config; ``` + ##### `method` You can specify an HTTP method for the introspection query (the default value is `POST`). -```yaml {3} -schema: - - http://localhost:3000/graphql: - method: GET +```ts {7} +import { CodegenConfig } from '@graphql-codegen/cli'; + +const config: CodegenConfig = { + schema: [ + { + 'http://localhost:3000/graphql': { + method: 'GET', + } + } + ] +}; +export default config; + ``` ### JSON You can point to a local `.json` file that contains [GraphQL Introspection](https://graphql.org/learn/introspection) JSON. -```yaml -schema: schema.json + +```ts {4} +import { CodegenConfig } from '@graphql-codegen/cli'; + +const config: CodegenConfig = { + schema: 'schema.json', + // ... +}; +export default config; ``` + ### Local `.graphql` files You can point to a single `.graphql` file that contains the AST string of your schema: -```yaml -schema: schema.graphql +```ts {4} +import { CodegenConfig } from '@graphql-codegen/cli'; + +const config: CodegenConfig = { + schema: 'schema.graphql', + // ... +}; +export default config; ``` Or, you can point to multiple files using a glob expression (codegen will merge the schema files for you): -```yaml -schema: 'src/**/*.graphql' + + +```ts {4} +import { CodegenConfig } from '@graphql-codegen/cli'; + +const config: CodegenConfig = { + schema: 'src/**/*.graphql', + // ... +}; +export default config; ``` You can also specify multiple patterns: -```yaml -schema: - - 'src/dir1/**/*.graphql' - - 'src/dir2/**/*.graphql' + +```ts {4} +import { CodegenConfig } from '@graphql-codegen/cli'; + +const config: CodegenConfig = { + schema: ['src/dir1/**/*.graphql', 'src/dir2/**/*.graphql'], + // ... +}; +export default config; ``` + And, you can specify files to exclude/ignore, using the `!` sign: -```yaml {3} -schema: - - './src/**/*.graphql' - - '!*.generated.graphql' +```ts {4} +import { CodegenConfig } from '@graphql-codegen/cli'; + +const config: CodegenConfig = { + schema: ['src/**/*.graphql', '!*.generated.graphql'], + // ... +}; +export default config; ``` All provided glob expressions are evaluated together. The usage is similar to `.gitignore`. @@ -149,38 +240,76 @@ By default, codegen skips `graphql-import` to load all files using glob expressi If you are using `graphql-import` syntax in your schema definitions, you can tell codegen to use those import statements: -```yaml {3} -schema: - - 'src/dir1/**/*.graphql': - skipGraphQLImport: false + +```ts {7} +import { CodegenConfig } from '@graphql-codegen/cli'; + +const config: CodegenConfig = { + schema: [ + { + './src/**/*.ts': { + skipGraphQLImport: true + }, + }, + ], +}; +export default config; ``` + ##### `commentDescriptions` When enabled, converts all deprecated forms of GraphQL comments (marked with `#`) into a GraphQL description (marked with `"`) during the parsing phase. -```yaml {3} -schema: - - 'src/dir1/**/*.graphql': - commentDescriptions: true + +```ts {7} +import { CodegenConfig } from '@graphql-codegen/cli'; + +const config: CodegenConfig = { + schema: [ + { + './src/**/*.ts': { + commentDescriptions: true + }, + }, + ], +}; +export default config; ``` + + ##### `assumeValidSDL` Set to true to assume the SDL is valid, and skip any SDL syntax validations. -```yaml {3} -schema: - - 'src/dir1/**/*.graphql': - assumeValidSDL: true + +```ts {7} +import { CodegenConfig } from '@graphql-codegen/cli'; + +const config: CodegenConfig = { + schema: [ + { + './src/**/*.ts': { + assumeValidSDL: true + }, + }, + ], +}; +export default config; ``` ### Code Files You can use code files, and the codegen will try to extract the GraphQL schema from it, based on `gql` tag: -```yaml -schema: './src/**/*.ts' +```ts {4} +import { CodegenConfig } from '@graphql-codegen/cli'; + +const config: CodegenConfig = { + schema: './src/**/*.ts' +}; +export default config; ``` The codegen will try to load the file as an AST and look for exact GraphQL strings, but if it can't find those, it will try to `require` the file and looks for operations in the default export. @@ -191,40 +320,74 @@ The codegen will try to load the file as an AST and look for exact GraphQL strin You can disable the `require` if it causes errors for you (for example, because of a different module system or missing dependency): -```yaml {3} -schema: - - './src/**/*.ts': - noRequire: true +```ts {7} +import { CodegenConfig } from '@graphql-codegen/cli'; + +const config: CodegenConfig = { + schema: [ + { + './src/**/*.ts': { + noRequire: true, + }, + }, + ], +}; +export default config; ``` ##### `noPluck` You can disable the AST lookup phase and tell codegen to skip and directly try to `require` each file: -```yaml {3} -schema: - - './src/**/*.ts': - noPluck: true + +```ts {7} +import { CodegenConfig } from '@graphql-codegen/cli'; + +const config: CodegenConfig = { + schema: [ + { + './src/**/*.ts': { + noPluck: true, + }, + }, + ], +}; +export default config; ``` ##### `assumeValid` Set this to `true` to tell codegen to skip AST validation. -```yaml {3} -schema: - - './src/**/*.ts': - assumeValid: true +```ts {7} +import { CodegenConfig } from '@graphql-codegen/cli'; + +const config: CodegenConfig = { + schema: [ + { + './src/**/*.ts': { + assumeValid: true, + }, + }, + ], +}; +export default config; ``` ### JavaScript export You can also specify a code file that exports your `GraphQLSchema` object as export `schema` or as default export. -```yaml -schema: schema.js -``` + +```ts {4} +import { CodegenConfig } from '@graphql-codegen/cli'; + +const config: CodegenConfig = { + schema: 'schema.js' +}; +export default config; +``` ```js const { buildSchema } = require('graphql') @@ -247,26 +410,44 @@ module.exports = buildSchema(/* GraphQL */ ` You can specify your schema directly as an AST string in your config file. It's handy for testing. -```yaml -schema: 'type MyType { foo: String } type Query { myType: MyType }' + +```ts {4} +import { CodegenConfig } from '@graphql-codegen/cli'; + +const config: CodegenConfig = { + schema: 'type MyType { foo: String } type Query { myType: MyType }' +}; +export default config; ``` + ### GitHub You can load your schema file from a remote GitHub file, using the following syntax: -```yaml -schema: github:user/repo#branchName:path/to/file.graphql +```ts {4} +import { CodegenConfig } from '@graphql-codegen/cli'; + +const config: CodegenConfig = { + schema: 'github:user/repo#branchName:path/to/file.graphql' +}; +export default config; ``` + You can load from a JSON file, `.graphql` file, or from a code file containing `gql` tag syntax. ### Git You can load your schema file from a Git repository using the following syntax: -```yaml -schema: git:branch:path/to/file.graphql +```ts {4} +import { CodegenConfig } from '@graphql-codegen/cli'; + +const config: CodegenConfig = { + schema: 'git:branch:path/to/file.graphql' +}; +export default config; ``` You can load from a JSON file, `.graphql` file, or from a code file containing `gql` tag syntax. @@ -275,25 +456,49 @@ schema: git:branch:path/to/file.graphql You can load your schema from Apollo Engine with the following syntax: -```yaml -schema: - - apollo-engine: - engine: - apiKey: APOLLO_ENGINE_KEY_ID - graph: GRAPH_ID - variant: current +```ts +import { CodegenConfig } from '@graphql-codegen/cli'; + +const config: CodegenConfig = { + schema: [ + { + 'apollo-engine': { + engine: { + apiKey: 'APOLLO_ENGINE_KEY_ID', + }, + graph: 'GRAPH_ID', + variant: 'current', + } + } + ] +}; +export default config; + ``` ## Custom Schema Loader If your schema has a different or complicated way of loading, you can point to a single code file that works for you. -```yaml {3,5} -schema: - - http://localhost:3000/graphql: - loader: ./my-url-loader.js - - schema.graphql: - loader: ./my-file-loader.js +```ts {7,12} +import { CodegenConfig } from '@graphql-codegen/cli'; + +const config: CodegenConfig = { + schema: [ + { + 'http://localhost:3000/graphql': { + loader: './my-url-loader.js', + } + }, + { + 'schema.graphql': { + loader: './my-file-loader.js', + } + } + ], +}; +export default config; + ``` Your custom loader should export a default function that returns `GraphQLSchema` object, or an identifier called `schema`. For example: @@ -350,10 +555,20 @@ export default async () => { Add custom loader to your codegen config: -```yaml {3} -schema: - - my-api: - loader: ./codegen-loader.ts +```ts {7} +import { CodegenConfig } from '@graphql-codegen/cli'; + +const config: CodegenConfig = { + schema: [ + { + 'my-api': { + loader: './codegen-loader.ts' + } + } + ] +}; +export default config; + ``` Finally, make sure that you have installed `ts-node`, so TypeScript file can be transpiled before running codegen. diff --git a/website/src/pages/docs/getting-started/development-workflow.mdx b/website/src/pages/docs/getting-started/development-workflow.mdx index 71a3e8dbdbe..c3da310a13c 100644 --- a/website/src/pages/docs/getting-started/development-workflow.mdx +++ b/website/src/pages/docs/getting-started/development-workflow.mdx @@ -49,12 +49,21 @@ Use this when you are loading your schema or documents from a single code file t By default, watch mode uses the system's native support to listen for file change events. This can be configured in the settings file to use a stat polling method instead of in unusual cases where system support is unavailable. -```yaml -watch: true -# Passed directly through to chokidar's file watch configuration -watchConfig: - usePolling: true - interval: 1000 +```ts {6-10} +import { CodegenConfig } from '@graphql-codegen/cli' + +const config: CodegenConfig = { + schema: 'http://localhost:4000/graphql', + // ... + watch: true, + watchConfig: { + // Passed directly through to chokidar's file watch configuration + usePolling: true, + interval: 1000 + } +} + +export default config ``` ## Monorepo and Yarn Workspaces @@ -63,14 +72,23 @@ If you are using a monorepo structure, with tools such as [Yarn Workspaces](http If you need to execute the codegen multiple times, note that you can specify multiple fields for `generates` field, for example: -```yaml {4,7} -schema: 'server/src/**/*.graphql' -documents: 'client/src/**/*.graphql' -generates: - client/src/models.ts: - - typescript - - typescript-operations - server/src/models.ts: - - typescript - - typescript-resolvers +```ts {7,11} +import { CodegenConfig } from '@graphql-codegen/cli' + +const config: CodegenConfig = { + schema: 'server/src/**/*.graphql', + documents: 'client/src/**/*.graphql' + generates { + 'client/src/models.ts': [ + 'typescript', + 'typescript-operations' + ], + 'server/src/models.ts': [ + 'typescript', + 'typescript-resolver' + ] + } +} + +export default config ``` diff --git a/website/src/pages/docs/getting-started/esm-typescript-usage.mdx b/website/src/pages/docs/getting-started/esm-typescript-usage.mdx index 6a59f0b304f..ed46a0c104f 100644 --- a/website/src/pages/docs/getting-started/esm-typescript-usage.mdx +++ b/website/src/pages/docs/getting-started/esm-typescript-usage.mdx @@ -24,15 +24,22 @@ For these examples the correct ESM counterpart is `./foo.js` and `../something/f In order to instruct GraphQL Code Generator to generate such imports whenever a named import is generated you need to set the `emitLegacyCommonJSImports` option to `false`. -```yaml filename="codegen.yml" {5} -schema: https://swapi-graphql.netlify.app/.netlify/functions/index -documents: - - 'src/**/*.ts' - - '!src/gql/**/*' -emitLegacyCommonJSImports: false -generates: - ./src/gql/: - preset: gql-tag-operations-preset +```ts filename="codegen.ts" {6} +import { CodegenConfig } from '@graphql-codegen/cli' + +const config: CodegenConfig = { + schema: 'http://localhost:4000/graphql', + documents: ['src/**/*.tsx'], + emitLegacyCommonJSImports: false + generates: { + './src/gql/': { + preset: 'client', + plugins: [] + } + } +} + +export default config ``` ## TypeScript Compiler Options @@ -73,7 +80,7 @@ This step, however, is fully optional. "graphql": "16.5.0" }, "scripts": { - "codegen": "graphql-codegen-esm --config codegen.yml", + "codegen": "graphql-codegen-esm --config codegen.ts", "build": "tsc", "start": "node dist/main.js" }, diff --git a/website/src/pages/docs/integrations/apollo-local-state.mdx b/website/src/pages/docs/integrations/apollo-local-state.mdx index 4404e2fba60..fd62b918153 100644 --- a/website/src/pages/docs/integrations/apollo-local-state.mdx +++ b/website/src/pages/docs/integrations/apollo-local-state.mdx @@ -28,10 +28,13 @@ type Todo { And then, you can merge this part of the schema with your remote schema by specifying it as part of your `schema` field: -```yaml -schema: - - http://my-remote-schema/graphql - - my-client-schema.graphql +```ts +import { CodegenConfig } from '@graphql-codegen/cli' + +const config: CodegenConfig = { + schema: ['http://my-remote-schema/graphql', 'my-client-schema.graphql'] +} +export default config ``` This way, the GraphQL Code Generator will generate complete typings that match both your client fields and server fields. diff --git a/website/src/pages/docs/integrations/federation.mdx b/website/src/pages/docs/integrations/federation.mdx index 75e40d18ada..244eacef0e1 100644 --- a/website/src/pages/docs/integrations/federation.mdx +++ b/website/src/pages/docs/integrations/federation.mdx @@ -2,16 +2,20 @@ The `typescript-resolvers` plugin also supports [Apollo Federation](https://apollographql.com/docs/apollo-server/federation/introduction). -To use it, add `federation: true{:yaml}` to your configuration: +To use it, add `federation: true{:ts}` to your configuration: -```yaml {6-7} -generates: - ./src/types.ts: - plugins: - - typescript - - typescript-resolvers - config: - federation: true +```ts {6-7} +import { CodegenConfig } from '@graphql-codegen/cli' + +const config: CodegenConfig = { + generates: { + './src/types.ts': { + plugins: ['typescript', 'typescript-resolvers'], + config: { federation: true } + } + } +} +export default config ``` It will add the required GraphQL directives to your codegen schema and generate a compatible resolvers signature for Apollo Federation. diff --git a/website/src/pages/docs/integrations/prettier.mdx b/website/src/pages/docs/integrations/prettier.mdx index 141043cb80c..a042f40cc56 100644 --- a/website/src/pages/docs/integrations/prettier.mdx +++ b/website/src/pages/docs/integrations/prettier.mdx @@ -23,18 +23,28 @@ all files as stale. You can run it per each file: -```yaml -hooks: - afterOneFileWrite: - - prettier --write +```ts +import { CodegenConfig } from '@graphql-codegen/cli' + +const config: CodegenConfig = { + // ... + hooks: { afterOneFileWrite: ['prettier --write'] } + // ... +} +export default config ``` Or, for all files together: -```yaml -hooks: - afterAllFileWrite: - - prettier --write +```ts +import { CodegenConfig } from '@graphql-codegen/cli' + +const config: CodegenConfig = { + // ... + hooks: { afterAllFileWrite: ['prettier --write'] } + // ... +} +export default config ``` Consider this method if you're using `near-operation-file` preset as this has better performance when writing many files. @@ -43,32 +53,54 @@ Consider this method if you're using `near-operation-file` preset as this has be You can run it per each file: -```yaml -hooks: - afterOneFileWrite: - - tslint --fix +```ts +import { CodegenConfig } from '@graphql-codegen/cli' + +const config: CodegenConfig = { + // ... + hooks: { afterOneFileWrite: ['tslint --fix'] } + // ... +} +export default config ``` Or, for all files together: -```yaml -hooks: - afterAllFileWrite: - - tslint --fix +```ts +import { CodegenConfig } from '@graphql-codegen/cli' + +const config: CodegenConfig = { + // ... + hooks: { afterAllFileWrite: ['tslint --fix'] } + // ... +} +export default config ``` ## ESLint -```yaml -hooks: - afterOneFileWrite: - - eslint --fix +You can run it per each file: + +```ts +import { CodegenConfig } from '@graphql-codegen/cli' + +const config: CodegenConfig = { + // ... + hooks: { afterOneFileWrite: ['eslint --fix'] } + // ... +} +export default config ``` Or, for all files together: -```yaml -hooks: - afterAllFileWrite: - - eslint --fix +```ts +import { CodegenConfig } from '@graphql-codegen/cli' + +const config: CodegenConfig = { + // ... + hooks: { afterAllFileWrite: ['eslint --fix'] } + // ... +} +export default config ```