From 5aa95aa969993043ba5e9d5dabebd7127ea5e22c Mon Sep 17 00:00:00 2001 From: Eddy Nguyen Date: Fri, 28 Apr 2023 08:44:56 +1000 Subject: [PATCH] [typescript-resolvers] Extract interface types into ResolversInterfaceTypes + add interface to resolversNonOptionalTypename + simplify ResolversUnionTypes (#9229) * Extract Interface Types to separate type in TypeScript resolvers * Make ResolversUnionTypes similar to ResolversInterfaceTypes --- .changeset/long-pears-peel.md | 8 + .changeset/tricky-swans-happen.md | 100 +++ dev-test/modules/types.ts | 11 +- .../src/base-resolvers-visitor.ts | 222 +++--- .../other/visitor-plugin-common/src/types.ts | 1 + .../plugins/typescript/resolvers/src/index.ts | 4 +- .../__snapshots__/ts-resolvers.spec.ts.snap | 114 +-- .../resolvers/tests/mapping.spec.ts | 677 ++++++++++-------- .../resolvers/tests/ts-resolvers.spec.ts | 318 ++++++-- 9 files changed, 922 insertions(+), 533 deletions(-) create mode 100644 .changeset/long-pears-peel.md create mode 100644 .changeset/tricky-swans-happen.md diff --git a/.changeset/long-pears-peel.md b/.changeset/long-pears-peel.md new file mode 100644 index 00000000000..86541f8f412 --- /dev/null +++ b/.changeset/long-pears-peel.md @@ -0,0 +1,8 @@ +--- +'@graphql-codegen/visitor-plugin-common': minor +'@graphql-codegen/typescript-resolvers': minor +--- + +Use generic to simplify ResolversUnionTypes + +This follows the `ResolversInterfaceTypes`'s approach where the `RefType` generic is used to refer back to `ResolversTypes` or `ResolversParentTypes` in cases of nested Union types diff --git a/.changeset/tricky-swans-happen.md b/.changeset/tricky-swans-happen.md new file mode 100644 index 00000000000..1d9d7e100ae --- /dev/null +++ b/.changeset/tricky-swans-happen.md @@ -0,0 +1,100 @@ +--- +'@graphql-codegen/visitor-plugin-common': minor +'@graphql-codegen/typescript-resolvers': minor +--- + +Extract interfaces to ResolversInterfaceTypes and add to resolversNonOptionalTypename + +1. `ResolversInterfaceTypes` is a new type that keeps track of a GraphQL interface and its implementing types. + +For example, consider this schema: + +```graphql +extend type Query { + character(id: ID!): CharacterNode +} + +interface CharacterNode { + id: ID! +} + +type Wizard implements CharacterNode { + id: ID! + screenName: String! + spells: [String!]! +} + +type Fighter implements CharacterNode { + id: ID! + screenName: String! + powerLevel: Int! +} +``` + +The generated types will look like this: + +```ts +export type ResolversInterfaceTypes> = { + CharacterNode: Fighter | Wizard; +}; + +export type ResolversTypes = { + // other types... + CharacterNode: ResolverTypeWrapper["CharacterNode"]>; + Fighter: ResolverTypeWrapper; + Wizard: ResolverTypeWrapper; + // other types... +}; + +export type ResolversParentTypes = { + // other types... + CharacterNode: ResolversInterfaceTypes["CharacterNode"]; + Fighter: Fighter; + Wizard: Wizard; + // other types... +}; +``` + +The `RefType` generic is used to reference back to `ResolversTypes` and `ResolversParentTypes` in some cases such as field returning a Union. + +2. `resolversNonOptionalTypename` also affects `ResolversInterfaceTypes` + +Using the schema above, if we use `resolversNonOptionalTypename` option: + +```typescript +const config: CodegenConfig = { + schema: 'src/schema/**/*.graphql', + generates: { + 'src/schema/types.ts': { + plugins: ['typescript', 'typescript-resolvers'], + config: { + resolversNonOptionalTypename: true // Or `resolversNonOptionalTypename: { interfaceImplementingType: true }` + } + }, + }, +}; +``` + +Then, the generated type looks like this: + +```ts +export type ResolversInterfaceTypes> = { + CharacterNode: (Fighter & { __typename: "Fighter" }) | (Wizard & { __typename: "Wizard" }); +}; + +export type ResolversTypes = { + // other types... + CharacterNode: ResolverTypeWrapper["CharacterNode"]>; + Fighter: ResolverTypeWrapper; + Wizard: ResolverTypeWrapper; + // other types... +}; + +export type ResolversParentTypes = { + // other types... + CharacterNode: ResolversInterfaceTypes["CharacterNode"]; + Fighter: Fighter; + Wizard: Wizard; + // other types... +}; +``` diff --git a/dev-test/modules/types.ts b/dev-test/modules/types.ts index 7f31678c4a4..05c9718ccae 100644 --- a/dev-test/modules/types.ts +++ b/dev-test/modules/types.ts @@ -163,12 +163,7 @@ export type DirectiveResolverFn TResult | Promise; /** Mapping of union types */ -export type ResolversUnionTypes = { - PaymentOption: CreditCard | Paypal; -}; - -/** Mapping of union parent types */ -export type ResolversUnionParentTypes = { +export type ResolversUnionTypes> = { PaymentOption: CreditCard | Paypal; }; @@ -183,7 +178,7 @@ export type ResolversTypes = { ID: ResolverTypeWrapper; Int: ResolverTypeWrapper; Mutation: ResolverTypeWrapper<{}>; - PaymentOption: ResolverTypeWrapper; + PaymentOption: ResolverTypeWrapper['PaymentOption']>; Paypal: ResolverTypeWrapper; Query: ResolverTypeWrapper<{}>; String: ResolverTypeWrapper; @@ -203,7 +198,7 @@ export type ResolversParentTypes = { ID: Scalars['ID']; Int: Scalars['Int']; Mutation: {}; - PaymentOption: ResolversUnionParentTypes['PaymentOption']; + PaymentOption: ResolversUnionTypes['PaymentOption']; Paypal: Paypal; Query: {}; String: Scalars['String']; diff --git a/packages/plugins/other/visitor-plugin-common/src/base-resolvers-visitor.ts b/packages/plugins/other/visitor-plugin-common/src/base-resolvers-visitor.ts index d48ef4c617e..d54a626c690 100644 --- a/packages/plugins/other/visitor-plugin-common/src/base-resolvers-visitor.ts +++ b/packages/plugins/other/visitor-plugin-common/src/base-resolvers-visitor.ts @@ -568,9 +568,10 @@ export class BaseResolversVisitor< protected _resolversTypes: ResolverTypes = {}; protected _resolversParentTypes: ResolverParentTypes = {}; protected _hasReferencedResolversUnionTypes = false; - protected _hasReferencedResolversUnionParentTypes = false; + protected _hasReferencedResolversInterfaceTypes = false; protected _resolversUnionTypes: Record = {}; protected _resolversUnionParentTypes: Record = {}; + protected _resolversInterfaceTypes: Record = {}; protected _rootTypeNames = new Set(); protected _globalDeclarations = new Set(); protected _federation: ApolloFederation; @@ -632,21 +633,17 @@ export class BaseResolversVisitor< applyWrapper: type => this.applyResolverTypeWrapper(type), clearWrapper: type => this.clearResolverTypeWrapper(type), getTypeToUse: name => this.getTypeToUse(name), - referencedUnionType: 'ResolversUnionTypes', + currentType: 'ResolversTypes', }); this._resolversParentTypes = this.createResolversFields({ applyWrapper: type => type, clearWrapper: type => type, getTypeToUse: name => this.getParentTypeToUse(name), - referencedUnionType: 'ResolversUnionParentTypes', + currentType: 'ResolversParentTypes', shouldInclude: namedType => !isEnumType(namedType), }); - this._resolversUnionTypes = this.createResolversUnionTypes({ - getTypeToUse: this.getTypeToUse, - }); - this._resolversUnionParentTypes = this.createResolversUnionTypes({ - getTypeToUse: this.getParentTypeToUse, - }); + this._resolversUnionTypes = this.createResolversUnionTypes(); + this._resolversInterfaceTypes = this.createResolversInterfaceTypes(); this._fieldContextTypeMap = this.createFieldContextTypeMap(); this._directiveContextTypesMap = this.createDirectivedContextType(); this._directiveResolverMappings = rawConfig.directiveResolverMappings ?? {}; @@ -714,13 +711,13 @@ export class BaseResolversVisitor< applyWrapper, clearWrapper, getTypeToUse, - referencedUnionType, + currentType, shouldInclude, }: { applyWrapper: (str: string) => string; clearWrapper: (str: string) => string; getTypeToUse: (str: string) => string; - referencedUnionType: 'ResolversUnionTypes' | 'ResolversUnionParentTypes'; + currentType: 'ResolversTypes' | 'ResolversParentTypes'; shouldInclude?: (type: GraphQLNamedType) => boolean; }): ResolverTypes { const allSchemaTypes = this._schema.getTypeMap(); @@ -756,24 +753,6 @@ export class BaseResolversVisitor< if (isMapped && this.config.mappers[typeName].type && !hasPlaceholder(this.config.mappers[typeName].type)) { this.markMapperAsUsed(typeName); prev[typeName] = applyWrapper(this.config.mappers[typeName].type); - } else if (isInterfaceType(schemaType)) { - const allTypesMap = this._schema.getTypeMap(); - const implementingTypes: string[] = []; - - for (const graphqlType of Object.values(allTypesMap)) { - if (graphqlType instanceof GraphQLObjectType) { - const allInterfaces = graphqlType.getInterfaces(); - - if (allInterfaces.some(int => int.name === schemaType.name)) { - implementingTypes.push(graphqlType.name); - } - } - } - - const possibleTypes = implementingTypes.map(name => getTypeToUse(name)).join(' | ') || 'never'; - - prev[typeName] = possibleTypes; - return prev; } else if (isEnumType(schemaType) && this.config.enumValues[typeName]) { prev[typeName] = this.config.enumValues[typeName].sourceIdentifier || @@ -782,14 +761,17 @@ export class BaseResolversVisitor< prev[typeName] = applyWrapper(this.config.defaultMapper.type); } else if (isScalar) { prev[typeName] = applyWrapper(this._getScalar(typeName)); + } else if (isInterfaceType(schemaType)) { + this._hasReferencedResolversInterfaceTypes = true; + const type = this.convertName('ResolversInterfaceTypes'); + const generic = this.convertName(currentType); + prev[typeName] = applyWrapper(`${type}<${generic}>['${typeName}']`); + return prev; } else if (isUnionType(schemaType)) { - if (referencedUnionType === 'ResolversUnionTypes') { - this._hasReferencedResolversUnionTypes = true; - } else if (referencedUnionType === 'ResolversUnionParentTypes') { - this._hasReferencedResolversUnionParentTypes = true; - } - const resolversType = this.convertName(referencedUnionType); - prev[typeName] = applyWrapper(`${resolversType}['${typeName}']`); + this._hasReferencedResolversUnionTypes = true; + const type = this.convertName('ResolversUnionTypes'); + const generic = this.convertName(currentType); + prev[typeName] = applyWrapper(`${type}<${generic}>['${typeName}']`); } else if (isEnumType(schemaType)) { prev[typeName] = this.convertName(typeName, { useTypesPrefix: this.config.enumPrefix }, true); } else { @@ -882,11 +864,7 @@ export class BaseResolversVisitor< return `Array<${t}>`; } - protected createResolversUnionTypes({ - getTypeToUse, - }: { - getTypeToUse: (name: string) => string; - }): Record { + protected createResolversUnionTypes(): Record { if (!this._hasReferencedResolversUnionTypes) { return {}; } @@ -894,66 +872,121 @@ export class BaseResolversVisitor< const allSchemaTypes = this._schema.getTypeMap(); const typeNames = this._federation.filterTypeNames(Object.keys(allSchemaTypes)); - const unionTypes = typeNames.reduce((res, typeName) => { + const unionTypes = typeNames.reduce>((res, typeName) => { const schemaType = allSchemaTypes[typeName]; if (isUnionType(schemaType)) { - const referencedTypes = schemaType - .getTypes() - .map(unionMemberType => { - const isUnionMemberMapped = this.config.mappers[unionMemberType.name]; - - // 1. If mapped without placehoder, just use it without doing extra checks - if (isUnionMemberMapped && !hasPlaceholder(isUnionMemberMapped.type)) { - return { typename: unionMemberType.name, unionMemberValue: isUnionMemberMapped.type }; - } + res[typeName] = this.getAbstractMembersType({ + typeName, + memberTypes: schemaType.getTypes(), + isTypenameNonOptional: this.config.resolversNonOptionalTypename.unionMember, + }); + } + return res; + }, {}); - // 2. Work out value for union member type - // 2a. By default, use the typescript type - let unionMemberValue = this.convertName(unionMemberType.name, {}, true); + return unionTypes; + } - // 2b. Find fields to Omit if needed. - // - If no field to Omit, "type with maybe Omit" is typescript type i.e. no Omit - // - If there are fields to Omit, keep track of these "type with maybe Omit" to replace in original unionMemberValue - const fieldsToOmit = this.getRelevantFieldsToOmit({ schemaType: unionMemberType, getTypeToUse }); - if (fieldsToOmit.length > 0) { - unionMemberValue = this.replaceFieldsInType(unionMemberValue, fieldsToOmit); - } + protected createResolversInterfaceTypes(): Record { + if (!this._hasReferencedResolversInterfaceTypes) { + return {}; + } - // 2c. If union member is mapped with placeholder, use the "type with maybe Omit" as {T} - if (isUnionMemberMapped && hasPlaceholder(isUnionMemberMapped.type)) { - return { - typename: unionMemberType.name, - unionMemberValue: replacePlaceholder(isUnionMemberMapped.type, unionMemberValue), - }; - } + const allSchemaTypes = this._schema.getTypeMap(); + const typeNames = this._federation.filterTypeNames(Object.keys(allSchemaTypes)); - // 2d. If has default mapper with placeholder, use the "type with maybe Omit" as {T} - const hasDefaultMapper = !!this.config.defaultMapper?.type; - const isScalar = this.config.scalars[typeName]; - if (hasDefaultMapper && hasPlaceholder(this.config.defaultMapper.type)) { - const finalTypename = isScalar ? this._getScalar(typeName) : unionMemberValue; - return { - typename: unionMemberType.name, - unionMemberValue: replacePlaceholder(this.config.defaultMapper.type, finalTypename), - }; - } + const interfaceTypes = typeNames.reduce>((res, typeName) => { + const schemaType = allSchemaTypes[typeName]; - return { typename: unionMemberType.name, unionMemberValue }; - }) - .map(({ typename, unionMemberValue }) => { - const nonOptionalTypenameModifier = this.config.resolversNonOptionalTypename.unionMember - ? ` & { __typename: '${typename}' }` - : ''; + if (isInterfaceType(schemaType)) { + const allTypesMap = this._schema.getTypeMap(); + const implementingTypes: GraphQLObjectType[] = []; - return `( ${unionMemberValue}${nonOptionalTypenameModifier} )`; // Must wrap every union member in explicit "( )" to separate the members - }); - res[typeName] = referencedTypes.join(' | '); + for (const graphqlType of Object.values(allTypesMap)) { + if (graphqlType instanceof GraphQLObjectType) { + const allInterfaces = graphqlType.getInterfaces(); + + if (allInterfaces.some(int => int.name === schemaType.name)) { + implementingTypes.push(graphqlType); + } + } + } + + res[typeName] = this.getAbstractMembersType({ + typeName, + memberTypes: implementingTypes, + isTypenameNonOptional: this.config.resolversNonOptionalTypename.interfaceImplementingType, + }); } + return res; }, {}); - return unionTypes; + return interfaceTypes; + } + + /** + * Function to generate the types of Abstract Type Members i.e. Union Members or Interface Implementing Types + */ + getAbstractMembersType({ + typeName, + memberTypes, + isTypenameNonOptional, + }: { + typeName: string; + memberTypes: readonly GraphQLObjectType[] | GraphQLObjectType[]; + isTypenameNonOptional: boolean; + }): string { + const result = + memberTypes + .map(type => { + const isTypeMapped = this.config.mappers[type.name]; + // 1. If mapped without placehoder, just use it without doing extra checks + if (isTypeMapped && !hasPlaceholder(isTypeMapped.type)) { + return { typename: type.name, typeValue: isTypeMapped.type }; + } + + // 2. Work out value for type + // 2a. By default, use the typescript type + let typeValue = this.convertName(type.name, {}, true); + + // 2b. Find fields to Omit if needed. + // - If no field to Omit, "type with maybe Omit" is typescript type i.e. no Omit + // - If there are fields to Omit, keep track of these "type with maybe Omit" to replace in original unionMemberValue + const fieldsToOmit = this.getRelevantFieldsToOmit({ + schemaType: type, + getTypeToUse: baseType => `RefType['${baseType}']`, + }); + if (fieldsToOmit.length > 0) { + typeValue = this.replaceFieldsInType(typeValue, fieldsToOmit); + } + + // 2c. If type is mapped with placeholder, use the "type with maybe Omit" as {T} + if (isTypeMapped && hasPlaceholder(isTypeMapped.type)) { + return { typename: type.name, typeValue: replacePlaceholder(isTypeMapped.type, typeValue) }; + } + + // 2d. If has default mapper with placeholder, use the "type with maybe Omit" as {T} + const hasDefaultMapper = !!this.config.defaultMapper?.type; + const isScalar = this.config.scalars[typeName]; + if (hasDefaultMapper && hasPlaceholder(this.config.defaultMapper.type)) { + const finalTypename = isScalar ? this._getScalar(typeName) : typeValue; + return { + typename: type.name, + typeValue: replacePlaceholder(this.config.defaultMapper.type, finalTypename), + }; + } + + return { typename: type.name, typeValue }; + }) + .map(({ typename, typeValue }) => { + const nonOptionalTypenameModifier = isTypenameNonOptional ? ` & { __typename: '${typename}' }` : ''; + + return `( ${typeValue}${nonOptionalTypenameModifier} )`; // Must wrap every type in explicit "( )" to separate them + }) + .join(' | ') || 'never'; + return result; } protected createFieldContextTypeMap(): FieldContextTypeMap { @@ -1020,7 +1053,7 @@ export class BaseResolversVisitor< return new DeclarationBlock(this._declarationBlockConfig) .export() .asKind(declarationKind) - .withName(this.convertName('ResolversUnionTypes')) + .withName(this.convertName('ResolversUnionTypes'), `>`) .withComment('Mapping of union types') .withBlock( Object.entries(this._resolversUnionTypes) @@ -1029,8 +1062,8 @@ export class BaseResolversVisitor< ).string; } - public buildResolversUnionParentTypes(): string { - if (Object.keys(this._resolversUnionParentTypes).length === 0) { + public buildResolversInterfaceTypes(): string { + if (Object.keys(this._resolversInterfaceTypes).length === 0) { return ''; } @@ -1038,10 +1071,10 @@ export class BaseResolversVisitor< return new DeclarationBlock(this._declarationBlockConfig) .export() .asKind(declarationKind) - .withName(this.convertName('ResolversUnionParentTypes')) - .withComment('Mapping of union parent types') + .withName(this.convertName('ResolversInterfaceTypes'), `>`) + .withComment('Mapping of interface types') .withBlock( - Object.entries(this._resolversUnionParentTypes) + Object.entries(this._resolversInterfaceTypes) .map(([typeName, value]) => indent(`${typeName}: ${value}${this.getPunctuation(declarationKind)}`)) .join('\n') ).string; @@ -1658,6 +1691,7 @@ function normalizeResolversNonOptionalTypename( if (typeof input === 'boolean') { return { unionMember: input, + interfaceImplementingType: input, }; } diff --git a/packages/plugins/other/visitor-plugin-common/src/types.ts b/packages/plugins/other/visitor-plugin-common/src/types.ts index 94ee783a09a..41d9eac78f7 100644 --- a/packages/plugins/other/visitor-plugin-common/src/types.ts +++ b/packages/plugins/other/visitor-plugin-common/src/types.ts @@ -105,4 +105,5 @@ export interface ParsedImport { export interface ResolversNonOptionalTypenameConfig { unionMember?: boolean; + interfaceImplementingType?: boolean; } diff --git a/packages/plugins/typescript/resolvers/src/index.ts b/packages/plugins/typescript/resolvers/src/index.ts index d7f1129c7b5..758d97c8133 100644 --- a/packages/plugins/typescript/resolvers/src/index.ts +++ b/packages/plugins/typescript/resolvers/src/index.ts @@ -246,7 +246,7 @@ export type DirectiveResolverFn typeof d === 'string'), diff --git a/packages/plugins/typescript/resolvers/tests/__snapshots__/ts-resolvers.spec.ts.snap b/packages/plugins/typescript/resolvers/tests/__snapshots__/ts-resolvers.spec.ts.snap index 930a4ff5e42..f437df770ac 100644 --- a/packages/plugins/typescript/resolvers/tests/__snapshots__/ts-resolvers.spec.ts.snap +++ b/packages/plugins/typescript/resolvers/tests/__snapshots__/ts-resolvers.spec.ts.snap @@ -165,15 +165,17 @@ export type DirectiveResolverFn TResult | Promise; /** Mapping of union types */ -export type ResolversUnionTypes = ResolversObject<{ +export type ResolversUnionTypes> = ResolversObject<{ ChildUnion: ( Child ) | ( MyOtherType ); - MyUnion: ( Omit & { unionChild?: Maybe } ) | ( MyOtherType ); + MyUnion: ( Omit & { unionChild?: Maybe } ) | ( MyOtherType ); }>; -/** Mapping of union parent types */ -export type ResolversUnionParentTypes = ResolversObject<{ - ChildUnion: ( Child ) | ( MyOtherType ); - MyUnion: ( Omit & { unionChild?: Maybe } ) | ( MyOtherType ); +/** Mapping of interface types */ +export type ResolversInterfaceTypes> = ResolversObject<{ + Node: ( SomeNode ); + AnotherNode: ( Omit & { unionChild?: Maybe } ) | ( Omit & { unionChild?: Maybe, unionChildren: Array } ); + WithChild: ( Omit & { unionChild?: Maybe } ) | ( Omit & { unionChild?: Maybe, unionChildren: Array } ); + WithChildren: ( Omit & { unionChild?: Maybe, unionChildren: Array } ); }>; /** Mapping between all available schema types and the resolvers types */ @@ -182,18 +184,18 @@ export type ResolversTypes = ResolversObject<{ String: ResolverTypeWrapper; Child: ResolverTypeWrapper; MyOtherType: ResolverTypeWrapper; - ChildUnion: ResolverTypeWrapper; + ChildUnion: ResolverTypeWrapper['ChildUnion']>; Query: ResolverTypeWrapper<{}>; Subscription: ResolverTypeWrapper<{}>; - Node: ResolversTypes['SomeNode']; + Node: ResolverTypeWrapper['Node']>; ID: ResolverTypeWrapper; SomeNode: ResolverTypeWrapper; - AnotherNode: ResolversTypes['AnotherNodeWithChild'] | ResolversTypes['AnotherNodeWithAll']; - WithChild: ResolversTypes['AnotherNodeWithChild'] | ResolversTypes['AnotherNodeWithAll']; - WithChildren: ResolversTypes['AnotherNodeWithAll']; + AnotherNode: ResolverTypeWrapper['AnotherNode']>; + WithChild: ResolverTypeWrapper['WithChild']>; + WithChildren: ResolverTypeWrapper['WithChildren']>; AnotherNodeWithChild: ResolverTypeWrapper & { unionChild?: Maybe }>; AnotherNodeWithAll: ResolverTypeWrapper & { unionChild?: Maybe, unionChildren: Array }>; - MyUnion: ResolverTypeWrapper; + MyUnion: ResolverTypeWrapper['MyUnion']>; MyScalar: ResolverTypeWrapper; Int: ResolverTypeWrapper; Boolean: ResolverTypeWrapper; @@ -205,18 +207,18 @@ export type ResolversParentTypes = ResolversObject<{ String: Scalars['String']; Child: Child; MyOtherType: MyOtherType; - ChildUnion: ResolversUnionParentTypes['ChildUnion']; + ChildUnion: ResolversUnionTypes['ChildUnion']; Query: {}; Subscription: {}; - Node: ResolversParentTypes['SomeNode']; + Node: ResolversInterfaceTypes['Node']; ID: Scalars['ID']; SomeNode: SomeNode; - AnotherNode: ResolversParentTypes['AnotherNodeWithChild'] | ResolversParentTypes['AnotherNodeWithAll']; - WithChild: ResolversParentTypes['AnotherNodeWithChild'] | ResolversParentTypes['AnotherNodeWithAll']; - WithChildren: ResolversParentTypes['AnotherNodeWithAll']; + AnotherNode: ResolversInterfaceTypes['AnotherNode']; + WithChild: ResolversInterfaceTypes['WithChild']; + WithChildren: ResolversInterfaceTypes['WithChildren']; AnotherNodeWithChild: Omit & { unionChild?: Maybe }; AnotherNodeWithAll: Omit & { unionChild?: Maybe, unionChildren: Array }; - MyUnion: ResolversUnionParentTypes['MyUnion']; + MyUnion: ResolversUnionTypes['MyUnion']; MyScalar: Scalars['MyScalar']; Int: Scalars['Int']; Boolean: Scalars['Boolean']; @@ -422,15 +424,17 @@ export type DirectiveResolverFn TResult | Promise; /** Mapping of union types */ -export type ResolversUnionTypes = ResolversObject<{ +export type ResolversUnionTypes> = ResolversObject<{ ChildUnion: ( Types.Child ) | ( Types.MyOtherType ); - MyUnion: ( Omit & { unionChild?: Types.Maybe } ) | ( Types.MyOtherType ); + MyUnion: ( Omit & { unionChild?: Types.Maybe } ) | ( Types.MyOtherType ); }>; -/** Mapping of union parent types */ -export type ResolversUnionParentTypes = ResolversObject<{ - ChildUnion: ( Types.Child ) | ( Types.MyOtherType ); - MyUnion: ( Omit & { unionChild?: Types.Maybe } ) | ( Types.MyOtherType ); +/** Mapping of interface types */ +export type ResolversInterfaceTypes> = ResolversObject<{ + Node: ( Types.SomeNode ); + AnotherNode: ( Omit & { unionChild?: Types.Maybe } ) | ( Omit & { unionChild?: Types.Maybe, unionChildren: Array } ); + WithChild: ( Omit & { unionChild?: Types.Maybe } ) | ( Omit & { unionChild?: Types.Maybe, unionChildren: Array } ); + WithChildren: ( Omit & { unionChild?: Types.Maybe, unionChildren: Array } ); }>; /** Mapping between all available schema types and the resolvers types */ @@ -439,18 +443,18 @@ export type ResolversTypes = ResolversObject<{ String: ResolverTypeWrapper; Child: ResolverTypeWrapper; MyOtherType: ResolverTypeWrapper; - ChildUnion: ResolverTypeWrapper; + ChildUnion: ResolverTypeWrapper['ChildUnion']>; Query: ResolverTypeWrapper<{}>; Subscription: ResolverTypeWrapper<{}>; - Node: ResolversTypes['SomeNode']; + Node: ResolverTypeWrapper['Node']>; ID: ResolverTypeWrapper; SomeNode: ResolverTypeWrapper; - AnotherNode: ResolversTypes['AnotherNodeWithChild'] | ResolversTypes['AnotherNodeWithAll']; - WithChild: ResolversTypes['AnotherNodeWithChild'] | ResolversTypes['AnotherNodeWithAll']; - WithChildren: ResolversTypes['AnotherNodeWithAll']; + AnotherNode: ResolverTypeWrapper['AnotherNode']>; + WithChild: ResolverTypeWrapper['WithChild']>; + WithChildren: ResolverTypeWrapper['WithChildren']>; AnotherNodeWithChild: ResolverTypeWrapper & { unionChild?: Types.Maybe }>; AnotherNodeWithAll: ResolverTypeWrapper & { unionChild?: Types.Maybe, unionChildren: Array }>; - MyUnion: ResolverTypeWrapper; + MyUnion: ResolverTypeWrapper['MyUnion']>; MyScalar: ResolverTypeWrapper; Int: ResolverTypeWrapper; Boolean: ResolverTypeWrapper; @@ -462,18 +466,18 @@ export type ResolversParentTypes = ResolversObject<{ String: Types.Scalars['String']; Child: Types.Child; MyOtherType: Types.MyOtherType; - ChildUnion: ResolversUnionParentTypes['ChildUnion']; + ChildUnion: ResolversUnionTypes['ChildUnion']; Query: {}; Subscription: {}; - Node: ResolversParentTypes['SomeNode']; + Node: ResolversInterfaceTypes['Node']; ID: Types.Scalars['ID']; SomeNode: Types.SomeNode; - AnotherNode: ResolversParentTypes['AnotherNodeWithChild'] | ResolversParentTypes['AnotherNodeWithAll']; - WithChild: ResolversParentTypes['AnotherNodeWithChild'] | ResolversParentTypes['AnotherNodeWithAll']; - WithChildren: ResolversParentTypes['AnotherNodeWithAll']; + AnotherNode: ResolversInterfaceTypes['AnotherNode']; + WithChild: ResolversInterfaceTypes['WithChild']; + WithChildren: ResolversInterfaceTypes['WithChildren']; AnotherNodeWithChild: Omit & { unionChild?: Types.Maybe }; AnotherNodeWithAll: Omit & { unionChild?: Types.Maybe, unionChildren: Array }; - MyUnion: ResolversUnionParentTypes['MyUnion']; + MyUnion: ResolversUnionTypes['MyUnion']; MyScalar: Types.Scalars['MyScalar']; Int: Types.Scalars['Int']; Boolean: Types.Scalars['Boolean']; @@ -763,15 +767,17 @@ export type DirectiveResolverFn TResult | Promise; /** Mapping of union types */ -export type ResolversUnionTypes = ResolversObject<{ +export type ResolversUnionTypes> = ResolversObject<{ ChildUnion: ( Child ) | ( MyOtherType ); - MyUnion: ( Omit & { unionChild?: Maybe } ) | ( MyOtherType ); + MyUnion: ( Omit & { unionChild?: Maybe } ) | ( MyOtherType ); }>; -/** Mapping of union parent types */ -export type ResolversUnionParentTypes = ResolversObject<{ - ChildUnion: ( Child ) | ( MyOtherType ); - MyUnion: ( Omit & { unionChild?: Maybe } ) | ( MyOtherType ); +/** Mapping of interface types */ +export type ResolversInterfaceTypes> = ResolversObject<{ + Node: ( SomeNode ); + AnotherNode: ( Omit & { unionChild?: Maybe } ) | ( Omit & { unionChild?: Maybe, unionChildren: Array } ); + WithChild: ( Omit & { unionChild?: Maybe } ) | ( Omit & { unionChild?: Maybe, unionChildren: Array } ); + WithChildren: ( Omit & { unionChild?: Maybe, unionChildren: Array } ); }>; /** Mapping between all available schema types and the resolvers types */ @@ -780,18 +786,18 @@ export type ResolversTypes = ResolversObject<{ String: ResolverTypeWrapper; Child: ResolverTypeWrapper; MyOtherType: ResolverTypeWrapper; - ChildUnion: ResolverTypeWrapper; + ChildUnion: ResolverTypeWrapper['ChildUnion']>; Query: ResolverTypeWrapper<{}>; Subscription: ResolverTypeWrapper<{}>; - Node: ResolversTypes['SomeNode']; + Node: ResolverTypeWrapper['Node']>; ID: ResolverTypeWrapper; SomeNode: ResolverTypeWrapper; - AnotherNode: ResolversTypes['AnotherNodeWithChild'] | ResolversTypes['AnotherNodeWithAll']; - WithChild: ResolversTypes['AnotherNodeWithChild'] | ResolversTypes['AnotherNodeWithAll']; - WithChildren: ResolversTypes['AnotherNodeWithAll']; + AnotherNode: ResolverTypeWrapper['AnotherNode']>; + WithChild: ResolverTypeWrapper['WithChild']>; + WithChildren: ResolverTypeWrapper['WithChildren']>; AnotherNodeWithChild: ResolverTypeWrapper & { unionChild?: Maybe }>; AnotherNodeWithAll: ResolverTypeWrapper & { unionChild?: Maybe, unionChildren: Array }>; - MyUnion: ResolverTypeWrapper; + MyUnion: ResolverTypeWrapper['MyUnion']>; MyScalar: ResolverTypeWrapper; Int: ResolverTypeWrapper; Boolean: ResolverTypeWrapper; @@ -803,18 +809,18 @@ export type ResolversParentTypes = ResolversObject<{ String: Scalars['String']; Child: Child; MyOtherType: MyOtherType; - ChildUnion: ResolversUnionParentTypes['ChildUnion']; + ChildUnion: ResolversUnionTypes['ChildUnion']; Query: {}; Subscription: {}; - Node: ResolversParentTypes['SomeNode']; + Node: ResolversInterfaceTypes['Node']; ID: Scalars['ID']; SomeNode: SomeNode; - AnotherNode: ResolversParentTypes['AnotherNodeWithChild'] | ResolversParentTypes['AnotherNodeWithAll']; - WithChild: ResolversParentTypes['AnotherNodeWithChild'] | ResolversParentTypes['AnotherNodeWithAll']; - WithChildren: ResolversParentTypes['AnotherNodeWithAll']; + AnotherNode: ResolversInterfaceTypes['AnotherNode']; + WithChild: ResolversInterfaceTypes['WithChild']; + WithChildren: ResolversInterfaceTypes['WithChildren']; AnotherNodeWithChild: Omit & { unionChild?: Maybe }; AnotherNodeWithAll: Omit & { unionChild?: Maybe, unionChildren: Array }; - MyUnion: ResolversUnionParentTypes['MyUnion']; + MyUnion: ResolversUnionTypes['MyUnion']; MyScalar: Scalars['MyScalar']; Int: Scalars['Int']; Boolean: Scalars['Boolean']; diff --git a/packages/plugins/typescript/resolvers/tests/mapping.spec.ts b/packages/plugins/typescript/resolvers/tests/mapping.spec.ts index 652307eb697..61dfb0b8436 100644 --- a/packages/plugins/typescript/resolvers/tests/mapping.spec.ts +++ b/packages/plugins/typescript/resolvers/tests/mapping.spec.ts @@ -8,15 +8,17 @@ describe('ResolversTypes', () => { const result = await plugin(resolversTestingSchema, [], {}, { outputFile: '' }); expect(result.content).toBeSimilarStringTo(` - export type ResolversUnionTypes = { + export type ResolversUnionTypes> = { ChildUnion: ( Child ) | ( MyOtherType ); - MyUnion: ( Omit & { unionChild?: Maybe } ) | ( MyOtherType ); + MyUnion: ( Omit & { unionChild?: Maybe } ) | ( MyOtherType ); }; `); expect(result.content).toBeSimilarStringTo(` - export type ResolversUnionParentTypes = { - ChildUnion: ( Child ) | ( MyOtherType ); - MyUnion: ( Omit & { unionChild?: Maybe } ) | ( MyOtherType ); + export type ResolversInterfaceTypes> = { + Node: ( SomeNode ); + AnotherNode: ( Omit & { unionChild?: Maybe } ) | ( Omit & { unionChild?: Maybe, unionChildren: Array } ); + WithChild: ( Omit & { unionChild?: Maybe } ) | ( Omit & { unionChild?: Maybe, unionChildren: Array } ); + WithChildren: ( Omit & { unionChild?: Maybe, unionChildren: Array } ); }; `); expect(result.content).toBeSimilarStringTo(` @@ -25,18 +27,18 @@ describe('ResolversTypes', () => { String: ResolverTypeWrapper; Child: ResolverTypeWrapper; MyOtherType: ResolverTypeWrapper; - ChildUnion: ResolverTypeWrapper; + ChildUnion: ResolverTypeWrapper['ChildUnion']>; Query: ResolverTypeWrapper<{}>; Subscription: ResolverTypeWrapper<{}>; - Node: ResolversTypes['SomeNode']; + Node: ResolverTypeWrapper['Node']>; ID: ResolverTypeWrapper; SomeNode: ResolverTypeWrapper; - AnotherNode: ResolversTypes['AnotherNodeWithChild'] | ResolversTypes['AnotherNodeWithAll']; - WithChild: ResolversTypes['AnotherNodeWithChild'] | ResolversTypes['AnotherNodeWithAll']; - WithChildren: ResolversTypes['AnotherNodeWithAll']; + AnotherNode: ResolverTypeWrapper['AnotherNode']>; + WithChild: ResolverTypeWrapper['WithChild']>; + WithChildren: ResolverTypeWrapper['WithChildren']>; AnotherNodeWithChild: ResolverTypeWrapper & { unionChild?: Maybe }>; AnotherNodeWithAll: ResolverTypeWrapper & { unionChild?: Maybe, unionChildren: Array }>; - MyUnion: ResolverTypeWrapper; + MyUnion: ResolverTypeWrapper['MyUnion']>; MyScalar: ResolverTypeWrapper; Int: ResolverTypeWrapper; Boolean: ResolverTypeWrapper; @@ -48,18 +50,18 @@ describe('ResolversTypes', () => { String: Scalars['String']; Child: Child; MyOtherType: MyOtherType; - ChildUnion: ResolversUnionParentTypes['ChildUnion']; + ChildUnion: ResolversUnionTypes['ChildUnion']; Query: {}; Subscription: {}; - Node: ResolversParentTypes['SomeNode']; + Node: ResolversInterfaceTypes['Node']; ID: Scalars['ID']; SomeNode: SomeNode; - AnotherNode: ResolversParentTypes['AnotherNodeWithChild'] | ResolversParentTypes['AnotherNodeWithAll']; - WithChild: ResolversParentTypes['AnotherNodeWithChild'] | ResolversParentTypes['AnotherNodeWithAll']; - WithChildren: ResolversParentTypes['AnotherNodeWithAll']; + AnotherNode: ResolversInterfaceTypes['AnotherNode']; + WithChild: ResolversInterfaceTypes['WithChild']; + WithChildren: ResolversInterfaceTypes['WithChildren']; AnotherNodeWithChild: Omit & { unionChild?: Maybe }; AnotherNodeWithAll: Omit & { unionChild?: Maybe, unionChildren: Array }; - MyUnion: ResolversUnionParentTypes['MyUnion']; + MyUnion: ResolversUnionTypes['MyUnion']; MyScalar: Scalars['MyScalar']; Int: Scalars['Int']; Boolean: Scalars['Boolean']; @@ -74,6 +76,7 @@ describe('ResolversTypes', () => { { mappers: { MyType: 'MyTypeDb', + AnotherNodeWithChild: 'AnotherNodeWithChildMapper', String: 'number', }, }, @@ -81,15 +84,17 @@ describe('ResolversTypes', () => { )) as Types.ComplexPluginOutput; expect(result.content).toBeSimilarStringTo(` - export type ResolversUnionTypes = { - ChildUnion: ( Omit & { bar: ResolversTypes['String'], parent?: Maybe } ) | ( Omit & { bar: ResolversTypes['String'] } ); - MyUnion: ( MyTypeDb ) | ( Omit & { bar: ResolversTypes['String'] } ); + export type ResolversUnionTypes> = { + ChildUnion: ( Omit & { bar: RefType['String'], parent?: Maybe } ) | ( Omit & { bar: RefType['String'] } ); + MyUnion: ( MyTypeDb ) | ( Omit & { bar: RefType['String'] } ); }; `); expect(result.content).toBeSimilarStringTo(` - export type ResolversUnionParentTypes = { - ChildUnion: ( Omit & { bar: ResolversParentTypes['String'], parent?: Maybe } ) | ( Omit & { bar: ResolversParentTypes['String'] } ); - MyUnion: ( MyTypeDb ) | ( Omit & { bar: ResolversParentTypes['String'] } ); + export type ResolversInterfaceTypes> = { + Node: ( SomeNode ); + AnotherNode: ( AnotherNodeWithChildMapper ) | ( Omit & { unionChild?: Maybe, unionChildren: Array } ); + WithChild: ( AnotherNodeWithChildMapper ) | ( Omit & { unionChild?: Maybe, unionChildren: Array } ); + WithChildren: ( Omit & { unionChild?: Maybe, unionChildren: Array } ); }; `); expect(result.content).toBeSimilarStringTo(` @@ -98,18 +103,18 @@ describe('ResolversTypes', () => { String: ResolverTypeWrapper; Child: ResolverTypeWrapper & { bar: ResolversTypes['String'], parent?: Maybe }>; MyOtherType: ResolverTypeWrapper & { bar: ResolversTypes['String'] }>; - ChildUnion: ResolverTypeWrapper; + ChildUnion: ResolverTypeWrapper['ChildUnion']>; Query: ResolverTypeWrapper<{}>; Subscription: ResolverTypeWrapper<{}>; - Node: ResolversTypes['SomeNode']; + Node: ResolverTypeWrapper['Node']>; ID: ResolverTypeWrapper; SomeNode: ResolverTypeWrapper; - AnotherNode: ResolversTypes['AnotherNodeWithChild'] | ResolversTypes['AnotherNodeWithAll']; - WithChild: ResolversTypes['AnotherNodeWithChild'] | ResolversTypes['AnotherNodeWithAll']; - WithChildren: ResolversTypes['AnotherNodeWithAll']; - AnotherNodeWithChild: ResolverTypeWrapper & { unionChild?: Maybe }>; + AnotherNode: ResolverTypeWrapper['AnotherNode']>; + WithChild: ResolverTypeWrapper['WithChild']>; + WithChildren: ResolverTypeWrapper['WithChildren']>; + AnotherNodeWithChild: ResolverTypeWrapper; AnotherNodeWithAll: ResolverTypeWrapper & { unionChild?: Maybe, unionChildren: Array }>; - MyUnion: ResolverTypeWrapper; + MyUnion: ResolverTypeWrapper['MyUnion']>; MyScalar: ResolverTypeWrapper; Int: ResolverTypeWrapper; Boolean: ResolverTypeWrapper; @@ -121,18 +126,18 @@ describe('ResolversTypes', () => { String: number; Child: Omit & { bar: ResolversParentTypes['String'], parent?: Maybe }; MyOtherType: Omit & { bar: ResolversParentTypes['String'] }; - ChildUnion: ResolversUnionParentTypes['ChildUnion']; + ChildUnion: ResolversUnionTypes['ChildUnion']; Query: {}; Subscription: {}; - Node: ResolversParentTypes['SomeNode']; + Node: ResolversInterfaceTypes['Node']; ID: Scalars['ID']; SomeNode: SomeNode; - AnotherNode: ResolversParentTypes['AnotherNodeWithChild'] | ResolversParentTypes['AnotherNodeWithAll']; - WithChild: ResolversParentTypes['AnotherNodeWithChild'] | ResolversParentTypes['AnotherNodeWithAll']; - WithChildren: ResolversParentTypes['AnotherNodeWithAll']; - AnotherNodeWithChild: Omit & { unionChild?: Maybe }; + AnotherNode: ResolversInterfaceTypes['AnotherNode']; + WithChild: ResolversInterfaceTypes['WithChild']; + WithChildren: ResolversInterfaceTypes['WithChildren']; + AnotherNodeWithChild: AnotherNodeWithChildMapper; AnotherNodeWithAll: Omit & { unionChild?: Maybe, unionChildren: Array }; - MyUnion: ResolversUnionParentTypes['MyUnion']; + MyUnion: ResolversUnionTypes['MyUnion']; MyScalar: Scalars['MyScalar']; Int: Scalars['Int']; Boolean: Scalars['Boolean']; @@ -173,12 +178,7 @@ describe('ResolversTypes', () => { const content = mergeOutputs([result]); expect(result.content).toBeSimilarStringTo(` - export type ResolversUnionTypes = { - MovieLike: ( MovieEntity ) | ( Book ); - }; - `); - expect(result.content).toBeSimilarStringTo(` - export type ResolversUnionParentTypes = { + export type ResolversUnionTypes> = { MovieLike: ( MovieEntity ) | ( Book ); }; `); @@ -188,7 +188,7 @@ describe('ResolversTypes', () => { ID: ResolverTypeWrapper; String: ResolverTypeWrapper; Book: ResolverTypeWrapper; - MovieLike: ResolverTypeWrapper; + MovieLike: ResolverTypeWrapper['MovieLike']>; NonInterfaceHasNarrative: ResolverTypeWrapper & { narrative: ResolversTypes['MovieLike'], movie: ResolversTypes['Movie'] }>; Boolean: ResolverTypeWrapper; }; @@ -199,7 +199,7 @@ describe('ResolversTypes', () => { ID: Scalars['ID']; String: Scalars['String']; Book: Book; - MovieLike: ResolversUnionParentTypes['MovieLike']; + MovieLike: ResolversUnionTypes['MovieLike']; NonInterfaceHasNarrative: Omit & { narrative: ResolversParentTypes['MovieLike'], movie: ResolversParentTypes['Movie'] }; Boolean: Scalars['Boolean']; }; @@ -248,12 +248,7 @@ describe('ResolversTypes', () => { const content = mergeOutputs([result]); expect(content).toBeSimilarStringTo(` - export type ResolversUnionTypes = { - MovieLike: ( MovieEntity ) | ( Book ); - }; - `); - expect(content).toBeSimilarStringTo(` - export type ResolversUnionParentTypes = { + export type ResolversUnionTypes> = { MovieLike: ( MovieEntity ) | ( Book ); }; `); @@ -262,7 +257,7 @@ describe('ResolversTypes', () => { ID: ResolverTypeWrapper; String: ResolverTypeWrapper; Book: ResolverTypeWrapper; - MovieLike: ResolverTypeWrapper; + MovieLike: ResolverTypeWrapper['MovieLike']>; NonInterfaceHasNarrative: ResolverTypeWrapper & { narrative: ResolversTypes['MovieLike'], movie: ResolversTypes['Movie'] }>; LayerOfIndirection: ResolverTypeWrapper & { movies: Array }>; AnotherLayerOfIndirection: ResolverTypeWrapper & { inner: ResolversTypes['LayerOfIndirection'] }>; @@ -274,7 +269,7 @@ describe('ResolversTypes', () => { ID: Scalars['ID']; String: Scalars['String']; Book: Book; - MovieLike: ResolversUnionParentTypes['MovieLike']; + MovieLike: ResolversUnionTypes['MovieLike']; NonInterfaceHasNarrative: Omit & { narrative: ResolversParentTypes['MovieLike'], movie: ResolversParentTypes['Movie'] }; LayerOfIndirection: Omit & { movies: Array }; AnotherLayerOfIndirection: Omit & { inner: ResolversParentTypes['LayerOfIndirection'] }; @@ -396,15 +391,17 @@ describe('ResolversTypes', () => { )) as Types.ComplexPluginOutput; expect(result.content).toBeSimilarStringTo(` - export type ResolversUnionTypes = { + export type ResolversUnionTypes> = { ChildUnion: ( Partial ) | ( Partial ); - MyUnion: ( Partial & { unionChild?: Maybe }> ) | ( Partial ); + MyUnion: ( Partial & { unionChild?: Maybe }> ) | ( Partial ); }; `); expect(result.content).toBeSimilarStringTo(` - export type ResolversUnionParentTypes = { - ChildUnion: ( Partial ) | ( Partial ); - MyUnion: ( Partial & { unionChild?: Maybe }> ) | ( Partial ); + export type ResolversInterfaceTypes> = { + Node: ( Partial ); + AnotherNode: ( Partial & { unionChild?: Maybe }> ) | ( Partial & { unionChild?: Maybe, unionChildren: Array }> ); + WithChild: ( Partial & { unionChild?: Maybe }> ) | ( Partial & { unionChild?: Maybe, unionChildren: Array }> ); + WithChildren: ( Partial & { unionChild?: Maybe, unionChildren: Array }> ); }; `); expect(result.content).toBeSimilarStringTo(` @@ -413,18 +410,18 @@ describe('ResolversTypes', () => { String: ResolverTypeWrapper>; Child: ResolverTypeWrapper>; MyOtherType: ResolverTypeWrapper>; - ChildUnion: Partial>; + ChildUnion: Partial['ChildUnion']>>; Query: ResolverTypeWrapper<{}>; Subscription: ResolverTypeWrapper<{}>; - Node: ResolversTypes['SomeNode']; + Node: ResolverTypeWrapper['Node']>; ID: ResolverTypeWrapper>; SomeNode: ResolverTypeWrapper>; - AnotherNode: ResolversTypes['AnotherNodeWithChild'] | ResolversTypes['AnotherNodeWithAll']; - WithChild: ResolversTypes['AnotherNodeWithChild'] | ResolversTypes['AnotherNodeWithAll']; - WithChildren: ResolversTypes['AnotherNodeWithAll']; + AnotherNode: ResolverTypeWrapper['AnotherNode']>; + WithChild: ResolverTypeWrapper['WithChild']>; + WithChildren: ResolverTypeWrapper['WithChildren']>; AnotherNodeWithChild: ResolverTypeWrapper & { unionChild?: Maybe }>>; AnotherNodeWithAll: ResolverTypeWrapper & { unionChild?: Maybe, unionChildren: Array }>>; - MyUnion: Partial>; + MyUnion: Partial['MyUnion']>>; MyScalar: ResolverTypeWrapper>; Int: ResolverTypeWrapper>; Boolean: ResolverTypeWrapper>; @@ -435,18 +432,18 @@ describe('ResolversTypes', () => { String: Partial; Child: Partial; MyOtherType: Partial; - ChildUnion: Partial; + ChildUnion: Partial['ChildUnion']>; Query: {}; Subscription: {}; - Node: ResolversParentTypes['SomeNode']; + Node: ResolversInterfaceTypes['Node']; ID: Partial; SomeNode: Partial; - AnotherNode: ResolversParentTypes['AnotherNodeWithChild'] | ResolversParentTypes['AnotherNodeWithAll']; - WithChild: ResolversParentTypes['AnotherNodeWithChild'] | ResolversParentTypes['AnotherNodeWithAll']; - WithChildren: ResolversParentTypes['AnotherNodeWithAll']; + AnotherNode: ResolversInterfaceTypes['AnotherNode']; + WithChild: ResolversInterfaceTypes['WithChild']; + WithChildren: ResolversInterfaceTypes['WithChildren']; AnotherNodeWithChild: Partial & { unionChild?: Maybe }>; AnotherNodeWithAll: Partial & { unionChild?: Maybe, unionChildren: Array }>; - MyUnion: Partial; + MyUnion: Partial['MyUnion']>; MyScalar: Partial; Int: Partial; Boolean: Partial; @@ -467,16 +464,18 @@ describe('ResolversTypes', () => { expect(result.prepend).toContain(`import { CustomPartial } from './my-wrapper';`); expect(result.content).toBeSimilarStringTo(` - export type ResolversUnionTypes = { + export type ResolversUnionTypes> = { ChildUnion: ( CustomPartial ) | ( CustomPartial ); - MyUnion: ( CustomPartial & { unionChild?: Maybe }> ) | ( CustomPartial ); + MyUnion: ( CustomPartial & { unionChild?: Maybe }> ) | ( CustomPartial ); } `); expect(result.content).toBeSimilarStringTo(` - export type ResolversUnionParentTypes = { - ChildUnion: ( CustomPartial ) | ( CustomPartial ); - MyUnion: ( CustomPartial & { unionChild?: Maybe }> ) | ( CustomPartial ); - } + export type ResolversInterfaceTypes> = { + Node: ( CustomPartial ); + AnotherNode: ( CustomPartial & { unionChild?: Maybe }> ) | ( CustomPartial & { unionChild?: Maybe, unionChildren: Array }> ); + WithChild: ( CustomPartial & { unionChild?: Maybe }> ) | ( CustomPartial & { unionChild?: Maybe, unionChildren: Array }> ); + WithChildren: ( CustomPartial & { unionChild?: Maybe, unionChildren: Array }> ); + }; `); expect(result.content).toBeSimilarStringTo(` export type ResolversTypes = { @@ -484,18 +483,18 @@ describe('ResolversTypes', () => { String: ResolverTypeWrapper>; Child: ResolverTypeWrapper>; MyOtherType: ResolverTypeWrapper>; - ChildUnion: CustomPartial>; + ChildUnion: CustomPartial['ChildUnion']>>; Query: ResolverTypeWrapper<{}>; Subscription: ResolverTypeWrapper<{}>; - Node: ResolversTypes['SomeNode']; + Node: ResolverTypeWrapper['Node']>; ID: ResolverTypeWrapper>; SomeNode: ResolverTypeWrapper>; - AnotherNode: ResolversTypes['AnotherNodeWithChild'] | ResolversTypes['AnotherNodeWithAll']; - WithChild: ResolversTypes['AnotherNodeWithChild'] | ResolversTypes['AnotherNodeWithAll']; - WithChildren: ResolversTypes['AnotherNodeWithAll']; + AnotherNode: ResolverTypeWrapper['AnotherNode']>; + WithChild: ResolverTypeWrapper['WithChild']>; + WithChildren: ResolverTypeWrapper['WithChildren']>; AnotherNodeWithChild: ResolverTypeWrapper & { unionChild?: Maybe }>>; AnotherNodeWithAll: ResolverTypeWrapper & { unionChild?: Maybe, unionChildren: Array }>>; - MyUnion: CustomPartial>; + MyUnion: CustomPartial['MyUnion']>>; MyScalar: ResolverTypeWrapper>; Int: ResolverTypeWrapper>; Boolean: ResolverTypeWrapper>; @@ -506,18 +505,18 @@ describe('ResolversTypes', () => { String: CustomPartial; Child: CustomPartial; MyOtherType: CustomPartial; - ChildUnion: CustomPartial; + ChildUnion: CustomPartial['ChildUnion']>; Query: {}; Subscription: {}; - Node: ResolversParentTypes['SomeNode']; + Node: ResolversInterfaceTypes['Node']; ID: CustomPartial; SomeNode: CustomPartial; - AnotherNode: ResolversParentTypes['AnotherNodeWithChild'] | ResolversParentTypes['AnotherNodeWithAll']; - WithChild: ResolversParentTypes['AnotherNodeWithChild'] | ResolversParentTypes['AnotherNodeWithAll']; - WithChildren: ResolversParentTypes['AnotherNodeWithAll']; + AnotherNode: ResolversInterfaceTypes['AnotherNode']; + WithChild: ResolversInterfaceTypes['WithChild']; + WithChildren: ResolversInterfaceTypes['WithChildren']; AnotherNodeWithChild: CustomPartial & { unionChild?: Maybe }>; AnotherNodeWithAll: CustomPartial & { unionChild?: Maybe, unionChildren: Array }>; - MyUnion: CustomPartial; + MyUnion: CustomPartial['MyUnion']>; MyScalar: CustomPartial; Int: CustomPartial; Boolean: CustomPartial; @@ -533,6 +532,7 @@ describe('ResolversTypes', () => { noSchemaStitching: true, mappers: { MyType: './my-wrapper#CustomPartial<{T}>', + AnotherNodeWithChild: './my-wrapper#CustomPartial<{T}>', }, }, { outputFile: '' } @@ -540,15 +540,17 @@ describe('ResolversTypes', () => { expect(result.prepend).toContain(`import { CustomPartial } from './my-wrapper';`); expect(result.content).toBeSimilarStringTo(` - export type ResolversUnionTypes = { - ChildUnion: ( Omit & { parent?: Maybe } ) | ( MyOtherType ); - MyUnion: ( CustomPartial & { unionChild?: Maybe }> ) | ( MyOtherType ); + export type ResolversUnionTypes> = { + ChildUnion: ( Omit & { parent?: Maybe } ) | ( MyOtherType ); + MyUnion: ( CustomPartial & { unionChild?: Maybe }> ) | ( MyOtherType ); }; `); expect(result.content).toBeSimilarStringTo(` - export type ResolversUnionParentTypes = { - ChildUnion: ( Omit & { parent?: Maybe } ) | ( MyOtherType ); - MyUnion: ( CustomPartial & { unionChild?: Maybe }> ) | ( MyOtherType ); + export type ResolversInterfaceTypes> = { + Node: ( SomeNode ); + AnotherNode: ( CustomPartial & { unionChild?: Maybe }> ) | ( Omit & { unionChild?: Maybe, unionChildren: Array } ); + WithChild: ( CustomPartial & { unionChild?: Maybe }> ) | ( Omit & { unionChild?: Maybe, unionChildren: Array } ); + WithChildren: ( Omit & { unionChild?: Maybe, unionChildren: Array } ); }; `); expect(result.content).toBeSimilarStringTo(` @@ -557,18 +559,18 @@ describe('ResolversTypes', () => { String: ResolverTypeWrapper; Child: ResolverTypeWrapper & { parent?: Maybe }>; MyOtherType: ResolverTypeWrapper; - ChildUnion: ResolverTypeWrapper; + ChildUnion: ResolverTypeWrapper['ChildUnion']>; Query: ResolverTypeWrapper<{}>; Subscription: ResolverTypeWrapper<{}>; - Node: ResolversTypes['SomeNode']; + Node: ResolverTypeWrapper['Node']>; ID: ResolverTypeWrapper; SomeNode: ResolverTypeWrapper; - AnotherNode: ResolversTypes['AnotherNodeWithChild'] | ResolversTypes['AnotherNodeWithAll']; - WithChild: ResolversTypes['AnotherNodeWithChild'] | ResolversTypes['AnotherNodeWithAll']; - WithChildren: ResolversTypes['AnotherNodeWithAll']; - AnotherNodeWithChild: ResolverTypeWrapper & { unionChild?: Maybe }>; + AnotherNode: ResolverTypeWrapper['AnotherNode']>; + WithChild: ResolverTypeWrapper['WithChild']>; + WithChildren: ResolverTypeWrapper['WithChildren']>; + AnotherNodeWithChild: ResolverTypeWrapper & { unionChild?: Maybe }>>; AnotherNodeWithAll: ResolverTypeWrapper & { unionChild?: Maybe, unionChildren: Array }>; - MyUnion: ResolverTypeWrapper; + MyUnion: ResolverTypeWrapper['MyUnion']>; MyScalar: ResolverTypeWrapper; Int: ResolverTypeWrapper; Boolean: ResolverTypeWrapper; @@ -579,18 +581,18 @@ describe('ResolversTypes', () => { String: Scalars['String']; Child: Omit & { parent?: Maybe }; MyOtherType: MyOtherType; - ChildUnion: ResolversUnionParentTypes['ChildUnion']; + ChildUnion: ResolversUnionTypes['ChildUnion']; Query: {}; Subscription: {}; - Node: ResolversParentTypes['SomeNode']; + Node: ResolversInterfaceTypes['Node']; ID: Scalars['ID']; SomeNode: SomeNode; - AnotherNode: ResolversParentTypes['AnotherNodeWithChild'] | ResolversParentTypes['AnotherNodeWithAll']; - WithChild: ResolversParentTypes['AnotherNodeWithChild'] | ResolversParentTypes['AnotherNodeWithAll']; - WithChildren: ResolversParentTypes['AnotherNodeWithAll']; - AnotherNodeWithChild: Omit & { unionChild?: Maybe }; + AnotherNode: ResolversInterfaceTypes['AnotherNode']; + WithChild: ResolversInterfaceTypes['WithChild']; + WithChildren: ResolversInterfaceTypes['WithChildren']; + AnotherNodeWithChild: CustomPartial & { unionChild?: Maybe }>; AnotherNodeWithAll: Omit & { unionChild?: Maybe, unionChildren: Array }; - MyUnion: ResolversUnionParentTypes['MyUnion']; + MyUnion: ResolversUnionTypes['MyUnion']; MyScalar: Scalars['MyScalar']; Int: Scalars['Int']; Boolean: Scalars['Boolean']; @@ -679,22 +681,28 @@ describe('ResolversTypes', () => { noSchemaStitching: true, mappers: { MyType: './my-type#MyType as DatabaseMyType', + AnotherNodeWithChild: './my-interface#AnotherNodeWithChild as AnotherNodeWithChildMapper', }, }, { outputFile: '' } )) as Types.ComplexPluginOutput; expect(result.prepend).toContain(`import { MyType as DatabaseMyType } from './my-type';`); + expect(result.prepend).toContain( + `import { AnotherNodeWithChild as AnotherNodeWithChildMapper } from './my-interface';` + ); expect(result.content).toBeSimilarStringTo(` - export type ResolversUnionTypes = { - ChildUnion: ( Omit & { parent?: Maybe } ) | ( MyOtherType ); + export type ResolversUnionTypes> = { + ChildUnion: ( Omit & { parent?: Maybe } ) | ( MyOtherType ); MyUnion: ( DatabaseMyType ) | ( MyOtherType ); }; `); expect(result.content).toBeSimilarStringTo(` - export type ResolversUnionParentTypes = { - ChildUnion: ( Omit & { parent?: Maybe } ) | ( MyOtherType ); - MyUnion: ( DatabaseMyType ) | ( MyOtherType ); + export type ResolversInterfaceTypes> = { + Node: ( SomeNode ); + AnotherNode: ( AnotherNodeWithChildMapper ) | ( Omit & { unionChild?: Maybe, unionChildren: Array } ); + WithChild: ( AnotherNodeWithChildMapper ) | ( Omit & { unionChild?: Maybe, unionChildren: Array } ); + WithChildren: ( Omit & { unionChild?: Maybe, unionChildren: Array } ); }; `); expect(result.content).toBeSimilarStringTo(` @@ -703,18 +711,18 @@ describe('ResolversTypes', () => { String: ResolverTypeWrapper; Child: ResolverTypeWrapper & { parent?: Maybe }>; MyOtherType: ResolverTypeWrapper; - ChildUnion: ResolverTypeWrapper; + ChildUnion: ResolverTypeWrapper['ChildUnion']>; Query: ResolverTypeWrapper<{}>; Subscription: ResolverTypeWrapper<{}>; - Node: ResolversTypes['SomeNode']; + Node: ResolverTypeWrapper['Node']>; ID: ResolverTypeWrapper; SomeNode: ResolverTypeWrapper; - AnotherNode: ResolversTypes['AnotherNodeWithChild'] | ResolversTypes['AnotherNodeWithAll']; - WithChild: ResolversTypes['AnotherNodeWithChild'] | ResolversTypes['AnotherNodeWithAll']; - WithChildren: ResolversTypes['AnotherNodeWithAll']; - AnotherNodeWithChild: ResolverTypeWrapper & { unionChild?: Maybe }>; + AnotherNode: ResolverTypeWrapper['AnotherNode']>; + WithChild: ResolverTypeWrapper['WithChild']>; + WithChildren: ResolverTypeWrapper['WithChildren']>; + AnotherNodeWithChild: ResolverTypeWrapper; AnotherNodeWithAll: ResolverTypeWrapper & { unionChild?: Maybe, unionChildren: Array }>; - MyUnion: ResolverTypeWrapper; + MyUnion: ResolverTypeWrapper['MyUnion']>; MyScalar: ResolverTypeWrapper; Int: ResolverTypeWrapper; Boolean: ResolverTypeWrapper; @@ -725,18 +733,18 @@ describe('ResolversTypes', () => { String: Scalars['String']; Child: Omit & { parent?: Maybe }; MyOtherType: MyOtherType; - ChildUnion: ResolversUnionParentTypes['ChildUnion']; + ChildUnion: ResolversUnionTypes['ChildUnion']; Query: {}; Subscription: {}; - Node: ResolversParentTypes['SomeNode']; + Node: ResolversInterfaceTypes['Node']; ID: Scalars['ID']; SomeNode: SomeNode; - AnotherNode: ResolversParentTypes['AnotherNodeWithChild'] | ResolversParentTypes['AnotherNodeWithAll']; - WithChild: ResolversParentTypes['AnotherNodeWithChild'] | ResolversParentTypes['AnotherNodeWithAll']; - WithChildren: ResolversParentTypes['AnotherNodeWithAll']; - AnotherNodeWithChild: Omit & { unionChild?: Maybe }; + AnotherNode: ResolversInterfaceTypes['AnotherNode']; + WithChild: ResolversInterfaceTypes['WithChild']; + WithChildren: ResolversInterfaceTypes['WithChildren']; + AnotherNodeWithChild: AnotherNodeWithChildMapper; AnotherNodeWithAll: Omit & { unionChild?: Maybe, unionChildren: Array }; - MyUnion: ResolversUnionParentTypes['MyUnion']; + MyUnion: ResolversUnionTypes['MyUnion']; MyScalar: Scalars['MyScalar']; Int: Scalars['Int']; Boolean: Scalars['Boolean']; @@ -753,6 +761,8 @@ describe('ResolversTypes', () => { mappers: { MyOtherType: './my-type#default as DatabaseMyOtherType', MyType: './my-type#MyType as DatabaseMyType', + AnotherNodeWithChild: './my-interface#default as AnotherNodeWithChildMapper', + AnotherNodeWithAll: './my-interface#AnotherNodeWithAll as AnotherNodeWithAllMapper', }, }, { outputFile: '' } @@ -760,15 +770,17 @@ describe('ResolversTypes', () => { expect(result.prepend).toContain(`import DatabaseMyOtherType, { MyType as DatabaseMyType } from './my-type';`); expect(result.content).toBeSimilarStringTo(` - export type ResolversUnionTypes = { - ChildUnion: ( Omit & { parent?: Maybe } ) | ( DatabaseMyOtherType ); + export type ResolversUnionTypes> = { + ChildUnion: ( Omit & { parent?: Maybe } ) | ( DatabaseMyOtherType ); MyUnion: ( DatabaseMyType ) | ( DatabaseMyOtherType ); }; `); expect(result.content).toBeSimilarStringTo(` - export type ResolversUnionParentTypes = { - ChildUnion: ( Omit & { parent?: Maybe } ) | ( DatabaseMyOtherType ); - MyUnion: ( DatabaseMyType ) | ( DatabaseMyOtherType ); + export type ResolversInterfaceTypes> = { + Node: ( SomeNode ); + AnotherNode: ( AnotherNodeWithChildMapper ) | ( AnotherNodeWithAllMapper ); + WithChild: ( AnotherNodeWithChildMapper ) | ( AnotherNodeWithAllMapper ); + WithChildren: ( AnotherNodeWithAllMapper ); }; `); expect(result.content).toBeSimilarStringTo(` @@ -777,18 +789,18 @@ describe('ResolversTypes', () => { String: ResolverTypeWrapper; Child: ResolverTypeWrapper & { parent?: Maybe }>; MyOtherType: ResolverTypeWrapper; - ChildUnion: ResolverTypeWrapper; + ChildUnion: ResolverTypeWrapper['ChildUnion']>; Query: ResolverTypeWrapper<{}>; Subscription: ResolverTypeWrapper<{}>; - Node: ResolversTypes['SomeNode']; + Node: ResolverTypeWrapper['Node']>; ID: ResolverTypeWrapper; SomeNode: ResolverTypeWrapper; - AnotherNode: ResolversTypes['AnotherNodeWithChild'] | ResolversTypes['AnotherNodeWithAll']; - WithChild: ResolversTypes['AnotherNodeWithChild'] | ResolversTypes['AnotherNodeWithAll']; - WithChildren: ResolversTypes['AnotherNodeWithAll']; - AnotherNodeWithChild: ResolverTypeWrapper & { unionChild?: Maybe }>; - AnotherNodeWithAll: ResolverTypeWrapper & { unionChild?: Maybe, unionChildren: Array }>; - MyUnion: ResolverTypeWrapper; + AnotherNode: ResolverTypeWrapper['AnotherNode']>; + WithChild: ResolverTypeWrapper['WithChild']>; + WithChildren: ResolverTypeWrapper['WithChildren']>; + AnotherNodeWithChild: ResolverTypeWrapper; + AnotherNodeWithAll: ResolverTypeWrapper; + MyUnion: ResolverTypeWrapper['MyUnion']>; MyScalar: ResolverTypeWrapper; Int: ResolverTypeWrapper; Boolean: ResolverTypeWrapper; @@ -799,18 +811,18 @@ describe('ResolversTypes', () => { String: Scalars['String']; Child: Omit & { parent?: Maybe }; MyOtherType: DatabaseMyOtherType; - ChildUnion: ResolversUnionParentTypes['ChildUnion']; + ChildUnion: ResolversUnionTypes['ChildUnion']; Query: {}; Subscription: {}; - Node: ResolversParentTypes['SomeNode']; + Node: ResolversInterfaceTypes['Node']; ID: Scalars['ID']; SomeNode: SomeNode; - AnotherNode: ResolversParentTypes['AnotherNodeWithChild'] | ResolversParentTypes['AnotherNodeWithAll']; - WithChild: ResolversParentTypes['AnotherNodeWithChild'] | ResolversParentTypes['AnotherNodeWithAll']; - WithChildren: ResolversParentTypes['AnotherNodeWithAll']; - AnotherNodeWithChild: Omit & { unionChild?: Maybe }; - AnotherNodeWithAll: Omit & { unionChild?: Maybe, unionChildren: Array }; - MyUnion: ResolversUnionParentTypes['MyUnion']; + AnotherNode: ResolversInterfaceTypes['AnotherNode']; + WithChild: ResolversInterfaceTypes['WithChild']; + WithChildren: ResolversInterfaceTypes['WithChildren']; + AnotherNodeWithChild: AnotherNodeWithChildMapper; + AnotherNodeWithAll: AnotherNodeWithAllMapper; + MyUnion: ResolversUnionTypes['MyUnion']; MyScalar: Scalars['MyScalar']; Int: Scalars['Int']; Boolean: Scalars['Boolean']; @@ -827,6 +839,8 @@ describe('ResolversTypes', () => { mappers: { MyOtherType: './my-type#default as DatabaseMyOtherType', MyType: './my-type#MyType as DatabaseMyType', + AnotherNodeWithChild: './my-interface#default as AnotherNodeWithChildMapper', + AnotherNodeWithAll: './my-interface#AnotherNodeWithAll as AnotherNodeWithAllMapper', }, useTypeImports: true, }, @@ -836,16 +850,21 @@ describe('ResolversTypes', () => { expect(result.prepend).toContain( `import type { default as DatabaseMyOtherType, MyType as DatabaseMyType } from './my-type';` ); + expect(result.prepend).toContain( + `import type { default as AnotherNodeWithChildMapper, AnotherNodeWithAll as AnotherNodeWithAllMapper } from './my-interface';` + ); expect(result.content).toBeSimilarStringTo(` - export type ResolversUnionTypes = { - ChildUnion: ( Omit & { parent?: Maybe } ) | ( DatabaseMyOtherType ); + export type ResolversUnionTypes> = { + ChildUnion: ( Omit & { parent?: Maybe } ) | ( DatabaseMyOtherType ); MyUnion: ( DatabaseMyType ) | ( DatabaseMyOtherType ); }; `); expect(result.content).toBeSimilarStringTo(` - export type ResolversUnionParentTypes = { - ChildUnion: ( Omit & { parent?: Maybe } ) | ( DatabaseMyOtherType ); - MyUnion: ( DatabaseMyType ) | ( DatabaseMyOtherType ); + export type ResolversInterfaceTypes> = { + Node: ( SomeNode ); + AnotherNode: ( AnotherNodeWithChildMapper ) | ( AnotherNodeWithAllMapper ); + WithChild: ( AnotherNodeWithChildMapper ) | ( AnotherNodeWithAllMapper ); + WithChildren: ( AnotherNodeWithAllMapper ); }; `); expect(result.content).toBeSimilarStringTo(` @@ -854,18 +873,18 @@ describe('ResolversTypes', () => { String: ResolverTypeWrapper; Child: ResolverTypeWrapper & { parent?: Maybe }>; MyOtherType: ResolverTypeWrapper; - ChildUnion: ResolverTypeWrapper; + ChildUnion: ResolverTypeWrapper['ChildUnion']>; Query: ResolverTypeWrapper<{}>; Subscription: ResolverTypeWrapper<{}>; - Node: ResolversTypes['SomeNode']; + Node: ResolverTypeWrapper['Node']>; ID: ResolverTypeWrapper; SomeNode: ResolverTypeWrapper; - AnotherNode: ResolversTypes['AnotherNodeWithChild'] | ResolversTypes['AnotherNodeWithAll']; - WithChild: ResolversTypes['AnotherNodeWithChild'] | ResolversTypes['AnotherNodeWithAll']; - WithChildren: ResolversTypes['AnotherNodeWithAll']; - AnotherNodeWithChild: ResolverTypeWrapper & { unionChild?: Maybe }>; - AnotherNodeWithAll: ResolverTypeWrapper & { unionChild?: Maybe, unionChildren: Array }>; - MyUnion: ResolverTypeWrapper; + AnotherNode: ResolverTypeWrapper['AnotherNode']>; + WithChild: ResolverTypeWrapper['WithChild']>; + WithChildren: ResolverTypeWrapper['WithChildren']>; + AnotherNodeWithChild: ResolverTypeWrapper; + AnotherNodeWithAll: ResolverTypeWrapper; + MyUnion: ResolverTypeWrapper['MyUnion']>; MyScalar: ResolverTypeWrapper; Int: ResolverTypeWrapper; Boolean: ResolverTypeWrapper; @@ -876,18 +895,18 @@ describe('ResolversTypes', () => { String: Scalars['String']; Child: Omit & { parent?: Maybe }; MyOtherType: DatabaseMyOtherType; - ChildUnion: ResolversUnionParentTypes['ChildUnion']; + ChildUnion: ResolversUnionTypes['ChildUnion']; Query: {}; Subscription: {}; - Node: ResolversParentTypes['SomeNode']; + Node: ResolversInterfaceTypes['Node']; ID: Scalars['ID']; SomeNode: SomeNode; - AnotherNode: ResolversParentTypes['AnotherNodeWithChild'] | ResolversParentTypes['AnotherNodeWithAll']; - WithChild: ResolversParentTypes['AnotherNodeWithChild'] | ResolversParentTypes['AnotherNodeWithAll']; - WithChildren: ResolversParentTypes['AnotherNodeWithAll']; - AnotherNodeWithChild: Omit & { unionChild?: Maybe }; - AnotherNodeWithAll: Omit & { unionChild?: Maybe, unionChildren: Array }; - MyUnion: ResolversUnionParentTypes['MyUnion']; + AnotherNode: ResolversInterfaceTypes['AnotherNode']; + WithChild: ResolversInterfaceTypes['WithChild']; + WithChildren: ResolversInterfaceTypes['WithChildren']; + AnotherNodeWithChild: AnotherNodeWithChildMapper; + AnotherNodeWithAll: AnotherNodeWithAllMapper; + MyUnion: ResolversUnionTypes['MyUnion']; MyScalar: Scalars['MyScalar']; Int: Scalars['Int']; Boolean: Scalars['Boolean']; @@ -911,6 +930,7 @@ describe('ResolversTypes', () => { )) as Types.ComplexPluginOutput; expect(result.content).not.toBeSimilarStringTo(`export type ResolversUnionTypes`); + expect(result.content).not.toBeSimilarStringTo(`export type ResolversInterfaceTypes`); expect(result.content).toBeSimilarStringTo(` export type ResolversTypes = { MyType: ResolverTypeWrapper; @@ -920,12 +940,12 @@ describe('ResolversTypes', () => { ChildUnion: ResolverTypeWrapper; Query: ResolverTypeWrapper<{}>; Subscription: ResolverTypeWrapper<{}>; - Node: ResolversTypes['SomeNode']; + Node: ResolverTypeWrapper; ID: ResolverTypeWrapper; SomeNode: ResolverTypeWrapper; - AnotherNode: ResolversTypes['AnotherNodeWithChild'] | ResolversTypes['AnotherNodeWithAll']; - WithChild: ResolversTypes['AnotherNodeWithChild'] | ResolversTypes['AnotherNodeWithAll']; - WithChildren: ResolversTypes['AnotherNodeWithAll']; + AnotherNode: ResolverTypeWrapper; + WithChild: ResolverTypeWrapper; + WithChildren: ResolverTypeWrapper; AnotherNodeWithChild: ResolverTypeWrapper; AnotherNodeWithAll: ResolverTypeWrapper; MyUnion: ResolverTypeWrapper; @@ -942,12 +962,12 @@ describe('ResolversTypes', () => { ChildUnion: any; Query: {}; Subscription: {}; - Node: ResolversParentTypes['SomeNode']; + Node: any; ID: any; SomeNode: any; - AnotherNode: ResolversParentTypes['AnotherNodeWithChild'] | ResolversParentTypes['AnotherNodeWithAll']; - WithChild: ResolversParentTypes['AnotherNodeWithChild'] | ResolversParentTypes['AnotherNodeWithAll']; - WithChildren: ResolversParentTypes['AnotherNodeWithAll']; + AnotherNode: any; + WithChild: any; + WithChildren: any; AnotherNodeWithChild: any; AnotherNodeWithAll: any; MyUnion: any; @@ -966,21 +986,25 @@ describe('ResolversTypes', () => { mappers: { MyOtherType: './my-module#CustomMyOtherType', MyType: 'MyTypeDb', + AnotherNodeWithChild: './my-interface#AnotherNodeWithChildMapper', + AnotherNodeWithAll: 'AnotherNodeWithAllMapper', }, }, { outputFile: '' } )) as Types.ComplexPluginOutput; expect(result.content).toBeSimilarStringTo(` - export type ResolversUnionTypes = { - ChildUnion: ( Omit & { parent?: Maybe } ) | ( CustomMyOtherType ); + export type ResolversUnionTypes> = { + ChildUnion: ( Omit & { parent?: Maybe } ) | ( CustomMyOtherType ); MyUnion: ( MyTypeDb ) | ( CustomMyOtherType ); }; `); expect(result.content).toBeSimilarStringTo(` - export type ResolversUnionParentTypes = { - ChildUnion: ( Omit & { parent?: Maybe } ) | ( CustomMyOtherType ); - MyUnion: ( MyTypeDb ) | ( CustomMyOtherType ); + export type ResolversInterfaceTypes> = { + Node: ( SomeNode ); + AnotherNode: ( AnotherNodeWithChildMapper ) | ( AnotherNodeWithAllMapper ); + WithChild: ( AnotherNodeWithChildMapper ) | ( AnotherNodeWithAllMapper ); + WithChildren: ( AnotherNodeWithAllMapper ); }; `); expect(result.content).toBeSimilarStringTo(` @@ -989,18 +1013,18 @@ describe('ResolversTypes', () => { String: ResolverTypeWrapper; Child: ResolverTypeWrapper & { parent?: Maybe }>; MyOtherType: ResolverTypeWrapper; - ChildUnion: ResolverTypeWrapper; + ChildUnion: ResolverTypeWrapper['ChildUnion']>; Query: ResolverTypeWrapper<{}>; Subscription: ResolverTypeWrapper<{}>; - Node: ResolversTypes['SomeNode']; + Node: ResolverTypeWrapper['Node']>; ID: ResolverTypeWrapper; SomeNode: ResolverTypeWrapper; - AnotherNode: ResolversTypes['AnotherNodeWithChild'] | ResolversTypes['AnotherNodeWithAll']; - WithChild: ResolversTypes['AnotherNodeWithChild'] | ResolversTypes['AnotherNodeWithAll']; - WithChildren: ResolversTypes['AnotherNodeWithAll']; - AnotherNodeWithChild: ResolverTypeWrapper & { unionChild?: Maybe }>; - AnotherNodeWithAll: ResolverTypeWrapper & { unionChild?: Maybe, unionChildren: Array }>; - MyUnion: ResolverTypeWrapper; + AnotherNode: ResolverTypeWrapper['AnotherNode']>; + WithChild: ResolverTypeWrapper['WithChild']>; + WithChildren: ResolverTypeWrapper['WithChildren']>; + AnotherNodeWithChild: ResolverTypeWrapper; + AnotherNodeWithAll: ResolverTypeWrapper; + MyUnion: ResolverTypeWrapper['MyUnion']>; MyScalar: ResolverTypeWrapper; Int: ResolverTypeWrapper; Boolean: ResolverTypeWrapper; @@ -1011,18 +1035,18 @@ describe('ResolversTypes', () => { String: Scalars['String']; Child: Omit & { parent?: Maybe }; MyOtherType: CustomMyOtherType; - ChildUnion: ResolversUnionParentTypes['ChildUnion']; + ChildUnion: ResolversUnionTypes['ChildUnion']; Query: {}; Subscription: {}; - Node: ResolversParentTypes['SomeNode']; + Node: ResolversInterfaceTypes['Node']; ID: Scalars['ID']; SomeNode: SomeNode; - AnotherNode: ResolversParentTypes['AnotherNodeWithChild'] | ResolversParentTypes['AnotherNodeWithAll']; - WithChild: ResolversParentTypes['AnotherNodeWithChild'] | ResolversParentTypes['AnotherNodeWithAll']; - WithChildren: ResolversParentTypes['AnotherNodeWithAll']; - AnotherNodeWithChild: Omit & { unionChild?: Maybe }; - AnotherNodeWithAll: Omit & { unionChild?: Maybe, unionChildren: Array }; - MyUnion: ResolversUnionParentTypes['MyUnion']; + AnotherNode: ResolversInterfaceTypes['AnotherNode']; + WithChild: ResolversInterfaceTypes['WithChild']; + WithChildren: ResolversInterfaceTypes['WithChildren']; + AnotherNodeWithChild: AnotherNodeWithChildMapper; + AnotherNodeWithAll: AnotherNodeWithAllMapper; + MyUnion: ResolversUnionTypes['MyUnion']; MyScalar: Scalars['MyScalar']; Int: Scalars['Int']; Boolean: Scalars['Boolean']; @@ -1038,21 +1062,24 @@ describe('ResolversTypes', () => { noSchemaStitching: true, mappers: { MyType: 'Partial<{T}>', + AnotherNodeWithChild: 'ExtraPartial<{T}>', }, }, { outputFile: '' } )) as Types.ComplexPluginOutput; expect(result.content).toBeSimilarStringTo(` - export type ResolversUnionTypes = { - ChildUnion: ( Omit & { parent?: Maybe } ) | ( MyOtherType ); - MyUnion: ( Partial & { unionChild?: Maybe }> ) | ( MyOtherType ); + export type ResolversUnionTypes> = { + ChildUnion: ( Omit & { parent?: Maybe } ) | ( MyOtherType ); + MyUnion: ( Partial & { unionChild?: Maybe }> ) | ( MyOtherType ); }; `); expect(result.content).toBeSimilarStringTo(` - export type ResolversUnionParentTypes = { - ChildUnion: ( Omit & { parent?: Maybe } ) | ( MyOtherType ); - MyUnion: ( Partial & { unionChild?: Maybe }> ) | ( MyOtherType ); + export type ResolversInterfaceTypes> = { + Node: ( SomeNode ); + AnotherNode: ( ExtraPartial & { unionChild?: Maybe }> ) | ( Omit & { unionChild?: Maybe, unionChildren: Array } ); + WithChild: ( ExtraPartial & { unionChild?: Maybe }> ) | ( Omit & { unionChild?: Maybe, unionChildren: Array } ); + WithChildren: ( Omit & { unionChild?: Maybe, unionChildren: Array } ); }; `); expect(result.content).toBeSimilarStringTo(` @@ -1061,18 +1088,18 @@ describe('ResolversTypes', () => { String: ResolverTypeWrapper; Child: ResolverTypeWrapper & { parent?: Maybe }>; MyOtherType: ResolverTypeWrapper; - ChildUnion: ResolverTypeWrapper; + ChildUnion: ResolverTypeWrapper['ChildUnion']>; Query: ResolverTypeWrapper<{}>; Subscription: ResolverTypeWrapper<{}>; - Node: ResolversTypes['SomeNode']; + Node: ResolverTypeWrapper['Node']>; ID: ResolverTypeWrapper; SomeNode: ResolverTypeWrapper; - AnotherNode: ResolversTypes['AnotherNodeWithChild'] | ResolversTypes['AnotherNodeWithAll']; - WithChild: ResolversTypes['AnotherNodeWithChild'] | ResolversTypes['AnotherNodeWithAll']; - WithChildren: ResolversTypes['AnotherNodeWithAll']; - AnotherNodeWithChild: ResolverTypeWrapper & { unionChild?: Maybe }>; + AnotherNode: ResolverTypeWrapper['AnotherNode']>; + WithChild: ResolverTypeWrapper['WithChild']>; + WithChildren: ResolverTypeWrapper['WithChildren']>; + AnotherNodeWithChild: ResolverTypeWrapper & { unionChild?: Maybe }>>; AnotherNodeWithAll: ResolverTypeWrapper & { unionChild?: Maybe, unionChildren: Array }>; - MyUnion: ResolverTypeWrapper; + MyUnion: ResolverTypeWrapper['MyUnion']>; MyScalar: ResolverTypeWrapper; Int: ResolverTypeWrapper; Boolean: ResolverTypeWrapper; @@ -1085,18 +1112,18 @@ describe('ResolversTypes', () => { String: Scalars['String']; Child: Omit & { parent?: Maybe }; MyOtherType: MyOtherType; - ChildUnion: ResolversUnionParentTypes['ChildUnion']; + ChildUnion: ResolversUnionTypes['ChildUnion']; Query: {}; Subscription: {}; - Node: ResolversParentTypes['SomeNode']; + Node: ResolversInterfaceTypes['Node']; ID: Scalars['ID']; SomeNode: SomeNode; - AnotherNode: ResolversParentTypes['AnotherNodeWithChild'] | ResolversParentTypes['AnotherNodeWithAll']; - WithChild: ResolversParentTypes['AnotherNodeWithChild'] | ResolversParentTypes['AnotherNodeWithAll']; - WithChildren: ResolversParentTypes['AnotherNodeWithAll']; - AnotherNodeWithChild: Omit & { unionChild?: Maybe }; + AnotherNode: ResolversInterfaceTypes['AnotherNode']; + WithChild: ResolversInterfaceTypes['WithChild']; + WithChildren: ResolversInterfaceTypes['WithChildren']; + AnotherNodeWithChild: ExtraPartial & { unionChild?: Maybe }>; AnotherNodeWithAll: Omit & { unionChild?: Maybe, unionChildren: Array }; - MyUnion: ResolversUnionParentTypes['MyUnion']; + MyUnion: ResolversUnionTypes['MyUnion']; MyScalar: Scalars['MyScalar']; Int: Scalars['Int']; Boolean: Scalars['Boolean']; @@ -1581,15 +1608,17 @@ describe('ResolversTypes', () => { )) as Types.ComplexPluginOutput; expect(result.content).toBeSimilarStringTo(` - export type ResolversUnionTypes = { - ChildUnion: ( Omit & { parent?: Maybe } ) | ( MyOtherTypeCustom ); - MyUnion: ( Omit & { otherType?: Maybe, unionChild?: Maybe } ) | ( MyOtherTypeCustom ); + export type ResolversUnionTypes> = { + ChildUnion: ( Omit & { parent?: Maybe } ) | ( MyOtherTypeCustom ); + MyUnion: ( Omit & { otherType?: Maybe, unionChild?: Maybe } ) | ( MyOtherTypeCustom ); }; `); expect(result.content).toBeSimilarStringTo(` - export type ResolversUnionParentTypes = { - ChildUnion: ( Omit & { parent?: Maybe } ) | ( MyOtherTypeCustom ); - MyUnion: ( Omit & { otherType?: Maybe, unionChild?: Maybe } ) | ( MyOtherTypeCustom ); + export type ResolversInterfaceTypes> = { + Node: ( SomeNode ); + AnotherNode: ( Omit & { unionChild?: Maybe } ) | ( Omit & { unionChild?: Maybe, unionChildren: Array } ); + WithChild: ( Omit & { unionChild?: Maybe } ) | ( Omit & { unionChild?: Maybe, unionChildren: Array } ); + WithChildren: ( Omit & { unionChild?: Maybe, unionChildren: Array } ); }; `); expect(result.content).toBeSimilarStringTo(` @@ -1598,18 +1627,18 @@ describe('ResolversTypes', () => { String: ResolverTypeWrapper; Child: ResolverTypeWrapper & { parent?: Maybe }>; MyOtherType: ResolverTypeWrapper; - ChildUnion: ResolverTypeWrapper; + ChildUnion: ResolverTypeWrapper['ChildUnion']>; Query: ResolverTypeWrapper<{}>; Subscription: ResolverTypeWrapper<{}>; - Node: ResolversTypes['SomeNode']; + Node: ResolverTypeWrapper['Node']>; ID: ResolverTypeWrapper; SomeNode: ResolverTypeWrapper; - AnotherNode: ResolversTypes['AnotherNodeWithChild'] | ResolversTypes['AnotherNodeWithAll']; - WithChild: ResolversTypes['AnotherNodeWithChild'] | ResolversTypes['AnotherNodeWithAll']; - WithChildren: ResolversTypes['AnotherNodeWithAll']; + AnotherNode: ResolverTypeWrapper['AnotherNode']>; + WithChild: ResolverTypeWrapper['WithChild']>; + WithChildren: ResolverTypeWrapper['WithChildren']>; AnotherNodeWithChild: ResolverTypeWrapper & { unionChild?: Maybe }>; AnotherNodeWithAll: ResolverTypeWrapper & { unionChild?: Maybe, unionChildren: Array }>; - MyUnion: ResolverTypeWrapper; + MyUnion: ResolverTypeWrapper['MyUnion']>; MyScalar: ResolverTypeWrapper; Int: ResolverTypeWrapper; Boolean: ResolverTypeWrapper; @@ -1620,18 +1649,18 @@ describe('ResolversTypes', () => { String: Scalars['String']; Child: Omit & { parent?: Maybe }; MyOtherType: MyOtherTypeCustom; - ChildUnion: ResolversUnionParentTypes['ChildUnion']; + ChildUnion: ResolversUnionTypes['ChildUnion']; Query: {}; Subscription: {}; - Node: ResolversParentTypes['SomeNode']; + Node: ResolversInterfaceTypes['Node']; ID: Scalars['ID']; SomeNode: SomeNode; - AnotherNode: ResolversParentTypes['AnotherNodeWithChild'] | ResolversParentTypes['AnotherNodeWithAll']; - WithChild: ResolversParentTypes['AnotherNodeWithChild'] | ResolversParentTypes['AnotherNodeWithAll']; - WithChildren: ResolversParentTypes['AnotherNodeWithAll']; + AnotherNode: ResolversInterfaceTypes['AnotherNode']; + WithChild: ResolversInterfaceTypes['WithChild']; + WithChildren: ResolversInterfaceTypes['WithChildren']; AnotherNodeWithChild: Omit & { unionChild?: Maybe }; AnotherNodeWithAll: Omit & { unionChild?: Maybe, unionChildren: Array }; - MyUnion: ResolversUnionParentTypes['MyUnion']; + MyUnion: ResolversUnionTypes['MyUnion']; MyScalar: Scalars['MyScalar']; Int: Scalars['Int']; Boolean: Scalars['Boolean']; @@ -1655,15 +1684,17 @@ describe('ResolversTypes', () => { )) as Types.ComplexPluginOutput; expect(result.content).toBeSimilarStringTo(` - export type ResolversUnionTypes = { - ChildUnion: ( Omit & { parent?: Maybe } ) | ( MyOtherTypeCustom ); + export type ResolversUnionTypes> = { + ChildUnion: ( Omit & { parent?: Maybe } ) | ( MyOtherTypeCustom ); MyUnion: ( MyTypeCustom ) | ( MyOtherTypeCustom ); }; `); expect(result.content).toBeSimilarStringTo(` - export type ResolversUnionParentTypes = { - ChildUnion: ( Omit & { parent?: Maybe } ) | ( MyOtherTypeCustom ); - MyUnion: ( MyTypeCustom ) | ( MyOtherTypeCustom ); + export type ResolversInterfaceTypes> = { + Node: ( SomeNode ); + AnotherNode: ( Omit & { unionChild?: Maybe } ) | ( Omit & { unionChild?: Maybe, unionChildren: Array } ); + WithChild: ( Omit & { unionChild?: Maybe } ) | ( Omit & { unionChild?: Maybe, unionChildren: Array } ); + WithChildren: ( Omit & { unionChild?: Maybe, unionChildren: Array } ); }; `); expect(result.content).toBeSimilarStringTo(` @@ -1672,18 +1703,18 @@ describe('ResolversTypes', () => { String: ResolverTypeWrapper; Child: ResolverTypeWrapper & { parent?: Maybe }>; MyOtherType: ResolverTypeWrapper; - ChildUnion: ResolverTypeWrapper; + ChildUnion: ResolverTypeWrapper['ChildUnion']>; Query: ResolverTypeWrapper<{}>; Subscription: ResolverTypeWrapper<{}>; - Node: ResolversTypes['SomeNode']; + Node: ResolverTypeWrapper['Node']>; ID: ResolverTypeWrapper; SomeNode: ResolverTypeWrapper; - AnotherNode: ResolversTypes['AnotherNodeWithChild'] | ResolversTypes['AnotherNodeWithAll']; - WithChild: ResolversTypes['AnotherNodeWithChild'] | ResolversTypes['AnotherNodeWithAll']; - WithChildren: ResolversTypes['AnotherNodeWithAll']; + AnotherNode: ResolverTypeWrapper['AnotherNode']>; + WithChild: ResolverTypeWrapper['WithChild']>; + WithChildren: ResolverTypeWrapper['WithChildren']>; AnotherNodeWithChild: ResolverTypeWrapper & { unionChild?: Maybe }>; AnotherNodeWithAll: ResolverTypeWrapper & { unionChild?: Maybe, unionChildren: Array }>; - MyUnion: ResolverTypeWrapper; + MyUnion: ResolverTypeWrapper['MyUnion']>; MyScalar: ResolverTypeWrapper; Int: ResolverTypeWrapper; Boolean: ResolverTypeWrapper; @@ -1694,18 +1725,18 @@ describe('ResolversTypes', () => { String: Scalars['String']; Child: Omit & { parent?: Maybe }; MyOtherType: MyOtherTypeCustom; - ChildUnion: ResolversUnionParentTypes['ChildUnion']; + ChildUnion: ResolversUnionTypes['ChildUnion']; Query: {}; Subscription: {}; - Node: ResolversParentTypes['SomeNode']; + Node: ResolversInterfaceTypes['Node']; ID: Scalars['ID']; SomeNode: SomeNode; - AnotherNode: ResolversParentTypes['AnotherNodeWithChild'] | ResolversParentTypes['AnotherNodeWithAll']; - WithChild: ResolversParentTypes['AnotherNodeWithChild'] | ResolversParentTypes['AnotherNodeWithAll']; - WithChildren: ResolversParentTypes['AnotherNodeWithAll']; + AnotherNode: ResolversInterfaceTypes['AnotherNode']; + WithChild: ResolversInterfaceTypes['WithChild']; + WithChildren: ResolversInterfaceTypes['WithChildren']; AnotherNodeWithChild: Omit & { unionChild?: Maybe }; AnotherNodeWithAll: Omit & { unionChild?: Maybe, unionChildren: Array }; - MyUnion: ResolversUnionParentTypes['MyUnion']; + MyUnion: ResolversUnionTypes['MyUnion']; MyScalar: Scalars['MyScalar']; Int: Scalars['Int']; Boolean: Scalars['Boolean']; @@ -1722,22 +1753,26 @@ describe('ResolversTypes', () => { noSchemaStitching: true, mappers: { MyOtherType: './my-file#MyNamespace#MyCustomOtherType', + AnotherNodeWithChild: './my-interface#InterfaceNamespace#AnotherNodeWithChildMapper', }, }, { outputFile: '' } )) as Types.ComplexPluginOutput; expect(result.prepend).toContain(`import { MyNamespace } from './my-file';`); + expect(result.prepend).toContain(`import { InterfaceNamespace } from './my-interface';`); expect(result.content).toBeSimilarStringTo(` - export type ResolversUnionTypes = { - ChildUnion: ( Omit & { parent?: Maybe } ) | ( MyNamespace.MyCustomOtherType ); - MyUnion: ( Omit & { otherType?: Maybe, unionChild?: Maybe } ) | ( MyNamespace.MyCustomOtherType ); + export type ResolversUnionTypes> = { + ChildUnion: ( Omit & { parent?: Maybe } ) | ( MyNamespace.MyCustomOtherType ); + MyUnion: ( Omit & { otherType?: Maybe, unionChild?: Maybe } ) | ( MyNamespace.MyCustomOtherType ); }; `); expect(result.content).toBeSimilarStringTo(` - export type ResolversUnionParentTypes = { - ChildUnion: ( Omit & { parent?: Maybe } ) | ( MyNamespace.MyCustomOtherType ); - MyUnion: ( Omit & { otherType?: Maybe, unionChild?: Maybe } ) | ( MyNamespace.MyCustomOtherType ); + export type ResolversInterfaceTypes> = { + Node: ( SomeNode ); + AnotherNode: ( InterfaceNamespace.AnotherNodeWithChildMapper ) | ( Omit & { unionChild?: Maybe, unionChildren: Array } ); + WithChild: ( InterfaceNamespace.AnotherNodeWithChildMapper ) | ( Omit & { unionChild?: Maybe, unionChildren: Array } ); + WithChildren: ( Omit & { unionChild?: Maybe, unionChildren: Array } ); }; `); expect(result.content).toBeSimilarStringTo(` @@ -1746,18 +1781,18 @@ describe('ResolversTypes', () => { String: ResolverTypeWrapper; Child: ResolverTypeWrapper & { parent?: Maybe }>; MyOtherType: ResolverTypeWrapper; - ChildUnion: ResolverTypeWrapper; + ChildUnion: ResolverTypeWrapper['ChildUnion']>; Query: ResolverTypeWrapper<{}>; Subscription: ResolverTypeWrapper<{}>; - Node: ResolversTypes['SomeNode']; + Node: ResolverTypeWrapper['Node']>; ID: ResolverTypeWrapper; SomeNode: ResolverTypeWrapper; - AnotherNode: ResolversTypes['AnotherNodeWithChild'] | ResolversTypes['AnotherNodeWithAll']; - WithChild: ResolversTypes['AnotherNodeWithChild'] | ResolversTypes['AnotherNodeWithAll']; - WithChildren: ResolversTypes['AnotherNodeWithAll']; - AnotherNodeWithChild: ResolverTypeWrapper & { unionChild?: Maybe }>; + AnotherNode: ResolverTypeWrapper['AnotherNode']>; + WithChild: ResolverTypeWrapper['WithChild']>; + WithChildren: ResolverTypeWrapper['WithChildren']>; + AnotherNodeWithChild: ResolverTypeWrapper; AnotherNodeWithAll: ResolverTypeWrapper & { unionChild?: Maybe, unionChildren: Array }>; - MyUnion: ResolverTypeWrapper; + MyUnion: ResolverTypeWrapper['MyUnion']>; MyScalar: ResolverTypeWrapper; Int: ResolverTypeWrapper; Boolean: ResolverTypeWrapper; @@ -1770,18 +1805,18 @@ describe('ResolversTypes', () => { String: Scalars['String']; Child: Omit & { parent?: Maybe }; MyOtherType: MyNamespace.MyCustomOtherType; - ChildUnion: ResolversUnionParentTypes['ChildUnion']; + ChildUnion: ResolversUnionTypes['ChildUnion']; Query: {}; Subscription: {}; - Node: ResolversParentTypes['SomeNode']; + Node: ResolversInterfaceTypes['Node']; ID: Scalars['ID']; SomeNode: SomeNode; - AnotherNode: ResolversParentTypes['AnotherNodeWithChild'] | ResolversParentTypes['AnotherNodeWithAll']; - WithChild: ResolversParentTypes['AnotherNodeWithChild'] | ResolversParentTypes['AnotherNodeWithAll']; - WithChildren: ResolversParentTypes['AnotherNodeWithAll']; - AnotherNodeWithChild: Omit & { unionChild?: Maybe }; + AnotherNode: ResolversInterfaceTypes['AnotherNode']; + WithChild: ResolversInterfaceTypes['WithChild']; + WithChildren: ResolversInterfaceTypes['WithChildren']; + AnotherNodeWithChild: InterfaceNamespace.AnotherNodeWithChildMapper; AnotherNodeWithAll: Omit & { unionChild?: Maybe, unionChildren: Array }; - MyUnion: ResolversUnionParentTypes['MyUnion']; + MyUnion: ResolversUnionTypes['MyUnion']; MyScalar: Scalars['MyScalar']; Int: Scalars['Int']; Boolean: Scalars['Boolean']; @@ -1820,6 +1855,7 @@ describe('ResolversTypes', () => { expect(result.prepend).toContain(`import { MyNamespace } from './my-file';`); expect(result.content).not.toBeSimilarStringTo(`export type ResolversUnionTypes`); expect(result.content).not.toBeSimilarStringTo(`export type ResolversParentUnionTypes`); + expect(result.content).not.toBeSimilarStringTo(`export type ResolversInterfaceTypes`); expect(result.content).toBeSimilarStringTo(` export type ResolversTypes = { MyType: ResolverTypeWrapper; @@ -1829,12 +1865,12 @@ describe('ResolversTypes', () => { ChildUnion: ResolverTypeWrapper; Query: ResolverTypeWrapper<{}>; Subscription: ResolverTypeWrapper<{}>; - Node: ResolversTypes['SomeNode']; + Node: ResolverTypeWrapper; ID: ResolverTypeWrapper; SomeNode: ResolverTypeWrapper; - AnotherNode: ResolversTypes['AnotherNodeWithChild'] | ResolversTypes['AnotherNodeWithAll']; - WithChild: ResolversTypes['AnotherNodeWithChild'] | ResolversTypes['AnotherNodeWithAll']; - WithChildren: ResolversTypes['AnotherNodeWithAll']; + AnotherNode: ResolverTypeWrapper; + WithChild: ResolverTypeWrapper; + WithChildren: ResolverTypeWrapper; AnotherNodeWithChild: ResolverTypeWrapper; AnotherNodeWithAll: ResolverTypeWrapper; MyUnion: ResolverTypeWrapper; @@ -1853,12 +1889,12 @@ describe('ResolversTypes', () => { ChildUnion: MyNamespace.MyDefaultMapper; Query: {}; Subscription: {}; - Node: ResolversParentTypes['SomeNode']; + Node: MyNamespace.MyDefaultMapper; ID: MyNamespace.MyDefaultMapper; SomeNode: MyNamespace.MyDefaultMapper; - AnotherNode: ResolversParentTypes['AnotherNodeWithChild'] | ResolversParentTypes['AnotherNodeWithAll']; - WithChild: ResolversParentTypes['AnotherNodeWithChild'] | ResolversParentTypes['AnotherNodeWithAll']; - WithChildren: ResolversParentTypes['AnotherNodeWithAll']; + AnotherNode: MyNamespace.MyDefaultMapper; + WithChild: MyNamespace.MyDefaultMapper; + WithChildren: MyNamespace.MyDefaultMapper; AnotherNodeWithChild: MyNamespace.MyDefaultMapper; AnotherNodeWithAll: MyNamespace.MyDefaultMapper; MyUnion: MyNamespace.MyDefaultMapper; @@ -1882,15 +1918,17 @@ describe('ResolversTypes', () => { expect(result.prepend).toContain(`import { MyNamespace } from './my-file';`); expect(result.content).toBeSimilarStringTo(` - export type ResolversUnionTypes = { + export type ResolversUnionTypes> = { ChildUnion: ( Child ) | ( MyOtherType ); - MyUnion: ( Omit & { unionChild?: Maybe } ) | ( MyOtherType ); + MyUnion: ( Omit & { unionChild?: Maybe } ) | ( MyOtherType ); }; `); expect(result.content).toBeSimilarStringTo(` - export type ResolversUnionParentTypes = { - ChildUnion: ( Child ) | ( MyOtherType ); - MyUnion: ( Omit & { unionChild?: Maybe } ) | ( MyOtherType ); + export type ResolversInterfaceTypes> = { + Node: ( SomeNode ); + AnotherNode: ( Omit & { unionChild?: Maybe } ) | ( Omit & { unionChild?: Maybe, unionChildren: Array } ); + WithChild: ( Omit & { unionChild?: Maybe } ) | ( Omit & { unionChild?: Maybe, unionChildren: Array } ); + WithChildren: ( Omit & { unionChild?: Maybe, unionChildren: Array } ); }; `); expect(result.content).toBeSimilarStringTo(` @@ -1899,18 +1937,18 @@ describe('ResolversTypes', () => { String: ResolverTypeWrapper; Child: ResolverTypeWrapper; MyOtherType: ResolverTypeWrapper; - ChildUnion: ResolverTypeWrapper; + ChildUnion: ResolverTypeWrapper['ChildUnion']>; Query: ResolverTypeWrapper; Subscription: ResolverTypeWrapper; - Node: ResolversTypes['SomeNode']; + Node: ResolverTypeWrapper['Node']>; ID: ResolverTypeWrapper; SomeNode: ResolverTypeWrapper; - AnotherNode: ResolversTypes['AnotherNodeWithChild'] | ResolversTypes['AnotherNodeWithAll']; - WithChild: ResolversTypes['AnotherNodeWithChild'] | ResolversTypes['AnotherNodeWithAll']; - WithChildren: ResolversTypes['AnotherNodeWithAll']; + AnotherNode: ResolverTypeWrapper['AnotherNode']>; + WithChild: ResolverTypeWrapper['WithChild']>; + WithChildren: ResolverTypeWrapper['WithChildren']>; AnotherNodeWithChild: ResolverTypeWrapper & { unionChild?: Maybe }>; AnotherNodeWithAll: ResolverTypeWrapper & { unionChild?: Maybe, unionChildren: Array }>; - MyUnion: ResolverTypeWrapper; + MyUnion: ResolverTypeWrapper['MyUnion']>; MyScalar: ResolverTypeWrapper; Int: ResolverTypeWrapper; Boolean: ResolverTypeWrapper; @@ -1923,18 +1961,18 @@ describe('ResolversTypes', () => { String: Scalars['String']; Child: Child; MyOtherType: MyOtherType; - ChildUnion: ResolversUnionParentTypes['ChildUnion']; + ChildUnion: ResolversUnionTypes['ChildUnion']; Query: MyNamespace.MyRootType; Subscription: MyNamespace.MyRootType; - Node: ResolversParentTypes['SomeNode']; + Node: ResolversInterfaceTypes['Node']; ID: Scalars['ID']; SomeNode: SomeNode; - AnotherNode: ResolversParentTypes['AnotherNodeWithChild'] | ResolversParentTypes['AnotherNodeWithAll']; - WithChild: ResolversParentTypes['AnotherNodeWithChild'] | ResolversParentTypes['AnotherNodeWithAll']; - WithChildren: ResolversParentTypes['AnotherNodeWithAll']; + AnotherNode: ResolversInterfaceTypes['AnotherNode']; + WithChild: ResolversInterfaceTypes['WithChild']; + WithChildren: ResolversInterfaceTypes['WithChildren']; AnotherNodeWithChild: Omit & { unionChild?: Maybe }; AnotherNodeWithAll: Omit & { unionChild?: Maybe, unionChildren: Array }; - MyUnion: ResolversUnionParentTypes['MyUnion']; + MyUnion: ResolversUnionTypes['MyUnion']; MyScalar: Scalars['MyScalar']; Int: Scalars['Int']; Boolean: Scalars['Boolean']; @@ -1950,6 +1988,7 @@ describe('ResolversTypes', () => { defaultMapper: './my-file#MyNamespace#MyDefaultMapper<{T}>', mappers: { MyType: './my-file#MyNamespace#MyType<{T}>', + AnotherNodeWithChild: './my-inteface#InterfaceNamespace#MyInterface<{T}>', }, }, { outputFile: '' } @@ -1957,15 +1996,17 @@ describe('ResolversTypes', () => { expect(result.prepend).toContain(`import { MyNamespace } from './my-file';`); expect(result.content).toBeSimilarStringTo(` - export type ResolversUnionTypes = { - ChildUnion: ( MyNamespace.MyDefaultMapper & { parent?: Maybe }> ) | ( MyNamespace.MyDefaultMapper ); - MyUnion: ( MyNamespace.MyType & { unionChild?: Maybe }> ) | ( MyNamespace.MyDefaultMapper ); + export type ResolversUnionTypes> = { + ChildUnion: ( MyNamespace.MyDefaultMapper & { parent?: Maybe }> ) | ( MyNamespace.MyDefaultMapper ); + MyUnion: ( MyNamespace.MyType & { unionChild?: Maybe }> ) | ( MyNamespace.MyDefaultMapper ); }; `); expect(result.content).toBeSimilarStringTo(` - export type ResolversUnionParentTypes = { - ChildUnion: ( MyNamespace.MyDefaultMapper & { parent?: Maybe }> ) | ( MyNamespace.MyDefaultMapper ); - MyUnion: ( MyNamespace.MyType & { unionChild?: Maybe }> ) | ( MyNamespace.MyDefaultMapper ); + export type ResolversInterfaceTypes> = { + Node: ( MyNamespace.MyDefaultMapper ); + AnotherNode: ( InterfaceNamespace.MyInterface & { unionChild?: Maybe }> ) | ( MyNamespace.MyDefaultMapper & { unionChild?: Maybe, unionChildren: Array }> ); + WithChild: ( InterfaceNamespace.MyInterface & { unionChild?: Maybe }> ) | ( MyNamespace.MyDefaultMapper & { unionChild?: Maybe, unionChildren: Array }> ); + WithChildren: ( MyNamespace.MyDefaultMapper & { unionChild?: Maybe, unionChildren: Array }> ); }; `); expect(result.content).toBeSimilarStringTo(` @@ -1974,18 +2015,18 @@ describe('ResolversTypes', () => { String: ResolverTypeWrapper>; Child: ResolverTypeWrapper & { parent?: Maybe }>>; MyOtherType: ResolverTypeWrapper>; - ChildUnion: MyNamespace.MyDefaultMapper>; + ChildUnion: MyNamespace.MyDefaultMapper['ChildUnion']>>; Query: ResolverTypeWrapper<{}>; Subscription: ResolverTypeWrapper<{}>; - Node: ResolversTypes['SomeNode']; + Node: ResolverTypeWrapper['Node']>; ID: ResolverTypeWrapper>; SomeNode: ResolverTypeWrapper>; - AnotherNode: ResolversTypes['AnotherNodeWithChild'] | ResolversTypes['AnotherNodeWithAll']; - WithChild: ResolversTypes['AnotherNodeWithChild'] | ResolversTypes['AnotherNodeWithAll']; - WithChildren: ResolversTypes['AnotherNodeWithAll']; - AnotherNodeWithChild: ResolverTypeWrapper & { unionChild?: Maybe }>>; + AnotherNode: ResolverTypeWrapper['AnotherNode']>; + WithChild: ResolverTypeWrapper['WithChild']>; + WithChildren: ResolverTypeWrapper['WithChildren']>; + AnotherNodeWithChild: ResolverTypeWrapper & { unionChild?: Maybe }>>; AnotherNodeWithAll: ResolverTypeWrapper & { unionChild?: Maybe, unionChildren: Array }>>; - MyUnion: MyNamespace.MyDefaultMapper>; + MyUnion: MyNamespace.MyDefaultMapper['MyUnion']>>; MyScalar: ResolverTypeWrapper>; Int: ResolverTypeWrapper>; Boolean: ResolverTypeWrapper>; @@ -1997,18 +2038,18 @@ describe('ResolversTypes', () => { String: MyNamespace.MyDefaultMapper; Child: MyNamespace.MyDefaultMapper & { parent?: Maybe }>; MyOtherType: MyNamespace.MyDefaultMapper; - ChildUnion: MyNamespace.MyDefaultMapper; + ChildUnion: MyNamespace.MyDefaultMapper['ChildUnion']>; Query: {}; Subscription: {}; - Node: ResolversParentTypes['SomeNode']; + Node: ResolversInterfaceTypes['Node']; ID: MyNamespace.MyDefaultMapper; SomeNode: MyNamespace.MyDefaultMapper; - AnotherNode: ResolversParentTypes['AnotherNodeWithChild'] | ResolversParentTypes['AnotherNodeWithAll']; - WithChild: ResolversParentTypes['AnotherNodeWithChild'] | ResolversParentTypes['AnotherNodeWithAll']; - WithChildren: ResolversParentTypes['AnotherNodeWithAll']; - AnotherNodeWithChild: MyNamespace.MyDefaultMapper & { unionChild?: Maybe }>; + AnotherNode: ResolversInterfaceTypes['AnotherNode']; + WithChild: ResolversInterfaceTypes['WithChild']; + WithChildren: ResolversInterfaceTypes['WithChildren']; + AnotherNodeWithChild: InterfaceNamespace.MyInterface & { unionChild?: Maybe }>; AnotherNodeWithAll: MyNamespace.MyDefaultMapper & { unionChild?: Maybe, unionChildren: Array }>; - MyUnion: MyNamespace.MyDefaultMapper; + MyUnion: MyNamespace.MyDefaultMapper['MyUnion']>; MyScalar: MyNamespace.MyDefaultMapper; Int: MyNamespace.MyDefaultMapper; Boolean: MyNamespace.MyDefaultMapper; diff --git a/packages/plugins/typescript/resolvers/tests/ts-resolvers.spec.ts b/packages/plugins/typescript/resolvers/tests/ts-resolvers.spec.ts index 21b39529693..bd52c93cd9e 100644 --- a/packages/plugins/typescript/resolvers/tests/ts-resolvers.spec.ts +++ b/packages/plugins/typescript/resolvers/tests/ts-resolvers.spec.ts @@ -234,15 +234,17 @@ export type MyTypeResolvers> = { ChildUnion: ( Child & { __typename: 'Child' } ) | ( MyOtherType & { __typename: 'MyOtherType' } ); - MyUnion: ( Omit & { unionChild?: Maybe } & { __typename: 'MyType' } ) | ( MyOtherType & { __typename: 'MyOtherType' } ); + MyUnion: ( Omit & { unionChild?: Maybe } & { __typename: 'MyType' } ) | ( MyOtherType & { __typename: 'MyOtherType' } ); }; `); expect(result.content).toBeSimilarStringTo(` - export type ResolversUnionParentTypes = { - ChildUnion: ( Child & { __typename: 'Child' } ) | ( MyOtherType & { __typename: 'MyOtherType' } ); - MyUnion: ( Omit & { unionChild?: Maybe } & { __typename: 'MyType' } ) | ( MyOtherType & { __typename: 'MyOtherType' } ); + export type ResolversInterfaceTypes> = { + Node: ( SomeNode & { __typename: 'SomeNode' } ); + AnotherNode: ( Omit & { unionChild?: Maybe } & { __typename: 'AnotherNodeWithChild' } ) | ( Omit & { unionChild?: Maybe, unionChildren: Array } & { __typename: 'AnotherNodeWithAll' } ); + WithChild: ( Omit & { unionChild?: Maybe } & { __typename: 'AnotherNodeWithChild' } ) | ( Omit & { unionChild?: Maybe, unionChildren: Array } & { __typename: 'AnotherNodeWithAll' } ); + WithChildren: ( Omit & { unionChild?: Maybe, unionChildren: Array } & { __typename: 'AnotherNodeWithAll' } ); }; `); }); @@ -256,15 +258,9 @@ export type MyTypeResolvers & { unionChild?: Maybe } & { __typename: 'MyType' } ) | ( MyOtherType & { __typename: 'MyOtherType' } ); - }; - `); - expect(result.content).toBeSimilarStringTo(` - export type ResolversUnionParentTypes = { + export type ResolversUnionTypes> = { ChildUnion: ( Child & { __typename: 'Child' } ) | ( MyOtherType & { __typename: 'MyOtherType' } ); - MyUnion: ( Omit & { unionChild?: Maybe } & { __typename: 'MyType' } ) | ( MyOtherType & { __typename: 'MyOtherType' } ); + MyUnion: ( Omit & { unionChild?: Maybe } & { __typename: 'MyType' } ) | ( MyOtherType & { __typename: 'MyOtherType' } ); }; `); }); @@ -281,13 +277,7 @@ export type MyTypeResolvers> = { ChildUnion: ( ChildMapper & { __typename: 'Child' } ) | ( MyOtherType & { __typename: 'MyOtherType' } ); MyUnion: ( MyTypeMapper & { __typename: 'MyType' } ) | ( MyOtherType & { __typename: 'MyOtherType' } ); }; @@ -306,15 +296,9 @@ export type MyTypeResolvers & { parent?: Maybe }> & { __typename: 'Child' } ) | ( MyOtherType & { __typename: 'MyOtherType' } ); - MyUnion: ( MyWrapper & { unionChild?: Maybe }> & { __typename: 'MyType' } ) | ( MyOtherType & { __typename: 'MyOtherType' } ); - }; - `); - expect(result.content).toBeSimilarStringTo(` - export type ResolversUnionParentTypes = { - ChildUnion: ( Wrapper & { parent?: Maybe }> & { __typename: 'Child' } ) | ( MyOtherType & { __typename: 'MyOtherType' } ); - MyUnion: ( MyWrapper & { unionChild?: Maybe }> & { __typename: 'MyType' } ) | ( MyOtherType & { __typename: 'MyOtherType' } ); + export type ResolversUnionTypes> = { + ChildUnion: ( Wrapper & { parent?: Maybe }> & { __typename: 'Child' } ) | ( MyOtherType & { __typename: 'MyOtherType' } ); + MyUnion: ( MyWrapper & { unionChild?: Maybe }> & { __typename: 'MyType' } ) | ( MyOtherType & { __typename: 'MyOtherType' } ); }; `); }); @@ -331,15 +315,9 @@ export type MyTypeResolvers & { __typename: 'Child' } ) | ( Partial & { __typename: 'MyOtherType' } ); - MyUnion: ( Partial & { unionChild?: Maybe }> & { __typename: 'MyType' } ) | ( Partial & { __typename: 'MyOtherType' } ); - }; - `); - expect(result.content).toBeSimilarStringTo(` - export type ResolversUnionParentTypes = { + export type ResolversUnionTypes> = { ChildUnion: ( Partial & { __typename: 'Child' } ) | ( Partial & { __typename: 'MyOtherType' } ); - MyUnion: ( Partial & { unionChild?: Maybe }> & { __typename: 'MyType' } ) | ( Partial & { __typename: 'MyOtherType' } ); + MyUnion: ( Partial & { unionChild?: Maybe }> & { __typename: 'MyType' } ) | ( Partial & { __typename: 'MyOtherType' } ); }; `); }); @@ -358,6 +336,101 @@ export type MyTypeResolvers { + const result = await plugin( + resolversTestingSchema, + [], + { resolversNonOptionalTypename: { interfaceImplementingType: true } }, + { outputFile: '' } + ); + + expect(result.content).toBeSimilarStringTo(` + export type ResolversInterfaceTypes> = { + Node: ( SomeNode & { __typename: 'SomeNode' } ); + AnotherNode: ( Omit & { unionChild?: Maybe } & { __typename: 'AnotherNodeWithChild' } ) | ( Omit & { unionChild?: Maybe, unionChildren: Array } & { __typename: 'AnotherNodeWithAll' } ); + WithChild: ( Omit & { unionChild?: Maybe } & { __typename: 'AnotherNodeWithChild' } ) | ( Omit & { unionChild?: Maybe, unionChildren: Array } & { __typename: 'AnotherNodeWithAll' } ); + WithChildren: ( Omit & { unionChild?: Maybe, unionChildren: Array } & { __typename: 'AnotherNodeWithAll' } ); + }; + `); + }); + + it('resolversNonOptionalTypename - adds non-optional typenames to ResolversInterfaceTypes for mappers with no placeholder', async () => { + const result = await plugin( + resolversTestingSchema, + [], + { + resolversNonOptionalTypename: { interfaceImplementingType: true }, + mappers: { AnotherNodeWithChild: 'AnotherNodeWithChildMapper' }, + }, + { outputFile: '' } + ); + + expect(result.content).toBeSimilarStringTo(` + export type ResolversInterfaceTypes> = { + Node: ( SomeNode & { __typename: 'SomeNode' } ); + AnotherNode: ( AnotherNodeWithChildMapper & { __typename: 'AnotherNodeWithChild' } ) | ( Omit & { unionChild?: Maybe, unionChildren: Array } & { __typename: 'AnotherNodeWithAll' } ); + WithChild: ( AnotherNodeWithChildMapper & { __typename: 'AnotherNodeWithChild' } ) | ( Omit & { unionChild?: Maybe, unionChildren: Array } & { __typename: 'AnotherNodeWithAll' } ); + WithChildren: ( Omit & { unionChild?: Maybe, unionChildren: Array } & { __typename: 'AnotherNodeWithAll' } ); + }; + `); + }); + + it('resolversNonOptionalTypename - adds non-optional typenames to ResolversInterfaceTypes for mappers with placeholder', async () => { + const result = await plugin( + resolversTestingSchema, + [], + { + resolversNonOptionalTypename: { interfaceImplementingType: true }, + mappers: { AnotherNodeWithChild: 'Wrapper<{T}>' }, + }, + { outputFile: '' } + ); + + expect(result.content).toBeSimilarStringTo(` + export type ResolversInterfaceTypes> = { + Node: ( SomeNode & { __typename: 'SomeNode' } ); + AnotherNode: ( Wrapper & { unionChild?: Maybe }> & { __typename: 'AnotherNodeWithChild' } ) | ( Omit & { unionChild?: Maybe, unionChildren: Array } & { __typename: 'AnotherNodeWithAll' } ); + WithChild: ( Wrapper & { unionChild?: Maybe }> & { __typename: 'AnotherNodeWithChild' } ) | ( Omit & { unionChild?: Maybe, unionChildren: Array } & { __typename: 'AnotherNodeWithAll' } ); + WithChildren: ( Omit & { unionChild?: Maybe, unionChildren: Array } & { __typename: 'AnotherNodeWithAll' } ); + }; + `); + }); + + it('resolversNonOptionalTypename - adds non-optional typenames to ResolversInterfaceTypes for default mappers with placeholder', async () => { + const result = await plugin( + resolversTestingSchema, + [], + { + resolversNonOptionalTypename: { interfaceImplementingType: true }, + defaultMapper: 'Partial<{T}>', + }, + { outputFile: '' } + ); + + expect(result.content).toBeSimilarStringTo(` + export type ResolversInterfaceTypes> = { + Node: ( Partial & { __typename: 'SomeNode' } ); + AnotherNode: ( Partial & { unionChild?: Maybe }> & { __typename: 'AnotherNodeWithChild' } ) | ( Partial & { unionChild?: Maybe, unionChildren: Array }> & { __typename: 'AnotherNodeWithAll' } ); + WithChild: ( Partial & { unionChild?: Maybe }> & { __typename: 'AnotherNodeWithChild' } ) | ( Partial & { unionChild?: Maybe, unionChildren: Array }> & { __typename: 'AnotherNodeWithAll' } ); + WithChildren: ( Partial & { unionChild?: Maybe, unionChildren: Array }> & { __typename: 'AnotherNodeWithAll' } ); + }; + `); + }); + + it('resolversNonOptionalTypename - does not create ResolversInterfaceTypes for default mappers with no placeholder', async () => { + const result = await plugin( + resolversTestingSchema, + [], + { + resolversNonOptionalTypename: { interfaceImplementingType: true }, + defaultMapper: 'unknown', + }, + { outputFile: '' } + ); + + expect(result.content).not.toBeSimilarStringTo('export type ResolversInterfaceTypes'); + }); }); it('directiveResolverMappings - should generate correct types (import definition)', async () => { @@ -1577,12 +1650,7 @@ export type ResolverFn = ( `); expect(content.content).toBeSimilarStringTo(` - export type ResolversUnionTypes = { - CCCUnion: ( CccFoo ) | ( CccBar ); - }; - `); - expect(content.content).toBeSimilarStringTo(` - export type ResolversUnionParentTypes = { + export type ResolversUnionTypes> = { CCCUnion: ( CccFoo ) | ( CccBar ); }; `); @@ -1593,7 +1661,7 @@ export type ResolverFn = ( String: ResolverTypeWrapper; CCCBar: ResolverTypeWrapper; Query: ResolverTypeWrapper<{}>; - CCCUnion: ResolverTypeWrapper; + CCCUnion: ResolverTypeWrapper['CCCUnion']>; Boolean: ResolverTypeWrapper; }; `); @@ -1603,7 +1671,7 @@ export type ResolverFn = ( String: Scalars['String']; CCCBar: CccBar; Query: {}; - CCCUnion: ResolversUnionParentTypes['CCCUnion']; + CCCUnion: ResolversUnionTypes['CCCUnion']; Boolean: Scalars['Boolean']; }; `); @@ -1933,14 +2001,7 @@ export type ResolverFn = ( const content = await plugin(testSchema, [], {}, { outputFile: 'graphql.ts' }); expect(content.content).toBeSimilarStringTo(` - export type ResolversUnionTypes = { - UserPayload: ( UserResult ) | ( StandardError ); - PostsPayload: ( PostsResult ) | ( StandardError ); - }; - `); - - expect(content.content).toBeSimilarStringTo(` - export type ResolversUnionParentTypes = { + export type ResolversUnionTypes> = { UserPayload: ( UserResult ) | ( StandardError ); PostsPayload: ( PostsResult ) | ( StandardError ); }; @@ -1954,10 +2015,10 @@ export type ResolverFn = ( String: ResolverTypeWrapper; User: ResolverTypeWrapper; UserResult: ResolverTypeWrapper; - UserPayload: ResolverTypeWrapper; + UserPayload: ResolverTypeWrapper['UserPayload']>; Post: ResolverTypeWrapper; PostsResult: ResolverTypeWrapper; - PostsPayload: ResolverTypeWrapper; + PostsPayload: ResolverTypeWrapper['PostsPayload']>; Boolean: ResolverTypeWrapper; }; `); @@ -1970,10 +2031,10 @@ export type ResolverFn = ( String: Scalars['String']; User: User; UserResult: UserResult; - UserPayload: ResolversUnionParentTypes['UserPayload']; + UserPayload: ResolversUnionTypes['UserPayload']; Post: Post; PostsResult: PostsResult; - PostsPayload: ResolversUnionParentTypes['PostsPayload']; + PostsPayload: ResolversUnionTypes['PostsPayload']; Boolean: Scalars['Boolean']; }; `); @@ -1996,6 +2057,149 @@ export type ResolverFn = ( expect(content.content).not.toBeSimilarStringTo(`export type ResolversUnionParentTypes`); }); + it('should generate ResolversInterfaceTypes', async () => { + const content = await plugin(resolversTestingSchema, [], {}, { outputFile: 'graphql.ts' }); + + expect(content.content).toBeSimilarStringTo(` + export type ResolversInterfaceTypes> = { + Node: ( SomeNode ); + AnotherNode: ( Omit & { unionChild?: Maybe } ) | ( Omit & { unionChild?: Maybe, unionChildren: Array } ); + WithChild: ( Omit & { unionChild?: Maybe } ) | ( Omit & { unionChild?: Maybe, unionChildren: Array } ); + WithChildren: ( Omit & { unionChild?: Maybe, unionChildren: Array } ); + }; + `); + + expect(content.content).toBeSimilarStringTo(` + export type ResolversTypes = { + MyType: ResolverTypeWrapper & { unionChild?: Maybe }>; + String: ResolverTypeWrapper; + Child: ResolverTypeWrapper; + MyOtherType: ResolverTypeWrapper; + ChildUnion: ResolverTypeWrapper['ChildUnion']>; + Query: ResolverTypeWrapper<{}>; + Subscription: ResolverTypeWrapper<{}>; + Node: ResolverTypeWrapper['Node']>; + ID: ResolverTypeWrapper; + SomeNode: ResolverTypeWrapper; + AnotherNode: ResolverTypeWrapper['AnotherNode']>; + WithChild: ResolverTypeWrapper['WithChild']>; + WithChildren: ResolverTypeWrapper['WithChildren']>; + AnotherNodeWithChild: ResolverTypeWrapper & { unionChild?: Maybe }>; + AnotherNodeWithAll: ResolverTypeWrapper & { unionChild?: Maybe, unionChildren: Array }>; + MyUnion: ResolverTypeWrapper['MyUnion']>; + MyScalar: ResolverTypeWrapper; + Int: ResolverTypeWrapper; + Boolean: ResolverTypeWrapper; + }; + `); + + expect(content.content).toBeSimilarStringTo(` + export type ResolversParentTypes = { + MyType: Omit & { unionChild?: Maybe }; + String: Scalars['String']; + Child: Child; + MyOtherType: MyOtherType; + ChildUnion: ResolversUnionTypes['ChildUnion']; + Query: {}; + Subscription: {}; + Node: ResolversInterfaceTypes['Node']; + ID: Scalars['ID']; + SomeNode: SomeNode; + AnotherNode: ResolversInterfaceTypes['AnotherNode']; + WithChild: ResolversInterfaceTypes['WithChild']; + WithChildren: ResolversInterfaceTypes['WithChildren']; + AnotherNodeWithChild: Omit & { unionChild?: Maybe }; + AnotherNodeWithAll: Omit & { unionChild?: Maybe, unionChildren: Array }; + MyUnion: ResolversUnionTypes['MyUnion']; + MyScalar: Scalars['MyScalar']; + Int: Scalars['Int']; + Boolean: Scalars['Boolean']; + }; + `); + }); + + it('should generate ResolversInterfaceTypes with transformed type names correctly', async () => { + const content = await plugin( + resolversTestingSchema, + [], + { typesPrefix: 'I_', typesSuffix: '_Types' }, + { outputFile: 'graphql.ts' } + ); + + expect(content.content).toBeSimilarStringTo(` + export type I_ResolversInterfaceTypes_Types> = { + Node: ( I_SomeNode_Types ); + AnotherNode: ( Omit & { unionChild?: Maybe } ) | ( Omit & { unionChild?: Maybe, unionChildren: Array } ); + WithChild: ( Omit & { unionChild?: Maybe } ) | ( Omit & { unionChild?: Maybe, unionChildren: Array } ); + WithChildren: ( Omit & { unionChild?: Maybe, unionChildren: Array } ); + }; + `); + + expect(content.content).toBeSimilarStringTo(` + export type I_ResolversTypes_Types = { + MyType: ResolverTypeWrapper & { unionChild?: Maybe }>; + String: ResolverTypeWrapper; + Child: ResolverTypeWrapper; + MyOtherType: ResolverTypeWrapper; + ChildUnion: ResolverTypeWrapper['ChildUnion']>; + Query: ResolverTypeWrapper<{}>; + Subscription: ResolverTypeWrapper<{}>; + Node: ResolverTypeWrapper['Node']>; + ID: ResolverTypeWrapper; + SomeNode: ResolverTypeWrapper; + AnotherNode: ResolverTypeWrapper['AnotherNode']>; + WithChild: ResolverTypeWrapper['WithChild']>; + WithChildren: ResolverTypeWrapper['WithChildren']>; + AnotherNodeWithChild: ResolverTypeWrapper & { unionChild?: Maybe }>; + AnotherNodeWithAll: ResolverTypeWrapper & { unionChild?: Maybe, unionChildren: Array }>; + MyUnion: ResolverTypeWrapper['MyUnion']>; + MyScalar: ResolverTypeWrapper; + Int: ResolverTypeWrapper; + Boolean: ResolverTypeWrapper; + }; + `); + + expect(content.content).toBeSimilarStringTo(` + export type I_ResolversParentTypes_Types = { + MyType: Omit & { unionChild?: Maybe }; + String: Scalars['String']; + Child: I_Child_Types; + MyOtherType: I_MyOtherType_Types; + ChildUnion: I_ResolversUnionTypes_Types['ChildUnion']; + Query: {}; + Subscription: {}; + Node: I_ResolversInterfaceTypes_Types['Node']; + ID: Scalars['ID']; + SomeNode: I_SomeNode_Types; + AnotherNode: I_ResolversInterfaceTypes_Types['AnotherNode']; + WithChild: I_ResolversInterfaceTypes_Types['WithChild']; + WithChildren: I_ResolversInterfaceTypes_Types['WithChildren']; + AnotherNodeWithChild: Omit & { unionChild?: Maybe }; + AnotherNodeWithAll: Omit & { unionChild?: Maybe, unionChildren: Array }; + MyUnion: I_ResolversUnionTypes_Types['MyUnion']; + MyScalar: Scalars['MyScalar']; + Int: Scalars['Int']; + Boolean: Scalars['Boolean']; + }; + `); + }); + + it('should NOT generate ResolversInterfaceTypes if there is no Interface', async () => { + const testSchema = buildSchema(/* GraphQL */ ` + type Query { + user(id: ID!): User + } + + type User { + id: ID! + fullName: String! + } + `); + const content = await plugin(testSchema, [], {}, { outputFile: 'graphql.ts' }); + + expect(content.content).not.toBeSimilarStringTo(`export type ResolversInterfaceTypes`); + }); + it('should use correct value when rootValueType mapped as default', async () => { const testSchema = buildSchema(/* GraphQL */ ` type Subscription {