UNPKG

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