-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Adjust config inheritance to reflect usage and type-hint better #10560
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| --- | ||
| '@graphql-codegen/visitor-plugin-common': major | ||
| '@graphql-codegen/typescript-operations': major | ||
| '@graphql-codegen/typescript': major | ||
| '@graphql-codegen/typescript-resolvers': major | ||
| --- | ||
|
|
||
| BREAKING CHANGE: visitors' config option are moved based on their use case | ||
|
|
||
| - addTypename/skipTypename: is only a types-visitor concern. This is moved to types-visitor from base-visitor | ||
| - nonOptionalTypename: is a documents-visitor and types-visitor concern. Moved from base-visitor there | ||
| - extractAllFieldsToTypes: is a documents-visitor concern. Moved from base-visitor there | ||
| - enumPrefix and enumSuffix: need to be in base-visitor as all 3 types of visitors need this to correctly sync the enum type names. This is moved to base visitor | ||
| - ignoreEnumValuesFromSchema: is a documents-visitor and types-visitor concern. Moved from base-visitor there. | ||
| - globalNamespace: is a documents-visitor concern. Moved from base-visitor there | ||
|
|
||
| Refactors | ||
|
|
||
| - documents-visitor no longer extends types-visitor _option types_ as they have two distinct usages now. The types now extend base-visitor types. This is now consistent with documents-visitor extending base-visitor | ||
| - Classes now handle config parsing and types at the same level e.g. if typescript-operations plugin parses configOne, then the types for configOne must be in that class, rather than in base-documents-visitor | ||
|
|
||
| Note: These visitors are rolled up into one type for simplicity | ||
|
|
||
| - base-visitor: includes `base-visitor` | ||
| - documents-visitor: includes `base-documents-visitor` and `typescript-operations` visitor | ||
| - types-visitor: includes `base-types-visitor` and `typescript` visitor | ||
| - resolvers-visitor: includes `base-resolvers-visitor` and `typescript-resolvers` visitor |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,43 +7,31 @@ import { | |
| OperationTypeNode, | ||
| VariableDefinitionNode, | ||
| } from 'graphql'; | ||
| import { ParsedTypesConfig, RawTypesConfig } from './base-types-visitor.js'; | ||
| import { BaseVisitor } from './base-visitor.js'; | ||
| import { BaseVisitor, type RawConfig, type ParsedConfig } from './base-visitor.js'; | ||
| import { DEFAULT_SCALARS } from './scalars.js'; | ||
| import { SelectionSetToObject } from './selection-set-to-object.js'; | ||
| import { NormalizedScalarsMap, CustomDirectivesConfig } from './types.js'; | ||
| import { buildScalarsFromConfig, DeclarationBlock, DeclarationBlockConfig, getConfigValue } from './utils.js'; | ||
| import { OperationVariablesToObject } from './variables-to-object.js'; | ||
|
|
||
| function getRootType(operation: OperationTypeNode, schema: GraphQLSchema) { | ||
| switch (operation) { | ||
| case 'query': | ||
| return schema.getQueryType(); | ||
| case 'mutation': | ||
| return schema.getMutationType(); | ||
| case 'subscription': | ||
| return schema.getSubscriptionType(); | ||
| } | ||
| throw new Error(`Unknown operation type: ${operation}`); | ||
| } | ||
|
|
||
| export interface ParsedDocumentsConfig extends ParsedTypesConfig { | ||
| export interface ParsedDocumentsConfig extends ParsedConfig { | ||
| extractAllFieldsToTypes: boolean; | ||
| globalNamespace: boolean; | ||
| operationResultSuffix: string; | ||
| dedupeOperationSuffix: boolean; | ||
| omitOperationSuffix: boolean; | ||
| namespacedImportName: string | null; | ||
| exportFragmentSpreadSubTypes: boolean; | ||
| skipTypeNameForRoot: boolean; | ||
| nonOptionalTypename: boolean; | ||
| globalNamespace: boolean; | ||
| experimentalFragmentVariables: boolean; | ||
| mergeFragmentTypes: boolean; | ||
| customDirectives: CustomDirectivesConfig; | ||
| generatesOperationTypes: boolean; | ||
| importSchemaTypesFrom: string; | ||
| } | ||
|
|
||
| export interface RawDocumentsConfig extends RawTypesConfig { | ||
| export interface RawDocumentsConfig extends RawConfig { | ||
| /** | ||
| * @default false | ||
| * @description Avoid adding `__typename` for root types. This is ignored when a selection explicitly specifies `__typename`. | ||
|
|
@@ -67,6 +55,30 @@ export interface RawDocumentsConfig extends RawTypesConfig { | |
| * ``` | ||
| */ | ||
| skipTypeNameForRoot?: boolean; | ||
| /** | ||
| * @default false | ||
| * @description Automatically adds `__typename` field to the generated types, even when they are not specified | ||
| * in the selection set, and makes it non-optional | ||
| * | ||
| * @exampleMarkdown | ||
| * ```ts filename="codegen.ts" | ||
| * import type { CodegenConfig } from '@graphql-codegen/cli'; | ||
| * | ||
| * const config: CodegenConfig = { | ||
| * // ... | ||
| * generates: { | ||
| * 'path/to/file': { | ||
| * // plugins... | ||
| * config: { | ||
| * nonOptionalTypename: true | ||
| * }, | ||
| * }, | ||
| * }, | ||
| * }; | ||
| * export default config; | ||
| * ``` | ||
| */ | ||
| nonOptionalTypename?: boolean; | ||
| /** | ||
| * @default false | ||
| * @description Puts all generated code under `global` namespace. Useful for Stencil integration. | ||
|
|
@@ -199,6 +211,14 @@ export interface RawDocumentsConfig extends RawTypesConfig { | |
| * ``` | ||
| */ | ||
| importSchemaTypesFrom?: string; | ||
| /** | ||
| * @default false | ||
| * @description Extract all field types to their own types, instead of inlining them. | ||
| * This helps to reduce type duplication, and makes type errors more readable. | ||
| * It can also significantly reduce the size of the generated code, the generation time, | ||
| * and the typechecking time. | ||
| */ | ||
| extractAllFieldsToTypes?: boolean; | ||
| } | ||
|
|
||
| export class BaseDocumentsVisitor< | ||
|
|
@@ -218,11 +238,10 @@ export class BaseDocumentsVisitor< | |
| ) { | ||
| super(rawConfig, { | ||
| exportFragmentSpreadSubTypes: getConfigValue(rawConfig.exportFragmentSpreadSubTypes, false), | ||
| enumPrefix: getConfigValue(rawConfig.enumPrefix, true), | ||
| enumSuffix: getConfigValue(rawConfig.enumSuffix, true), | ||
| dedupeOperationSuffix: getConfigValue(rawConfig.dedupeOperationSuffix, false), | ||
| omitOperationSuffix: getConfigValue(rawConfig.omitOperationSuffix, false), | ||
| skipTypeNameForRoot: getConfigValue(rawConfig.skipTypeNameForRoot, false), | ||
| nonOptionalTypename: getConfigValue(rawConfig.nonOptionalTypename, false), | ||
| namespacedImportName: getConfigValue(rawConfig.namespacedImportName, null), | ||
| experimentalFragmentVariables: getConfigValue(rawConfig.experimentalFragmentVariables, false), | ||
| globalNamespace: !!rawConfig.globalNamespace, | ||
|
|
@@ -231,6 +250,7 @@ export class BaseDocumentsVisitor< | |
| customDirectives: getConfigValue(rawConfig.customDirectives, { apolloUnmask: false }), | ||
| generatesOperationTypes: getConfigValue(rawConfig.generatesOperationTypes, true), | ||
| importSchemaTypesFrom: getConfigValue(rawConfig.importSchemaTypesFrom, ''), | ||
| extractAllFieldsToTypes: getConfigValue(rawConfig.extractAllFieldsToTypes, false), | ||
| ...((additionalConfig || {}) as any), | ||
| }); | ||
|
|
||
|
|
@@ -380,3 +400,15 @@ export class BaseDocumentsVisitor< | |
| .join('\n\n'); | ||
| } | ||
| } | ||
|
|
||
| function getRootType(operation: OperationTypeNode, schema: GraphQLSchema) { | ||
| switch (operation) { | ||
| case 'query': | ||
| return schema.getQueryType(); | ||
| case 'mutation': | ||
| return schema.getMutationType(); | ||
| case 'subscription': | ||
| return schema.getSubscriptionType(); | ||
| } | ||
| throw new Error(`Unknown operation type: ${operation}`); | ||
| } | ||
|
Comment on lines
+404
to
+414
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I drived-by moved this function here to make the first bit of this file the related to visitor. This is done fairly consistently across the codebase now to help readability and navigation |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -69,8 +69,6 @@ export interface ParsedResolversConfig extends ParsedConfig { | |
| enumValues: ParsedEnumValuesMap; | ||
| resolverTypeWrapperSignature: string; | ||
| federation: boolean; | ||
| enumPrefix: boolean; | ||
| enumSuffix: boolean; | ||
| optionalResolveType: boolean; | ||
| immutableTypes: boolean; | ||
| namespacedImportName: string; | ||
|
|
@@ -509,59 +507,7 @@ export interface RawResolversConfig extends RawConfig { | |
| * @description Supports Apollo Federation | ||
| */ | ||
| federation?: boolean; | ||
| /** | ||
| * @default true | ||
| * @description Allow you to disable prefixing for generated enums, works in combination with `typesPrefix`. | ||
| * | ||
| * @exampleMarkdown | ||
| * ## Disable enum prefixes | ||
| * | ||
| * ```ts filename="codegen.ts" | ||
| * import type { CodegenConfig } from '@graphql-codegen/cli'; | ||
| * | ||
| * const config: CodegenConfig = { | ||
| * // ... | ||
| * generates: { | ||
| * 'path/to/file': { | ||
| * plugins: ['typescript', 'typescript-resolver'], | ||
| * config: { | ||
| * typesPrefix: 'I', | ||
| * enumPrefix: false | ||
| * }, | ||
| * }, | ||
| * }, | ||
| * }; | ||
| * export default config; | ||
| * ``` | ||
| */ | ||
| enumPrefix?: boolean; | ||
|
|
||
| /** | ||
| * @default true | ||
| * @description Allow you to disable suffixing for generated enums, works in combination with `typesSuffix`. | ||
| * | ||
| * @exampleMarkdown | ||
| * ## Disable enum suffixes | ||
| * | ||
| * ```ts filename="codegen.ts" | ||
| * import type { CodegenConfig } from '@graphql-codegen/cli'; | ||
| * | ||
| * const config: CodegenConfig = { | ||
| * // ... | ||
| * generates: { | ||
| * 'path/to/file': { | ||
| * plugins: ['typescript', 'typescript-resolver'], | ||
| * config: { | ||
| * typesSuffix: 'I', | ||
| * enumSuffix: false | ||
| * }, | ||
| * }, | ||
| * }, | ||
| * }; | ||
| * export default config; | ||
| * ``` | ||
| */ | ||
| enumSuffix?: boolean; | ||
| /** | ||
| * @description Configures behavior for custom directives from various GraphQL libraries. | ||
| * @exampleMarkdown | ||
|
|
@@ -795,8 +741,6 @@ export class BaseResolversVisitor< | |
| super(rawConfig, { | ||
| immutableTypes: getConfigValue(rawConfig.immutableTypes, false), | ||
| optionalResolveType: getConfigValue(rawConfig.optionalResolveType, false), | ||
| enumPrefix: getConfigValue(rawConfig.enumPrefix, true), | ||
| enumSuffix: getConfigValue(rawConfig.enumSuffix, true), | ||
|
Comment on lines
-798
to
-799
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As mentioned in the description. This is moved to |
||
| federation: getConfigValue(rawConfig.federation, false), | ||
| resolverTypeWrapperSignature: getConfigValue(rawConfig.resolverTypeWrapperSignature, 'Promise<T> | T'), | ||
| enumValues: parseEnumValues({ | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Previously,
documents-visitorextendstypes-visitorconfig types, however,BaseDocumentsVisitorextendsBaseVisitor, instead ofBaseTypesVisitor.This may have created some confusion (at least for me) of which option is used for which use case. This change correctly reflects the inheritance path for the visitors.