UNPKG

24.3 kBTypeScriptView Raw
1import { ApolloFederation } from '@graphql-codegen/plugin-helpers';
2import { ASTNode, DirectiveDefinitionNode, EnumTypeDefinitionNode, FieldDefinitionNode, GraphQLNamedType, GraphQLObjectType, GraphQLSchema, InputValueDefinitionNode, InterfaceTypeDefinitionNode, ListTypeNode, NamedTypeNode, NameNode, NonNullTypeNode, ObjectTypeDefinitionNode, ScalarTypeDefinitionNode, UnionTypeDefinitionNode } from 'graphql';
3import { BaseVisitor, BaseVisitorConvertOptions, ParsedConfig, RawConfig } from './base-visitor.js';
4import { ParsedMapper } from './mappers.js';
5import { AvoidOptionalsConfig, ConvertOptions, DeclarationKind, EnumValuesMap, NormalizedScalarsMap, ParsedEnumValuesMap, ResolversNonOptionalTypenameConfig } from './types.js';
6import { DeclarationBlockConfig } from './utils.js';
7import { OperationVariablesToObject } from './variables-to-object.js';
8export interface ParsedResolversConfig extends ParsedConfig {
9 contextType: ParsedMapper;
10 fieldContextTypes: Array<string>;
11 directiveContextTypes: Array<string>;
12 rootValueType: ParsedMapper;
13 mappers: {
14 [typeName: string]: ParsedMapper;
15 };
16 defaultMapper: ParsedMapper | null;
17 avoidOptionals: AvoidOptionalsConfig | boolean;
18 addUnderscoreToArgsType: boolean;
19 enumValues: ParsedEnumValuesMap;
20 resolverTypeWrapperSignature: string;
21 federation: boolean;
22 enumPrefix: boolean;
23 enumSuffix: boolean;
24 optionalResolveType: boolean;
25 immutableTypes: boolean;
26 namespacedImportName: string;
27 resolverTypeSuffix: string;
28 allResolversTypeName: string;
29 internalResolversPrefix: string;
30 onlyResolveTypeForInterfaces: boolean;
31 directiveResolverMappings: Record<string, string>;
32 resolversNonOptionalTypename: ResolversNonOptionalTypenameConfig;
33}
34export interface RawResolversConfig extends RawConfig {
35 /**
36 * @description Adds `_` to generated `Args` types in order to avoid duplicate identifiers.
37 *
38 * @exampleMarkdown
39 * ```ts filename="codegen.ts"
40 * import type { CodegenConfig } from '@graphql-codegen/cli';
41 *
42 * const config: CodegenConfig = {
43 * // ...
44 * generates: {
45 * 'path/to/file': {
46 * // plugins...
47 * config: {
48 * addUnderscoreToArgsType: true
49 * },
50 * },
51 * },
52 * };
53 * export default config;
54 * ```
55 *
56 */
57 addUnderscoreToArgsType?: boolean;
58 /**
59 * @description Use this configuration to set a custom type for your `context`, and it will
60 * affect all the resolvers, without the need to override it using generics each time.
61 * If you wish to use an external type and import it from another file, you can use `add` plugin
62 * and add the required `import` statement, or you can use a `module#type` syntax.
63 *
64 * @exampleMarkdown
65 * ## Custom Context Type
66 *
67 * ```ts filename="codegen.ts"
68 * import type { CodegenConfig } from '@graphql-codegen/cli';
69 *
70 * const config: CodegenConfig = {
71 * // ...
72 * generates: {
73 * 'path/to/file': {
74 * // plugins...
75 * config: {
76 * contextType: 'MyContext'
77 * },
78 * },
79 * },
80 * };
81 * export default config;
82 * ```
83 *
84 * ## Custom Context Type
85 *
86 * ```ts filename="codegen.ts"
87 * import type { CodegenConfig } from '@graphql-codegen/cli';
88 *
89 * const config: CodegenConfig = {
90 * // ...
91 * generates: {
92 * 'path/to/file': {
93 * // plugins...
94 * config: {
95 * contextType: './my-types#MyContext'
96 * },
97 * },
98 * },
99 * };
100 * export default config;
101 * ```
102 */
103 contextType?: string;
104 /**
105 * @description Use this to set a custom type for a specific field `context`.
106 * It will only affect the targeted resolvers.
107 * You can either use `Field.Path#ContextTypeName` or `Field.Path#ExternalFileName#ContextTypeName`
108 *
109 * @exampleMarkdown
110 * ## Custom Field Context Types
111 *
112 * ```ts filename="codegen.ts"
113 * import type { CodegenConfig } from '@graphql-codegen/cli';
114 *
115 * const config: CodegenConfig = {
116 * // ...
117 * generates: {
118 * 'path/to/file': {
119 * // plugins...
120 * config: {
121 * fieldContextTypes: ['MyType.foo#CustomContextType', 'MyType.bar#./my-file#ContextTypeOne']
122 * },
123 * },
124 * },
125 * };
126 * export default config;
127 * ```
128 *
129 */
130 fieldContextTypes?: Array<string>;
131 /**
132 * @description Use this configuration to set a custom type for the `rootValue`, and it will
133 * affect resolvers of all root types (Query, Mutation and Subscription), without the need to override it using generics each time.
134 * If you wish to use an external type and import it from another file, you can use `add` plugin
135 * and add the required `import` statement, or you can use both `module#type` or `module#namespace#type` syntax.
136 *
137 * @exampleMarkdown
138 * ## Custom RootValue Type
139 *
140 * ```ts filename="codegen.ts"
141 * import type { CodegenConfig } from '@graphql-codegen/cli';
142 *
143 * const config: CodegenConfig = {
144 * // ...
145 * generates: {
146 * 'path/to/file': {
147 * // plugins...
148 * config: {
149 * rootValueType: 'MyRootValue'
150 * },
151 * },
152 * },
153 * };
154 * export default config;
155 * ```
156 *
157 * ## Custom RootValue Type
158 *
159 * ```ts filename="codegen.ts"
160 * import type { CodegenConfig } from '@graphql-codegen/cli';
161 *
162 * const config: CodegenConfig = {
163 * // ...
164 * generates: {
165 * 'path/to/file': {
166 * // plugins...
167 * config: {
168 * rootValueType: './my-types#MyRootValue'
169 * },
170 * },
171 * },
172 * };
173 * export default config;
174 * ```
175 */
176 rootValueType?: string;
177 /**
178 * @description Use this to set a custom type for a specific field `context` decorated by a directive.
179 * It will only affect the targeted resolvers.
180 * You can either use `Field.Path#ContextTypeName` or `Field.Path#ExternalFileName#ContextTypeName`
181 *
182 * ContextTypeName should by a generic Type that take the context or field context type as only type parameter.
183 *
184 * @exampleMarkdown
185 * ## Directive Context Extender
186 *
187 * ```ts filename="codegen.ts"
188 * import type { CodegenConfig } from '@graphql-codegen/cli';
189 *
190 * const config: CodegenConfig = {
191 * // ...
192 * generates: {
193 * 'path/to/file': {
194 * // plugins...
195 * config: {
196 * directiveContextTypes: ['myCustomDirectiveName#./my-file#CustomContextExtender']
197 * },
198 * },
199 * },
200 * };
201 * export default config;
202 * ```
203 *
204 */
205 directiveContextTypes?: Array<string>;
206 /**
207 * @description Adds a suffix to the imported names to prevent name clashes.
208 *
209 * @exampleMarkdown
210 * ```ts filename="codegen.ts"
211 * import type { CodegenConfig } from '@graphql-codegen/cli';
212 *
213 * const config: CodegenConfig = {
214 * // ...
215 * generates: {
216 * 'path/to/file': {
217 * // plugins...
218 * config: {
219 * mapperTypeSuffix: 'Model'
220 * },
221 * },
222 * },
223 * };
224 * export default config;
225 * ```
226 */
227 mapperTypeSuffix?: string;
228 /**
229 * @description Replaces a GraphQL type usage with a custom type, allowing you to return custom object from
230 * your resolvers.
231 * You can use both `module#type` and `module#namespace#type` syntax.
232 *
233 * @exampleMarkdown
234 * ## Custom Context Type
235 *
236 * ```ts filename="codegen.ts"
237 * import type { CodegenConfig } from '@graphql-codegen/cli';
238 *
239 * const config: CodegenConfig = {
240 * // ...
241 * generates: {
242 * 'path/to/file': {
243 * // plugins...
244 * config: {
245 * mappers: {
246 * User: './my-models#UserDbObject',
247 * Book: './my-models#Collections',
248 * }
249 * },
250 * },
251 * },
252 * };
253 * export default config;
254 * ```
255 */
256 mappers?: {
257 [typeName: string]: string;
258 };
259 /**
260 * @description Allow you to set the default mapper when it's not being override by `mappers` or generics.
261 * You can specify a type name, or specify a string in `module#type` or `module#namespace#type` format.
262 * The default value of mappers is the TypeScript type generated by `typescript` package.
263 *
264 * @exampleMarkdown
265 * ## Replace with any
266 *
267 * ```ts filename="codegen.ts"
268 * import type { CodegenConfig } from '@graphql-codegen/cli';
269 *
270 * const config: CodegenConfig = {
271 * // ...
272 * generates: {
273 * 'path/to/file': {
274 * // plugins...
275 * config: {
276 * defaultMapper: 'any',
277 * },
278 * },
279 * },
280 * };
281 * export default config;
282 * ```
283 *
284 * ## Custom Base Object
285 *
286 * ```ts filename="codegen.ts"
287 * import type { CodegenConfig } from '@graphql-codegen/cli';
288 *
289 * const config: CodegenConfig = {
290 * // ...
291 * generates: {
292 * 'path/to/file': {
293 * // plugins...
294 * config: {
295 * defaultMapper: './my-file#BaseObject',
296 * },
297 * },
298 * },
299 * };
300 * export default config;
301 * ```
302 *
303 * ## Wrap default types with Partial
304 *
305 * You can also specify a custom wrapper for the original type, without overriding the original generated types, use `{T}` to specify the identifier. (for flow, use `$Shape<{T}>`)
306 *
307 * ```ts filename="codegen.ts"
308 * import type { CodegenConfig } from '@graphql-codegen/cli';
309 *
310 * const config: CodegenConfig = {
311 * // ...
312 * generates: {
313 * 'path/to/file': {
314 * // plugins...
315 * config: {
316 * defaultMapper: 'Partial<{T}>',
317 * },
318 * },
319 * },
320 * };
321 * export default config;
322 * ```
323 *
324 * ## Allow deep partial with `utility-types`
325 *
326 * ```ts filename="codegen.ts"
327 * import type { CodegenConfig } from '@graphql-codegen/cli';
328 *
329 * const config: CodegenConfig = {
330 * // ...
331 * generates: {
332 * 'path/to/file': {
333 * plugins: ['typescript', 'typescript-resolver', { add: { content: "import { DeepPartial } from 'utility-types';" } }],
334 * config: {
335 * defaultMapper: 'DeepPartial<{T}>',
336 * },
337 * },
338 * },
339 * };
340 * export default config;
341 * ```
342 */
343 defaultMapper?: string;
344 /**
345 * @description This will cause the generator to avoid using optionals (`?`),
346 * so all field resolvers must be implemented in order to avoid compilation errors.
347 * @default false
348 *
349 * @exampleMarkdown
350 * ## Override all definition types
351 *
352 * ```ts filename="codegen.ts"
353 * import type { CodegenConfig } from '@graphql-codegen/cli';
354 *
355 * const config: CodegenConfig = {
356 * // ...
357 * generates: {
358 * 'path/to/file': {
359 * plugins: ['typescript', 'typescript-resolver'],
360 * config: {
361 * avoidOptionals: true
362 * },
363 * },
364 * },
365 * };
366 * export default config;
367 * ```
368 *
369 * ## Override only specific definition types
370 *
371 * ```ts filename="codegen.ts"
372 * import type { CodegenConfig } from '@graphql-codegen/cli';
373 *
374 * const config: CodegenConfig = {
375 * // ...
376 * generates: {
377 * 'path/to/file': {
378 * plugins: ['typescript', 'typescript-resolver'],
379 * config: {
380 * avoidOptionals: {
381 * field: true,
382 * inputValue: true,
383 * object: true,
384 * defaultValue: true,
385 * }
386 * },
387 * },
388 * },
389 * };
390 * export default config;
391 * ```
392 */
393 avoidOptionals?: boolean | AvoidOptionalsConfig;
394 /**
395 * @description Warns about unused mappers.
396 * @default true
397 *
398 * @exampleMarkdown
399 * ```ts filename="codegen.ts"
400 * import type { CodegenConfig } from '@graphql-codegen/cli';
401 *
402 * const config: CodegenConfig = {
403 * // ...
404 * generates: {
405 * 'path/to/file': {
406 * plugins: ['typescript', 'typescript-resolver'],
407 * config: {
408 * showUnusedMappers: true,
409 * },
410 * },
411 * },
412 * };
413 * export default config;
414 * ```
415 */
416 showUnusedMappers?: boolean;
417 /**
418 * @description Overrides the default value of enum values declared in your GraphQL schema, supported
419 * in this plugin because of the need for integration with `typescript` package.
420 * See documentation under `typescript` plugin for more information and examples.
421 */
422 enumValues?: EnumValuesMap;
423 /**
424 * @default Promise<T> | T
425 * @description Allow you to override `resolverTypeWrapper` definition.
426 */
427 resolverTypeWrapperSignature?: string;
428 /**
429 * @default false
430 * @description Supports Apollo Federation
431 */
432 federation?: boolean;
433 /**
434 * @default true
435 * @description Allow you to disable prefixing for generated enums, works in combination with `typesPrefix`.
436 *
437 * @exampleMarkdown
438 * ## Disable enum prefixes
439 *
440 * ```ts filename="codegen.ts"
441 * import type { CodegenConfig } from '@graphql-codegen/cli';
442 *
443 * const config: CodegenConfig = {
444 * // ...
445 * generates: {
446 * 'path/to/file': {
447 * plugins: ['typescript', 'typescript-resolver'],
448 * config: {
449 * typesPrefix: 'I',
450 * enumPrefix: false
451 * },
452 * },
453 * },
454 * };
455 * export default config;
456 * ```
457 */
458 enumPrefix?: boolean;
459 /**
460 * @default true
461 * @description Allow you to disable suffixing for generated enums, works in combination with `typesSuffix`.
462 *
463 * @exampleMarkdown
464 * ## Disable enum suffixes
465 *
466 * ```ts filename="codegen.ts"
467 * import type { CodegenConfig } from '@graphql-codegen/cli';
468 *
469 * const config: CodegenConfig = {
470 * // ...
471 * generates: {
472 * 'path/to/file': {
473 * plugins: ['typescript', 'typescript-resolver'],
474 * config: {
475 * typesSuffix: 'I',
476 * enumSuffix: false
477 * },
478 * },
479 * },
480 * };
481 * export default config;
482 * ```
483 */
484 enumSuffix?: boolean;
485 /**
486 * @default false
487 * @description Sets the `__resolveType` field as optional field.
488 */
489 optionalResolveType?: boolean;
490 /**
491 * @default false
492 * @description Generates immutable types by adding `readonly` to properties and uses `ReadonlyArray`.
493 */
494 immutableTypes?: boolean;
495 /**
496 * @default ''
497 * @description Prefixes all GraphQL related generated types with that value, as namespaces import.
498 * You can use this feature to allow separation of plugins to different files.
499 */
500 namespacedImportName?: string;
501 /**
502 * @default Resolvers
503 * @description Suffix we add to each generated type resolver.
504 */
505 resolverTypeSuffix?: string;
506 /**
507 * @default Resolvers
508 * @description The type name to use when exporting all resolvers signature as unified type.
509 */
510 allResolversTypeName?: string;
511 /**
512 * @type string
513 * @default '__'
514 * @description Defines the prefix value used for `__resolveType` and `__isTypeOf` resolvers.
515 * If you are using `mercurius-js`, please set this field to empty string for better compatibility.
516 */
517 internalResolversPrefix?: string;
518 /**
519 * @type boolean
520 * @default false
521 * @description Turning this flag to `true` will generate resolver signature that has only `resolveType` for interfaces, forcing developers to write inherited type resolvers in the type itself.
522 */
523 onlyResolveTypeForInterfaces?: boolean;
524 /**
525 * @description Makes `__typename` of resolver mappings non-optional without affecting the base types.
526 * @default false
527 *
528 * @exampleMarkdown
529 * ## Enable for all
530 *
531 * ```ts filename="codegen.ts"
532 * import type { CodegenConfig } from '@graphql-codegen/cli';
533 *
534 * const config: CodegenConfig = {
535 * // ...
536 * generates: {
537 * 'path/to/file': {
538 * plugins: ['typescript', 'typescript-resolver'],
539 * config: {
540 * resolversNonOptionalTypename: true // or { unionMember: true, interfaceImplementingType: true }
541 * },
542 * },
543 * },
544 * };
545 * export default config;
546 * ```
547 *
548 * ## Enable except for some types
549 *
550 * ```ts filename="codegen.ts"
551 * import type { CodegenConfig } from '@graphql-codegen/cli';
552 *
553 * const config: CodegenConfig = {
554 * // ...
555 * generates: {
556 * 'path/to/file': {
557 * plugins: ['typescript', 'typescript-resolver'],
558 * config: {
559 * resolversNonOptionalTypename: {
560 * unionMember: true,
561 * interfaceImplementingType: true,
562 * excludeTypes: ['MyType'],
563 * }
564 * },
565 * },
566 * },
567 * };
568 * export default config;
569 * ```
570 */
571 resolversNonOptionalTypename?: boolean | ResolversNonOptionalTypenameConfig;
572 /**
573 * @ignore
574 */
575 directiveResolverMappings?: Record<string, string>;
576}
577export type ResolverTypes = {
578 [gqlType: string]: string;
579};
580export type ResolverParentTypes = {
581 [gqlType: string]: string;
582};
583export type GroupedMappers = Record<string, {
584 identifier: string;
585 asDefault?: boolean;
586}[]>;
587type FieldContextTypeMap = Record<string, ParsedMapper>;
588export declare class BaseResolversVisitor<TRawConfig extends RawResolversConfig = RawResolversConfig, TPluginConfig extends ParsedResolversConfig = ParsedResolversConfig> extends BaseVisitor<TRawConfig, TPluginConfig> {
589 private _schema;
590 protected _parsedConfig: TPluginConfig;
591 protected _declarationBlockConfig: DeclarationBlockConfig;
592 protected _collectedResolvers: {
593 [key: string]: string;
594 };
595 protected _collectedDirectiveResolvers: {
596 [key: string]: string;
597 };
598 protected _variablesTransformer: OperationVariablesToObject;
599 protected _usedMappers: {
600 [key: string]: boolean;
601 };
602 protected _resolversTypes: ResolverTypes;
603 protected _resolversParentTypes: ResolverParentTypes;
604 protected _hasReferencedResolversUnionTypes: boolean;
605 protected _hasReferencedResolversInterfaceTypes: boolean;
606 protected _resolversUnionTypes: Record<string, string>;
607 protected _resolversUnionParentTypes: Record<string, string>;
608 protected _resolversInterfaceTypes: Record<string, string>;
609 protected _rootTypeNames: Set<string>;
610 protected _globalDeclarations: Set<string>;
611 protected _federation: ApolloFederation;
612 protected _hasScalars: boolean;
613 protected _hasFederation: boolean;
614 protected _fieldContextTypeMap: FieldContextTypeMap;
615 protected _directiveContextTypesMap: FieldContextTypeMap;
616 private _directiveResolverMappings;
617 private _shouldMapType;
618 constructor(rawConfig: TRawConfig, additionalConfig: TPluginConfig, _schema: GraphQLSchema, defaultScalars?: NormalizedScalarsMap);
619 getResolverTypeWrapperSignature(): string;
620 protected shouldMapType(type: GraphQLNamedType, duringCheck?: string[]): boolean;
621 convertName(node: ASTNode | string, options?: BaseVisitorConvertOptions & ConvertOptions, applyNamespacedImport?: boolean): string;
622 protected createResolversFields({ applyWrapper, clearWrapper, getTypeToUse, currentType, shouldInclude, }: {
623 applyWrapper: (str: string) => string;
624 clearWrapper: (str: string) => string;
625 getTypeToUse: (str: string) => string;
626 currentType: 'ResolversTypes' | 'ResolversParentTypes';
627 shouldInclude?: (type: GraphQLNamedType) => boolean;
628 }): ResolverTypes;
629 protected replaceFieldsInType(typeName: string, relevantFields: ReturnType<typeof this.getRelevantFieldsToOmit>): string;
630 protected applyMaybe(str: string): string;
631 protected applyResolverTypeWrapper(str: string): string;
632 protected clearMaybe(str: string): string;
633 protected clearResolverTypeWrapper(str: string): string;
634 protected wrapWithArray(t: string): string;
635 protected createResolversUnionTypes(): Record<string, string>;
636 protected createResolversInterfaceTypes(): Record<string, string>;
637 /**
638 * Function to generate the types of Abstract Type Members i.e. Union Members or Interface Implementing Types
639 */
640 getAbstractMembersType({ typeName, memberTypes, isTypenameNonOptional, }: {
641 typeName: string;
642 memberTypes: readonly GraphQLObjectType[] | GraphQLObjectType[];
643 isTypenameNonOptional: boolean;
644 }): string;
645 protected createFieldContextTypeMap(): FieldContextTypeMap;
646 protected createDirectivedContextType(): FieldContextTypeMap;
647 buildResolversTypes(): string;
648 buildResolversParentTypes(): string;
649 buildResolversUnionTypes(): string;
650 buildResolversInterfaceTypes(): string;
651 get schema(): GraphQLSchema;
652 get defaultMapperType(): string;
653 get unusedMappers(): string[];
654 get globalDeclarations(): string[];
655 protected isMapperImported(groupedMappers: GroupedMappers, identifier: string, source: string): boolean;
656 get mappersImports(): string[];
657 setDeclarationBlockConfig(config: DeclarationBlockConfig): void;
658 setVariablesTransformer(variablesTransfomer: OperationVariablesToObject): void;
659 hasScalars(): boolean;
660 hasFederation(): boolean;
661 getRootResolver(): string;
662 protected formatRootResolver(schemaTypeName: string, resolverType: string, declarationKind: DeclarationKind): string;
663 getAllDirectiveResolvers(): string;
664 Name(node: NameNode): string;
665 ListType(node: ListTypeNode): string;
666 protected _getScalar(name: string): string;
667 NamedType(node: NamedTypeNode): string;
668 NonNullType(node: NonNullTypeNode): string;
669 protected markMapperAsUsed(name: string): void;
670 protected getTypeToUse(name: string): string;
671 protected getParentTypeToUse(name: string): string;
672 protected getParentTypeForSignature(_node: FieldDefinitionNode): string;
673 protected transformParentGenericType(parentType: string): string;
674 FieldDefinition(node: FieldDefinitionNode, key: string | number, parent: any): (parentName: string) => string | null;
675 private getFieldContextType;
676 private getContextType;
677 protected applyRequireFields(argsType: string, fields: InputValueDefinitionNode[]): string;
678 protected applyOptionalFields(argsType: string, _fields: readonly InputValueDefinitionNode[]): string;
679 ObjectTypeDefinition(node: ObjectTypeDefinitionNode): string;
680 UnionTypeDefinition(node: UnionTypeDefinitionNode, key: string | number, parent: any): string;
681 ScalarTypeDefinition(node: ScalarTypeDefinitionNode): string;
682 DirectiveDefinition(node: DirectiveDefinitionNode, key: string | number, parent: any): string;
683 protected buildEnumResolverContentBlock(_node: EnumTypeDefinitionNode, _mappedEnumType: string): string;
684 protected buildEnumResolversExplicitMappedValues(_node: EnumTypeDefinitionNode, _valuesMapping: {
685 [valueName: string]: string | number;
686 }): string;
687 EnumTypeDefinition(node: EnumTypeDefinitionNode): string;
688 InterfaceTypeDefinition(node: InterfaceTypeDefinitionNode): string;
689 SchemaDefinition(): any;
690 private getRelevantFieldsToOmit;
691}
692export {};