diff --git a/packages/plugins/other/visitor-plugin-common/src/base-documents-visitor.ts b/packages/plugins/other/visitor-plugin-common/src/base-documents-visitor.ts index ff4718a6a41..77045df5c9e 100644 --- a/packages/plugins/other/visitor-plugin-common/src/base-documents-visitor.ts +++ b/packages/plugins/other/visitor-plugin-common/src/base-documents-visitor.ts @@ -28,7 +28,6 @@ function getRootType(operation: OperationTypeNode, schema: GraphQLSchema) { } export interface ParsedDocumentsConfig extends ParsedTypesConfig { - preResolveTypes: boolean; extractAllFieldsToTypes: boolean; globalNamespace: boolean; operationResultSuffix: string; @@ -45,30 +44,6 @@ export interface ParsedDocumentsConfig extends ParsedTypesConfig { } export interface RawDocumentsConfig extends RawTypesConfig { - /** - * @default true - * @description Uses primitive types where possible. - * Set to `false` in order to use `Pick` and take use the types generated by `typescript` plugin. - * - * @exampleMarkdown - * ```ts filename="codegen.ts" - * import type { CodegenConfig } from '@graphql-codegen/cli'; - * - * const config: CodegenConfig = { - * // ... - * generates: { - * 'path/to/file': { - * // plugins... - * config: { - * preResolveTypes: false - * }, - * }, - * }, - * }; - * export default config; - * ``` - */ - preResolveTypes?: boolean; /** * @default false * @description Avoid adding `__typename` for root types. This is ignored when a selection explicitly specifies `__typename`. @@ -245,7 +220,6 @@ export class BaseDocumentsVisitor< exportFragmentSpreadSubTypes: getConfigValue(rawConfig.exportFragmentSpreadSubTypes, false), enumPrefix: getConfigValue(rawConfig.enumPrefix, true), enumSuffix: getConfigValue(rawConfig.enumSuffix, true), - preResolveTypes: getConfigValue(rawConfig.preResolveTypes, true), dedupeOperationSuffix: getConfigValue(rawConfig.dedupeOperationSuffix, false), omitOperationSuffix: getConfigValue(rawConfig.omitOperationSuffix, false), skipTypeNameForRoot: getConfigValue(rawConfig.skipTypeNameForRoot, false), diff --git a/packages/plugins/typescript/operations/src/ts-selection-set-processor.ts b/packages/plugins/typescript/operations/src/ts-selection-set-processor.ts deleted file mode 100644 index e46c326ba20..00000000000 --- a/packages/plugins/typescript/operations/src/ts-selection-set-processor.ts +++ /dev/null @@ -1,103 +0,0 @@ -import { - BaseSelectionSetProcessor, - LinkField, - PrimitiveAliasedFields, - PrimitiveField, - ProcessResult, - SelectionSetProcessorConfig, -} from '@graphql-codegen/visitor-plugin-common'; -import { GraphQLInterfaceType, GraphQLObjectType } from 'graphql'; - -export class TypeScriptSelectionSetProcessor extends BaseSelectionSetProcessor { - transformPrimitiveFields( - schemaType: GraphQLObjectType | GraphQLInterfaceType, - fields: PrimitiveField[], - unsetTypes?: boolean - ): ProcessResult { - if (fields.length === 0) { - return []; - } - - const parentName = - (this.config.namespacedImportName ? `${this.config.namespacedImportName}.` : '') + - this.config.convertName(schemaType.name, { - useTypesPrefix: true, - }); - - if (unsetTypes) { - const escapedFieldNames = fields.map(field => `'${field.fieldName}'`); - return [formattedUnionTransform('MakeEmpty', parentName, escapedFieldNames)]; - } - - let hasConditionals = false; - const escapedConditionalsList: string[] = []; - const escapedFieldNames = fields.map(field => { - if (field.isConditional) { - hasConditionals = true; - escapedConditionalsList.push(`'${field.fieldName}'`); - } - return `'${field.fieldName}'`; - }); - let resString = formattedUnionTransform('Pick', parentName, escapedFieldNames); - - if (hasConditionals) { - resString = `${ - this.config.namespacedImportName ? `${this.config.namespacedImportName}.` : '' - }${formattedUnionTransform('MakeOptional', resString, escapedConditionalsList)}`; - } - return [resString]; - } - - transformTypenameField(type: string, name: string): ProcessResult { - return [`{ ${name}: ${type} }`]; - } - - transformAliasesPrimitiveFields( - schemaType: GraphQLObjectType | GraphQLInterfaceType, - fields: PrimitiveAliasedFields[] - ): ProcessResult { - if (fields.length === 0) { - return []; - } - - const parentName = - (this.config.namespacedImportName ? `${this.config.namespacedImportName}.` : '') + - this.config.convertName(schemaType.name, { - useTypesPrefix: true, - }); - - const selections = fields.map(aliasedField => { - const value = - aliasedField.fieldName === '__typename' ? `'${schemaType.name}'` : `${parentName}['${aliasedField.fieldName}']`; - - return `${aliasedField.alias}: ${value}`; - }); - return [formatSelections(selections)]; - } - - transformLinkFields(fields: LinkField[]): ProcessResult { - if (fields.length === 0) { - return []; - } - - const selections = fields.map(field => `${field.alias || field.name}: ${field.selectionSet}`); - - return [formatSelections(selections)]; - } -} - -/** Equivalent to `${transformName}<${target}, ${unionElements.join(' | ')}>`, but with line feeds if necessary */ -function formattedUnionTransform(transformName: string, target: string, unionElements: string[]): string { - if (unionElements.length > 3) { - return `${transformName}<\n ${target},\n | ${unionElements.join('\n | ')}\n >`; - } - return `${transformName}<${target}, ${unionElements.join(' | ')}>`; -} - -/** Equivalent to `{ ${selections.join(', ')} }`, but with line feeds if necessary */ -function formatSelections(selections: string[]): string { - if (selections.length > 1) { - return `{\n ${selections.map(s => s.replace(/\n/g, '\n ')).join(',\n ')},\n }`; - } - return `{ ${selections.join(', ')} }`; -} diff --git a/packages/plugins/typescript/operations/src/visitor.ts b/packages/plugins/typescript/operations/src/visitor.ts index 81d92421a46..f7ca9946591 100644 --- a/packages/plugins/typescript/operations/src/visitor.ts +++ b/packages/plugins/typescript/operations/src/visitor.ts @@ -46,7 +46,6 @@ import { } from 'graphql'; import { TypeScriptDocumentsPluginConfig } from './config.js'; import { TypeScriptOperationVariablesToObject, SCALARS } from './ts-operation-variables-to-object.js'; -import { TypeScriptSelectionSetProcessor } from './ts-selection-set-processor.js'; export interface TypeScriptDocumentsParsedConfig extends ParsedDocumentsConfig { arrayInputCoercion: boolean; @@ -88,7 +87,6 @@ export class TypeScriptDocumentsVisitor extends BaseDocumentsVisitor< avoidOptionals: normalizeAvoidOptionals(getConfigValue(config.avoidOptionals, false)), immutableTypes: getConfigValue(config.immutableTypes, false), nonOptionalTypename: getConfigValue(config.nonOptionalTypename, false), - preResolveTypes: getConfigValue(config.preResolveTypes, true), mergeFragmentTypes: getConfigValue(config.mergeFragmentTypes, false), allowUndefinedQueryVariables: getConfigValue(config.allowUndefinedQueryVariables, false), enumType: getConfigValue(config.enumType, 'string-literal'), @@ -105,22 +103,9 @@ export class TypeScriptDocumentsVisitor extends BaseDocumentsVisitor< this._outputPath = outputPath; autoBind(this); - const preResolveTypes = getConfigValue(config.preResolveTypes, true); const defaultMaybeValue = 'T | null'; const maybeValue = getConfigValue(config.maybeValue, defaultMaybeValue); - const wrapOptional = (type: string) => { - if (preResolveTypes === true) { - return maybeValue.replace('T', type); - } - const prefix = this.config.namespacedImportName ? `${this.config.namespacedImportName}.` : ''; - return `${prefix}Maybe<${type}>`; - }; - const wrapArray = (type: string) => { - const listModifier = this.config.immutableTypes ? 'ReadonlyArray' : 'Array'; - return `${listModifier}<${type}>`; - }; - const allFragments: LoadedFragment[] = [ ...(documentNode.definitions.filter(d => d.kind === Kind.FRAGMENT_DEFINITION) as FragmentDefinitionNode[]).map( fragmentDef => ({ @@ -144,14 +129,18 @@ export class TypeScriptDocumentsVisitor extends BaseDocumentsVisitor< formatNamedField: ({ name, isOptional }) => { return (this.config.immutableTypes ? `readonly ${name}` : name) + (isOptional ? '?' : ''); }, - wrapTypeWithModifiers(baseType, type) { - return wrapTypeWithModifiers(baseType, type, { wrapOptional, wrapArray }); + wrapTypeWithModifiers: (baseType, type) => { + return wrapTypeWithModifiers(baseType, type, { + wrapOptional: type => maybeValue.replace('T', type), + wrapArray: type => { + const listModifier = this.config.immutableTypes ? 'ReadonlyArray' : 'Array'; + return `${listModifier}<${type}>`; + }, + }); }, printFieldsOnNewLines: this.config.printFieldsOnNewLines, }; - const processor = new (preResolveTypes ? PreResolveTypesProcessor : TypeScriptSelectionSetProcessor)( - processorConfig - ); + const processor = new PreResolveTypesProcessor(processorConfig); this.setSelectionSetHandler( new SelectionSetToObject( processor, diff --git a/packages/plugins/typescript/operations/tests/__snapshots__/ts-documents.spec.ts.snap b/packages/plugins/typescript/operations/tests/__snapshots__/ts-documents.spec.ts.snap index 210cac2e1a8..760b49909be 100644 --- a/packages/plugins/typescript/operations/tests/__snapshots__/ts-documents.spec.ts.snap +++ b/packages/plugins/typescript/operations/tests/__snapshots__/ts-documents.spec.ts.snap @@ -56,7 +56,7 @@ export type ElementMetadataFragment = " `; -exports[`TypeScript Operations Plugin > Issues > #2916 - Missing import prefix with preResolveTypes: true and near-operation-file preset 1`] = ` +exports[`TypeScript Operations Plugin > Issues > #2916 - Missing import prefix with near-operation-file preset 1`] = ` "export type Department = | 'Direction' | 'Development'; @@ -81,23 +81,6 @@ export type VenueFragment = export type QQueryVariables = Exact<{ [key: string]: never; }>; -export type QQuery = { hotel: { id: string, gpsPosition: { lat: number, lng: number } }, transport: { id: string } }; -" -`; - -exports[`TypeScript Operations Plugin > Issues > #3064 - fragments over interfaces causes issues with fields 2`] = ` -"type Venue_Hotel_Fragment = { id: string, gpsPosition: { lat: number, lng: number } }; - -type Venue_Transport_Fragment = { id: string }; - -export type VenueFragment = - | Venue_Hotel_Fragment - | Venue_Transport_Fragment -; - -export type QQueryVariables = Exact<{ [key: string]: never; }>; - - export type QQuery = { hotel: { id: string, gpsPosition: { lat: number, lng: number } }, transport: { id: string } }; function test(q: QQuery) { if (q.hotel) { @@ -110,7 +93,7 @@ function test(q: QQuery) { }" `; -exports[`TypeScript Operations Plugin > Issues > #6874 - generates types when parent type differs from spread fragment member types and preResolveTypes=true 1`] = ` +exports[`TypeScript Operations Plugin > Issues > #6874 - generates types when parent type differs from spread fragment member types 1`] = ` "export type SnakeQueryQueryVariables = Exact<{ [key: string]: never; }>; @@ -130,24 +113,13 @@ export type AnimalFragmentFragment = " `; -exports[`TypeScript Operations Plugin > Issues > #8793 selecting __typename should not be optional 1`] = ` -"export type SnakeQueryQueryVariables = Exact<{ [key: string]: never; }>; - - -export type SnakeQueryQuery = { __typename: 'Query', snake: - | { __typename: 'Snake' } - | { __typename: 'Error' } - }; -" -`; - exports[`TypeScript Operations Plugin > Selection Set > Should generate the correct __typename when using both inline fragment and spread over type 1`] = ` "export type UserQueryQueryVariables = Exact<{ [key: string]: never; }>; -export type UserQueryQuery = { user: Maybe> }; +export type UserQueryQuery = { user: { id: string, name: string | null } | null }; -export type UserFragment = Pick; +export type UserFragment = { id: string, name: string | null }; " `; @@ -155,7 +127,7 @@ exports[`TypeScript Operations Plugin > Selection Set > Should generate the corr "export type UserQueryQueryVariables = Exact<{ [key: string]: never; }>; -export type UserQueryQuery = { user: Maybe> }; +export type UserQueryQuery = { user: { id: string, name: string | null } | null }; " `; @@ -163,56 +135,29 @@ exports[`TypeScript Operations Plugin > Selection Set > Should generate the corr "export type UserQueryQueryVariables = Exact<{ [key: string]: never; }>; -export type UserQueryQuery = { user: Maybe> }; +export type UserQueryQuery = { user: { id: string, name: string | null } | null }; -export type UserFragment = Pick; +export type UserFragment = { id: string, name: string | null }; " `; exports[`TypeScript Operations Plugin > Selection Set > Should generate the correct __typename when using fragment spread over union 1`] = ` -"export type UserFragmentFragment = Pick; +"export type UserFragmentFragment = { id: string }; export type AaaQueryVariables = Exact<{ [key: string]: never; }>; export type AaaQuery = { user: - | Pick + | { id: string } | Record }; " `; -exports[`TypeScript Operations Plugin > Selection Set > Should generate the correct intersection for fragments when using with interfaces with same type 2`] = ` -"export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>; - - -export type Unnamed_1_Query = { b: Maybe< - | Pick - | Record - > }; - -export type AFragment = Pick; - -export type BFragment = Pick; -" -`; - exports[`TypeScript Operations Plugin > Selection Set > Should have valid __typename usage and split types according to that (with usage) 1`] = ` -"type NetRoute_Ipv4Route_Fragment = ( - { __typename: 'IPV4Route' } - & { - ipv4Address: Ipv4Route['address'], - ipv4Gateway: Ipv4Route['gateway'], - } -); - -type NetRoute_Ipv6Route_Fragment = ( - { __typename: 'IPV6Route' } - & { - ipv6Address: Ipv6Route['address'], - ipv6Gateway: Ipv6Route['gateway'], - } -); +"type NetRoute_Ipv4Route_Fragment = { __typename: 'IPV4Route', ipv4Address: any | null, ipv4Gateway: any | null }; + +type NetRoute_Ipv6Route_Fragment = { __typename: 'IPV6Route', ipv6Address: any | null, ipv6Gateway: any | null }; export type NetRouteFragment = | NetRoute_Ipv4Route_Fragment @@ -223,81 +168,42 @@ export type QqQueryVariables = Exact<{ [key: string]: never; }>; export type QqQuery = { routes: Array< - | ( - { __typename: 'IPV4Route' } - & { - ipv4Address: Ipv4Route['address'], - ipv4Gateway: Ipv4Route['gateway'], - } - ) - | ( - { __typename: 'IPV6Route' } - & { - ipv6Address: Ipv6Route['address'], - ipv6Gateway: Ipv6Route['gateway'], - } - ) + | { __typename: 'IPV4Route', ipv4Address: any | null, ipv4Gateway: any | null } + | { __typename: 'IPV6Route', ipv6Address: any | null, ipv6Gateway: any | null } > }; " `; exports[`TypeScript Operations Plugin > Selection Set > Should have valid __typename usage and split types according to that (with usage) 2`] = ` -"type NetRoute_Ipv4Route_Fragment = ( - { __typename: 'IPV4Route' } - & { - ipv4Address: Ipv4Route['address'], - ipv4Gateway: Ipv4Route['gateway'], - } -); - -type NetRoute_Ipv6Route_Fragment = ( - { __typename: 'IPV6Route' } - & { - ipv6Address: Ipv6Route['address'], - ipv6Gateway: Ipv6Route['gateway'], - } -); +"type NetRoute_Ipv4Route_Fragment = { __typename: 'IPV4Route', ipv4Address: any | null, ipv4Gateway: any | null }; + +type NetRoute_Ipv6Route_Fragment = { __typename: 'IPV6Route', ipv6Address: any | null, ipv6Gateway: any | null }; export type NetRouteFragment = | NetRoute_Ipv4Route_Fragment | NetRoute_Ipv6Route_Fragment ; -export type TestFragment = { - ipv6Address: Ipv6Route['address'], - ipv6Gateway: Ipv6Route['gateway'], - }; +export type TestFragment = { ipv6Address: any | null, ipv6Gateway: any | null }; export type QqQueryVariables = Exact<{ [key: string]: never; }>; export type QqQuery = { routes: Array< - | ( - { __typename: 'IPV4Route' } - & { - ipv4Address: Ipv4Route['address'], - ipv4Gateway: Ipv4Route['gateway'], - } - ) - | ( - { __typename: 'IPV6Route' } - & { - ipv6Address: Ipv6Route['address'], - ipv6Gateway: Ipv6Route['gateway'], - } - ) + | { __typename: 'IPV4Route', ipv4Address: any | null, ipv4Gateway: any | null } + | { __typename: 'IPV6Route', ipv6Address: any | null, ipv6Gateway: any | null } > }; " `; exports[`TypeScript Operations Plugin > Selection Set > Should have valid fragments intersection on different types (with usage) #2498 1`] = ` -"export type TomFragment = Pick; +"export type TomFragment = { id: string, foo: string }; -export type JerryFragment = Pick; +export type JerryFragment = { id: string, bar: string }; -type User_Tom_Fragment = Pick; +type User_Tom_Fragment = { id: string, foo: string }; -type User_Jerry_Fragment = Pick; +type User_Jerry_Fragment = { id: string, bar: string }; export type UserFragment = | User_Tom_Fragment @@ -307,128 +213,9 @@ export type UserFragment = export type UserQueryQueryVariables = Exact<{ [key: string]: never; }>; -export type UserQueryQuery = { user: Maybe< - | Pick - | Pick - > }; -" -`; - -exports[`TypeScript Operations Plugin > Union & Interfaces > #4216 - handle fragments against unions and interfaces with flattenGeneratedTypes 1`] = ` -"export type SearchPopularQueryVariables = Exact<{ [key: string]: never; }>; - - -export type SearchPopularQuery = { search: Maybe - | ( - Pick - & { dimension: Maybe> } - ) - >> }; -" -`; - -exports[`TypeScript Operations Plugin > Union & Interfaces > Should handle union selection sets with both FragmentSpreads and InlineFragments 1`] = ` -"export type UserQueryQueryVariables = Exact<{ [key: string]: never; }>; - - export type UserQueryQuery = { user: - | Pick - | Pick - | ( - Pick - & { info: Maybe> } - ) - }; - -export type AdditionalInfoFragment = Pick; - -type UserResult1_User_Fragment = Pick; - -type UserResult1_Error3_Fragment = { info: Maybe> }; - -export type UserResult1Fragment = - | UserResult1_User_Fragment - | UserResult1_Error3_Fragment -; - -type UserResult_User_Fragment = Pick; - -type UserResult_Error2_Fragment = Pick; - -export type UserResultFragment = - | UserResult_User_Fragment - | UserResult_Error2_Fragment -; + | { id: string, foo: string } + | { id: string, bar: string } + | null }; " `; - -exports[`TypeScript Operations Plugin > Union & Interfaces > Should handle union selection sets with both FragmentSpreads and InlineFragments with flattenGeneratedTypes 1`] = ` -"export type UserQueryQueryVariables = Exact<{ [key: string]: never; }>; - - -export type UserQueryQuery = { user: - | Pick - | Pick - | ( - Pick - & { info: Maybe> } - ) - }; - - function t(q: UserQueryQuery) { - if (q.user) { - if (q.user.__typename === 'User') { - if (q.user.id) { - const u = q.user.login; - } - } - if (q.user.__typename === 'Error2') { - console.log(q.user.message); - } - if (q.user.__typename === 'Error3') { - if (q.user.info) { - console.log(q.user.info.__typename) - } - } - } - }" -`; - -exports[`TypeScript Operations Plugin > Union & Interfaces > Should handle union selection sets with both FragmentSpreads and InlineFragments with flattenGeneratedTypes and directives 1`] = ` -"export type UserQueryQueryVariables = Exact<{ [key: string]: never; }>; - - -export type UserQueryQuery = { user: - | Pick< - User, - | 'id' - | 'test2' - | 'login' - | 'test' - > - | Pick - | ( - Pick - & { info: Maybe> } - ) - }; - - function t(q: UserQueryQuery) { - if (q.user) { - if (q.user.__typename === 'User') { - if (q.user.id) { - const u = q.user.login; - } - } - if (q.user.__typename === 'Error2') { - console.log(q.user.message); - } - if (q.user.__typename === 'Error3') { - if (q.user.info) { - console.log(q.user.info.__typename) - } - } - } - }" -`; diff --git a/packages/plugins/typescript/operations/tests/extract-all-types.spec.ts b/packages/plugins/typescript/operations/tests/extract-all-types.spec.ts index 7c8f107aa11..bf09922b3f2 100644 --- a/packages/plugins/typescript/operations/tests/extract-all-types.spec.ts +++ b/packages/plugins/typescript/operations/tests/extract-all-types.spec.ts @@ -70,7 +70,6 @@ describe('extractAllFieldsToTypes: true', () => { it('should extract types from queries', async () => { const config: TypeScriptDocumentsPluginConfig = { - preResolveTypes: true, extractAllFieldsToTypes: true, printFieldsOnNewLines: true, nonOptionalTypename: true, @@ -389,7 +388,6 @@ describe('extractAllFieldsToTypes: true', () => { it('should extract types from multiple fragments', async () => { const config: TypeScriptDocumentsPluginConfig = { - preResolveTypes: true, extractAllFieldsToTypes: true, nonOptionalTypename: true, dedupeOperationSuffix: true, @@ -558,7 +556,6 @@ describe('extractAllFieldsToTypes: true', () => { it('should extract types from multiple fragments (mergeFragmentTypes: true)', async () => { const config: TypeScriptDocumentsPluginConfig = { - preResolveTypes: true, extractAllFieldsToTypes: true, nonOptionalTypename: true, dedupeOperationSuffix: true, @@ -733,7 +730,6 @@ describe('extractAllFieldsToTypes: true', () => { it("should extract types from multiple fragments (inlineFragmentTypes: 'combine')", async () => { const config: TypeScriptDocumentsPluginConfig = { - preResolveTypes: true, extractAllFieldsToTypes: true, nonOptionalTypename: true, dedupeOperationSuffix: true, @@ -977,7 +973,6 @@ describe('extractAllFieldsToTypes: true', () => { it("should extract types from multiple fragments (inlineFragmentTypes: 'mask')", async () => { const config: TypeScriptDocumentsPluginConfig = { - preResolveTypes: true, extractAllFieldsToTypes: true, nonOptionalTypename: true, dedupeOperationSuffix: true, @@ -1216,280 +1211,4 @@ describe('extractAllFieldsToTypes: true', () => { await validate(content, config, complexTestSchemaWithUnionsAndInterfaces); }); - - it('should extract types from multiple fragments (preResolveTypes: false)', async () => { - const config: TypeScriptDocumentsPluginConfig = { - preResolveTypes: false, - extractAllFieldsToTypes: true, - nonOptionalTypename: true, - dedupeOperationSuffix: true, - }; - const { content } = await plugin( - complexTestSchemaWithUnionsAndInterfaces, - [{ location: 'test-file.ts', document: fragmentsOnComplexSchema }], - config, - { outputFile: '' } - ); - expect(content).toMatchInlineSnapshot(` - "export type CallType = - | 'OUTGOING' - | 'INCOMING' - | 'VOICEMAIL' - | 'UNKNOWN'; - - export type ConversationBotSolutionFragment_BotSolution_article_ArchivedArticle = ( - { __typename: 'ArchivedArticle' } - & Pick< - ArchivedArticle, - | 'id' - | 'htmlUrl' - | 'title' - | 'url' - > - ); - - export type ConversationBotSolutionFragment_BotSolution_originatedFrom_EmailInteraction = ( - { __typename: 'EmailInteraction' } - & Pick - ); - - export type ConversationBotSolutionFragment_BotSolution_originatedFrom_CustomChannelInteraction = ( - { __typename: 'CustomChannelInteraction' } - & Pick - ); - - export type ConversationBotSolutionFragment_BotSolution_originatedFrom_TalkInteraction = { __typename: 'TalkInteraction' }; - - export type ConversationBotSolutionFragment_BotSolution_originatedFrom_NativeMessagingInteraction = ( - { __typename: 'NativeMessagingInteraction' } - & Pick - ); - - export type ConversationBotSolutionFragment_BotSolution_originatedFrom_WhatsAppInteraction = ( - { __typename: 'WhatsAppInteraction' } - & Pick - ); - - export type ConversationBotSolutionFragment_BotSolution_originatedFrom_WeChatInteraction = ( - { __typename: 'WeChatInteraction' } - & Pick - ); - - export type ConversationBotSolutionFragment_BotSolution_originatedFrom_NotImplementedOriginatedFrom = { __typename: 'NotImplementedOriginatedFrom' }; - - export type ConversationBotSolutionFragment_BotSolution_originatedFrom = - | ConversationBotSolutionFragment_BotSolution_originatedFrom_EmailInteraction - | ConversationBotSolutionFragment_BotSolution_originatedFrom_CustomChannelInteraction - | ConversationBotSolutionFragment_BotSolution_originatedFrom_TalkInteraction - | ConversationBotSolutionFragment_BotSolution_originatedFrom_NativeMessagingInteraction - | ConversationBotSolutionFragment_BotSolution_originatedFrom_WhatsAppInteraction - | ConversationBotSolutionFragment_BotSolution_originatedFrom_WeChatInteraction - | ConversationBotSolutionFragment_BotSolution_originatedFrom_NotImplementedOriginatedFrom - ; - - export type ConversationBotSolutionFragment = ( - { __typename: 'BotSolution' } - & Pick - & { - article: ConversationBotSolutionFragment_BotSolution_article_ArchivedArticle, - originatedFrom: ConversationBotSolutionFragment_BotSolution_originatedFrom, - } - ); - - export type ConversationGenericCallSummaryFragment = ( - { __typename: 'TalkPublicCallSummary' } - & Pick - ); - - export type ConversationTalkInteractionFragment = ( - { __typename: 'TalkInteraction' } - & Pick - ); - - export type ConversationConversationEventFragment_BrokenConversationEvent_originatedFrom_EmailInteraction = ( - { __typename: 'EmailInteraction' } - & Pick - ); - - export type ConversationConversationEventFragment_BrokenConversationEvent_originatedFrom_CustomChannelInteraction = ( - { __typename: 'CustomChannelInteraction' } - & Pick - ); - - export type ConversationConversationEventFragment_BrokenConversationEvent_originatedFrom_TalkInteraction = { __typename: 'TalkInteraction' }; - - export type ConversationConversationEventFragment_BrokenConversationEvent_originatedFrom_NativeMessagingInteraction = ( - { __typename: 'NativeMessagingInteraction' } - & Pick - ); - - export type ConversationConversationEventFragment_BrokenConversationEvent_originatedFrom_WhatsAppInteraction = ( - { __typename: 'WhatsAppInteraction' } - & Pick - ); - - export type ConversationConversationEventFragment_BrokenConversationEvent_originatedFrom_WeChatInteraction = ( - { __typename: 'WeChatInteraction' } - & Pick - ); - - export type ConversationConversationEventFragment_BrokenConversationEvent_originatedFrom_NotImplementedOriginatedFrom = { __typename: 'NotImplementedOriginatedFrom' }; - - export type ConversationConversationEventFragment_BrokenConversationEvent_originatedFrom = - | ConversationConversationEventFragment_BrokenConversationEvent_originatedFrom_EmailInteraction - | ConversationConversationEventFragment_BrokenConversationEvent_originatedFrom_CustomChannelInteraction - | ConversationConversationEventFragment_BrokenConversationEvent_originatedFrom_TalkInteraction - | ConversationConversationEventFragment_BrokenConversationEvent_originatedFrom_NativeMessagingInteraction - | ConversationConversationEventFragment_BrokenConversationEvent_originatedFrom_WhatsAppInteraction - | ConversationConversationEventFragment_BrokenConversationEvent_originatedFrom_WeChatInteraction - | ConversationConversationEventFragment_BrokenConversationEvent_originatedFrom_NotImplementedOriginatedFrom - ; - - type ConversationConversationEvent_BrokenConversationEvent_Fragment = ( - { __typename: 'BrokenConversationEvent' } - & Pick - & { originatedFrom: ConversationConversationEventFragment_BrokenConversationEvent_originatedFrom } - ); - - type ConversationConversationEvent_BotSolution_Fragment = ( - { __typename: 'BotSolution' } - & Pick - & { originatedFrom: ConversationConversationEventFragment_BrokenConversationEvent_originatedFrom } - ); - - type ConversationConversationEvent_TalkPublicCallSummary_Fragment = ( - { __typename: 'TalkPublicCallSummary' } - & Pick - & { originatedFrom: ConversationConversationEventFragment_BrokenConversationEvent_originatedFrom } - ); - - export type ConversationConversationEventFragment = - | ConversationConversationEvent_BrokenConversationEvent_Fragment - | ConversationConversationEvent_BotSolution_Fragment - | ConversationConversationEvent_TalkPublicCallSummary_Fragment - ; - - type MessageEnvelopeData_EmailInteraction_Fragment = ( - { __typename: 'EmailInteraction' } - & Pick - ); - - type MessageEnvelopeData_CustomChannelInteraction_Fragment = { __typename: 'CustomChannelInteraction' }; - - type MessageEnvelopeData_TalkInteraction_Fragment = { __typename: 'TalkInteraction' }; - - type MessageEnvelopeData_NativeMessagingInteraction_Fragment = { __typename: 'NativeMessagingInteraction' }; - - type MessageEnvelopeData_WhatsAppInteraction_Fragment = { __typename: 'WhatsAppInteraction' }; - - type MessageEnvelopeData_WeChatInteraction_Fragment = { __typename: 'WeChatInteraction' }; - - type MessageEnvelopeData_NotImplementedOriginatedFrom_Fragment = { __typename: 'NotImplementedOriginatedFrom' }; - - export type MessageEnvelopeDataFragment = - | MessageEnvelopeData_EmailInteraction_Fragment - | MessageEnvelopeData_CustomChannelInteraction_Fragment - | MessageEnvelopeData_TalkInteraction_Fragment - | MessageEnvelopeData_NativeMessagingInteraction_Fragment - | MessageEnvelopeData_WhatsAppInteraction_Fragment - | MessageEnvelopeData_WeChatInteraction_Fragment - | MessageEnvelopeData_NotImplementedOriginatedFrom_Fragment - ; - - export type AnyChannelOriginatedFromFragment = ( - { __typename: 'CustomChannelInteraction' } - & Pick - ); - - type ConversationOriginatedFrom_EmailInteraction_Fragment = ( - { __typename: 'EmailInteraction' } - & Pick - ); - - type ConversationOriginatedFrom_CustomChannelInteraction_Fragment = ( - { __typename: 'CustomChannelInteraction' } - & Pick - ); - - type ConversationOriginatedFrom_TalkInteraction_Fragment = { __typename: 'TalkInteraction' }; - - type ConversationOriginatedFrom_NativeMessagingInteraction_Fragment = ( - { __typename: 'NativeMessagingInteraction' } - & Pick - ); - - type ConversationOriginatedFrom_WhatsAppInteraction_Fragment = ( - { __typename: 'WhatsAppInteraction' } - & Pick - ); - - type ConversationOriginatedFrom_WeChatInteraction_Fragment = ( - { __typename: 'WeChatInteraction' } - & Pick - ); - - type ConversationOriginatedFrom_NotImplementedOriginatedFrom_Fragment = { __typename: 'NotImplementedOriginatedFrom' }; - - export type ConversationOriginatedFromFragment = - | ConversationOriginatedFrom_EmailInteraction_Fragment - | ConversationOriginatedFrom_CustomChannelInteraction_Fragment - | ConversationOriginatedFrom_TalkInteraction_Fragment - | ConversationOriginatedFrom_NativeMessagingInteraction_Fragment - | ConversationOriginatedFrom_WhatsAppInteraction_Fragment - | ConversationOriginatedFrom_WeChatInteraction_Fragment - | ConversationOriginatedFrom_NotImplementedOriginatedFrom_Fragment - ; - - export type ConversationTalkPublicCallSummaryFragment_TalkPublicCallSummary_originatedFrom_EmailInteraction = ( - { __typename: 'EmailInteraction' } - & Pick - ); - - export type ConversationTalkPublicCallSummaryFragment_TalkPublicCallSummary_originatedFrom_CustomChannelInteraction = ( - { __typename: 'CustomChannelInteraction' } - & Pick - ); - - export type ConversationTalkPublicCallSummaryFragment_TalkPublicCallSummary_originatedFrom_TalkInteraction = ( - { __typename: 'TalkInteraction' } - & Pick - ); - - export type ConversationTalkPublicCallSummaryFragment_TalkPublicCallSummary_originatedFrom_NativeMessagingInteraction = ( - { __typename: 'NativeMessagingInteraction' } - & Pick - ); - - export type ConversationTalkPublicCallSummaryFragment_TalkPublicCallSummary_originatedFrom_WhatsAppInteraction = ( - { __typename: 'WhatsAppInteraction' } - & Pick - ); - - export type ConversationTalkPublicCallSummaryFragment_TalkPublicCallSummary_originatedFrom_WeChatInteraction = ( - { __typename: 'WeChatInteraction' } - & Pick - ); - - export type ConversationTalkPublicCallSummaryFragment_TalkPublicCallSummary_originatedFrom_NotImplementedOriginatedFrom = { __typename: 'NotImplementedOriginatedFrom' }; - - export type ConversationTalkPublicCallSummaryFragment_TalkPublicCallSummary_originatedFrom = - | ConversationTalkPublicCallSummaryFragment_TalkPublicCallSummary_originatedFrom_EmailInteraction - | ConversationTalkPublicCallSummaryFragment_TalkPublicCallSummary_originatedFrom_CustomChannelInteraction - | ConversationTalkPublicCallSummaryFragment_TalkPublicCallSummary_originatedFrom_TalkInteraction - | ConversationTalkPublicCallSummaryFragment_TalkPublicCallSummary_originatedFrom_NativeMessagingInteraction - | ConversationTalkPublicCallSummaryFragment_TalkPublicCallSummary_originatedFrom_WhatsAppInteraction - | ConversationTalkPublicCallSummaryFragment_TalkPublicCallSummary_originatedFrom_WeChatInteraction - | ConversationTalkPublicCallSummaryFragment_TalkPublicCallSummary_originatedFrom_NotImplementedOriginatedFrom - ; - - export type ConversationTalkPublicCallSummaryFragment = ( - { __typename: 'TalkPublicCallSummary' } - & Pick - & { originatedFrom: ConversationTalkPublicCallSummaryFragment_TalkPublicCallSummary_originatedFrom } - ); - " - `); - - await validate(content, config, complexTestSchemaWithUnionsAndInterfaces); - }); }); diff --git a/packages/plugins/typescript/operations/tests/ts-documents.spec.ts b/packages/plugins/typescript/operations/tests/ts-documents.spec.ts index 22d88537e12..3976a631b8c 100644 --- a/packages/plugins/typescript/operations/tests/ts-documents.spec.ts +++ b/packages/plugins/typescript/operations/tests/ts-documents.spec.ts @@ -34,63 +34,17 @@ describe('TypeScript Operations Plugin', () => { } } `); - const config = { noExport: true, preResolveTypes: false }; - const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + const { content } = await plugin( + schema, + [{ location: 'test-file.ts', document: ast }], + { noExport: true }, + { outputFile: '' } + ); expect(content).not.toContain('export'); await validate(content); }); - it('Should handle "namespacedImportName" and add it when specified', async () => { - const ast = parse(/* GraphQL */ ` - query notifications { - notifications { - id - - ... on TextNotification { - text - textAlias: text - } - - ... on TextNotification { - text - } - - ... on ImageNotification { - imageUrl - metadata { - created: createdBy - } - } - } - } - `); - const config = { preResolveTypes: false, namespacedImportName: 'Types' }; - const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); - - expect(content).toMatchInlineSnapshot(` - "export type NotificationsQueryVariables = Exact<{ [key: string]: never; }>; - - - export type NotificationsQuery = { notifications: Array< - | ( - Pick - & { textAlias: Types.TextNotification['text'] } - ) - | ( - Pick - & { metadata: { created: Types.ImageMetadata['createdBy'] } } - ) - > }; - " - `); - await validate(content, '', [`Cannot find namespace 'Types'.`]); - }); - it('Can merge an inline fragment with a spread', async () => { const testSchema = buildSchema(/* GraphQL */ ` interface Comment { @@ -138,9 +92,7 @@ describe('TypeScript Operations Plugin', () => { testSchema, [{ location: 'test-file.ts', document: ast }], {}, - { - outputFile: '', - } + { outputFile: '' } ); expect(content).toMatchInlineSnapshot(` "export type PostFragment = { id: string, comments: Array< @@ -156,58 +108,6 @@ describe('TypeScript Operations Plugin', () => { `); }); - it('Should handle "namespacedImportName" and "preResolveTypes" together', async () => { - const testSchema = buildSchema(/* GraphQL */ ` - type Query { - f: E - user: User! - } - - enum E { - A - B - } - - scalar JSON - - type User { - id: ID! - f: E - j: JSON - } - `); - const ast = parse(/* GraphQL */ ` - query test { - f - user { - id - f - j - } - } - `); - const config = { namespacedImportName: 'Types', preResolveTypes: true }; - const { content } = await plugin(testSchema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); - - expect(content).toMatchInlineSnapshot( - ` - "export type E = - | 'A' - | 'B'; - - export type TestQueryVariables = Exact<{ [key: string]: never; }>; - - - export type TestQuery = { f: Types.E | null, user: { id: string, f: Types.E | null, j: any | null } }; - " - ` - ); - - await validate(content, '', [`Cannot find namespace 'Types'.`]); - }); - it('Should generate the correct output when using immutableTypes config', async () => { const ast = parse(/* GraphQL */ ` query notifications { @@ -227,21 +127,24 @@ describe('TypeScript Operations Plugin', () => { } } `); - const config = { preResolveTypes: false, namingConvention: 'change-case-all#lowerCase', immutableTypes: true }; - const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin( + schema, + [{ location: 'test-file.ts', document: ast }], + { + namingConvention: 'change-case-all#lowerCase', + immutableTypes: true, + }, + { outputFile: '' } + ); expect(content).toMatchInlineSnapshot(` "export type notificationsqueryvariables = Exact<{ [key: string]: never; }>; export type notificationsquery = { readonly notifications: ReadonlyArray< - | Pick - | ( - Pick - & { readonly metadata: Pick } - ) + | { readonly text: string, readonly id: string } + | { readonly imageUrl: string, readonly id: string, readonly metadata: { readonly createdBy: string } } > }; " `); @@ -296,7 +199,6 @@ describe('TypeScript Operations Plugin', () => { schema, [{ location: '', document: fragment }], { - preResolveTypes: true, maybeValue: "T | 'specialType'", }, { @@ -345,12 +247,9 @@ describe('TypeScript Operations Plugin', () => { schema, [{ location: '', document: fragment }], { - preResolveTypes: true, allowUndefinedQueryVariables: true, }, - { - outputFile: 'graphql.ts', - } + { outputFile: 'graphql.ts' } ); expect(content).toMatchInlineSnapshot(` @@ -365,36 +264,6 @@ describe('TypeScript Operations Plugin', () => { }); }); - describe('Scalars', () => { - it('Should include scalars when doing pick', async () => { - const testSchema = buildSchema(/* GraphQL */ ` - scalar Date - type Query { - me: User - } - type User { - id: ID! - joinDate: Date! - } - `); - - const doc = parse(/* GraphQL */ ` - query { - me { - id - joinDate - } - } - `); - const config = { preResolveTypes: false }; - const { content } = await plugin(testSchema, [{ location: 'test-file.ts', document: doc }], config, { - outputFile: '', - }); - expect(content).toContain(`Pick`); - await validate(content); - }); - }); - describe('Custom Operation Result Name Suffix', () => { it('Should generate custom operation result name', async () => { const ast = parse(/* GraphQL */ ` @@ -415,10 +284,13 @@ describe('TypeScript Operations Plugin', () => { } } `); - const config = { operationResultSuffix: 'Result', preResolveTypes: false }; - const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin( + schema, + [{ location: 'test-file.ts', document: ast }], + { operationResultSuffix: 'Result' }, + { outputFile: '' } + ); expect(content).toMatchInlineSnapshot( ` @@ -426,11 +298,8 @@ describe('TypeScript Operations Plugin', () => { export type NotificationsQueryResult = { notifications: Array< - | Pick - | ( - Pick - & { metadata: Pick } - ) + | { text: string, id: string } + | { imageUrl: string, id: string, metadata: { createdBy: string } } > }; " ` @@ -440,11 +309,8 @@ describe('TypeScript Operations Plugin', () => { export type NotificationsQueryResult = { notifications: Array< - | Pick - | ( - Pick - & { metadata: Pick } - ) + | { text: string, id: string } + | { imageUrl: string, id: string, metadata: { createdBy: string } } > }; " `); @@ -473,21 +339,21 @@ describe('TypeScript Operations Plugin', () => { } } `); - const config = { preResolveTypes: false, namingConvention: 'change-case-all#lowerCase' }; - const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin( + schema, + [{ location: 'test-file.ts', document: ast }], + { namingConvention: 'change-case-all#lowerCase' }, + { outputFile: '' } + ); expect(content).toMatchInlineSnapshot(` "export type notificationsqueryvariables = Exact<{ [key: string]: never; }>; export type notificationsquery = { notifications: Array< - | Pick - | ( - Pick - & { metadata: Pick } - ) + | { text: string, id: string } + | { imageUrl: string, id: string, metadata: { createdBy: string } } > }; " `); @@ -514,10 +380,12 @@ describe('TypeScript Operations Plugin', () => { } `); - const config = { preResolveTypes: false, typesPrefix: 'i', namingConvention: 'change-case-all#lowerCase' }; - const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + const { content } = await plugin( + schema, + [{ location: 'test-file.ts', document: ast }], + { typesPrefix: 'i', namingConvention: 'change-case-all#lowerCase' }, + { outputFile: '' } + ); expect(content).toMatchInlineSnapshot( ` @@ -525,28 +393,13 @@ describe('TypeScript Operations Plugin', () => { export type inotificationsquery = { notifications: Array< - | Pick - | ( - Pick - & { metadata: Pick } - ) + | { text: string, id: string } + | { imageUrl: string, id: string, metadata: { createdBy: string } } > }; " ` ); - expect(content).toMatchInlineSnapshot(` - "export type inotificationsqueryvariables = Exact<{ [key: string]: never; }>; - - export type inotificationsquery = { notifications: Array< - | Pick - | ( - Pick - & { metadata: Pick } - ) - > }; - " - `); await validate(content); }); @@ -660,7 +513,7 @@ describe('TypeScript Operations Plugin', () => { await plugin( schema, [{ location: 'test-file.ts', document: ast3 }], - { dedupeOperationSuffix: true, preResolveTypes: false }, + { dedupeOperationSuffix: true }, { outputFile: '' } ) ).content; @@ -669,28 +522,13 @@ describe('TypeScript Operations Plugin', () => { export type NotificationsQuery = { notifications: Array< - | Pick - | Pick - > }; - - export type MyFragment = { notifications: Array< - | Pick - | Pick - > }; - " - `); - expect(withUsage).toMatchInlineSnapshot(` - "export type NotificationsQueryVariables = Exact<{ [key: string]: never; }>; - - - export type NotificationsQuery = { notifications: Array< - | Pick - | Pick + | { id: string } + | { id: string } > }; export type MyFragment = { notifications: Array< - | Pick - | Pick + | { id: string } + | { id: string } > }; " `); @@ -737,31 +575,17 @@ describe('TypeScript Operations Plugin', () => { `); expect( - ( - await plugin( - schema, - [{ location: 'test-file.ts', document: ast }], - { preResolveTypes: false }, - { outputFile: '' } - ) - ).content + (await plugin(schema, [{ location: 'test-file.ts', document: ast }], {}, { outputFile: '' })).content ).toContain('export type NotificationsQueryQuery ='); expect( - ( - await plugin( - schema, - [{ location: 'test-file.ts', document: ast }], - { preResolveTypes: false }, - { outputFile: '' } - ) - ).content + (await plugin(schema, [{ location: 'test-file.ts', document: ast }], {}, { outputFile: '' })).content ).toContain('export type MyFragmentFragment ='); expect( ( await plugin( schema, [{ location: 'test-file.ts', document: ast }], - { omitOperationSuffix: true, preResolveTypes: false }, + { omitOperationSuffix: true }, { outputFile: '' } ) ).content @@ -771,7 +595,7 @@ describe('TypeScript Operations Plugin', () => { await plugin( schema, [{ location: 'test-file.ts', document: ast }], - { omitOperationSuffix: true, preResolveTypes: false }, + { omitOperationSuffix: true }, { outputFile: '' } ) ).content @@ -781,7 +605,7 @@ describe('TypeScript Operations Plugin', () => { await plugin( schema, [{ location: 'test-file.ts', document: ast2 }], - { omitOperationSuffix: true, preResolveTypes: false }, + { omitOperationSuffix: true }, { outputFile: '' } ) ).content @@ -791,7 +615,7 @@ describe('TypeScript Operations Plugin', () => { await plugin( schema, [{ location: 'test-file.ts', document: ast2 }], - { omitOperationSuffix: true, preResolveTypes: false }, + { omitOperationSuffix: true }, { outputFile: '' } ) ).content @@ -801,7 +625,7 @@ describe('TypeScript Operations Plugin', () => { await plugin( schema, [{ location: 'test-file.ts', document: ast2 }], - { omitOperationSuffix: false, preResolveTypes: false }, + { omitOperationSuffix: false }, { outputFile: '' } ) ).content @@ -811,7 +635,7 @@ describe('TypeScript Operations Plugin', () => { await plugin( schema, [{ location: 'test-file.ts', document: ast2 }], - { omitOperationSuffix: false, preResolveTypes: false }, + { omitOperationSuffix: false }, { outputFile: '' } ) ).content @@ -821,7 +645,7 @@ describe('TypeScript Operations Plugin', () => { await plugin( schema, [{ location: 'test-file.ts', document: ast3 }], - { omitOperationSuffix: true, preResolveTypes: false }, + { omitOperationSuffix: true }, { outputFile: '' } ) ).content; @@ -830,28 +654,13 @@ describe('TypeScript Operations Plugin', () => { export type Notifications = { notifications: Array< - | Pick - | Pick - > }; - - export type My = { notifications: Array< - | Pick - | Pick - > }; - " - `); - expect(withUsage).toMatchInlineSnapshot(` - "export type NotificationsVariables = Exact<{ [key: string]: never; }>; - - - export type Notifications = { notifications: Array< - | Pick - | Pick + | { id: string } + | { id: string } > }; export type My = { notifications: Array< - | Pick - | Pick + | { id: string } + | { id: string } > }; " `); @@ -875,20 +684,20 @@ describe('TypeScript Operations Plugin', () => { } } `); - const config = { - skipTypeNameForRoot: true, - preResolveTypes: false, - }; - const { content } = await plugin(testSchema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin( + testSchema, + [{ location: 'test-file.ts', document: ast }], + { skipTypeNameForRoot: true }, + { outputFile: '' } + ); expect(content).toMatchInlineSnapshot( ` "export type Q1QueryVariables = Exact<{ [key: string]: never; }>; - export type Q1Query = { test: Maybe> }; + export type Q1Query = { test: { foo: string | null } | null }; " ` ); @@ -912,24 +721,23 @@ describe('TypeScript Operations Plugin', () => { } } `); - const config = { - nonOptionalTypename: true, - skipTypeNameForRoot: true, - preResolveTypes: false, - }; - const { content } = await plugin(testSchema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin( + testSchema, + [{ location: 'test-file.ts', document: ast }], + { + nonOptionalTypename: true, + skipTypeNameForRoot: true, + }, + { outputFile: '' } + ); expect(content).toMatchInlineSnapshot( ` "export type Q1QueryVariables = Exact<{ [key: string]: never; }>; - export type Q1Query = { test: Maybe<( - { __typename: 'Test' } - & Pick - )> }; + export type Q1Query = { test: { __typename: 'Test', foo: string | null } | null }; " ` ); @@ -954,34 +762,30 @@ describe('TypeScript Operations Plugin', () => { } } `); - const config = { - nonOptionalTypename: true, - skipTypeNameForRoot: true, - preResolveTypes: false, - }; - const { content } = await plugin(testSchema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin( + testSchema, + [{ location: 'test-file.ts', document: ast }], + { + nonOptionalTypename: true, + skipTypeNameForRoot: true, + }, + { outputFile: '' } + ); expect(content).toMatchInlineSnapshot( ` "export type Q1QueryVariables = Exact<{ [key: string]: never; }>; - export type Q1Query = ( - { __typename: 'Query' } - & { test: Maybe<( - { __typename: 'Test' } - & Pick - )> } - ); + export type Q1Query = { __typename: 'Query', test: { __typename: 'Test', foo: string | null } | null }; " ` ); await validate(content); }); - it('Should add __typename correctly with nonOptionalTypename=false,skipTypename=true,preResolveTypes=true and explicit field', async () => { + it('Should add __typename correctly with nonOptionalTypename=false,skipTypename=true and explicit field', async () => { const testSchema = buildSchema(/* GraphQL */ ` type Search { search: [SearchResult!]! @@ -1032,13 +836,16 @@ describe('TypeScript Operations Plugin', () => { } } `); - const config = { - nonOptionalTypename: false, - skipTypename: true, - }; - const { content } = await plugin(testSchema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin( + testSchema, + [{ location: 'test-file.ts', document: ast }], + { + nonOptionalTypename: false, + skipTypename: true, + }, + { outputFile: '' } + ); expect(content).toContain( `\ @@ -1063,10 +870,13 @@ export type Q2Query = { search: Array< dummy } `); - const config = { skipTypename: true, preResolveTypes: false }; - const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin( + schema, + [{ location: 'test-file.ts', document: ast }], + { skipTypename: true }, + { outputFile: '' } + ); expect(content).not.toContain(`__typename`); await validate(content); @@ -1104,20 +914,17 @@ export type Q2Query = { search: Array< } } `); - const config = { preResolveTypes: false }; - const { content } = await plugin(testSchema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin( + testSchema, + [{ location: 'test-file.ts', document: ast }], + {}, + { outputFile: '' } + ); expect(content).toMatchInlineSnapshot(` - "type Node_A_Fragment = ( - { __typename: 'A' } - & Pick - ); + "type Node_A_Fragment = { __typename: 'A', id: string }; - type Node_B_Fragment = ( - { __typename: 'B' } - & Pick - ); + type Node_B_Fragment = { __typename: 'B', id: string }; export type NodeFragment = | Node_A_Fragment @@ -1127,16 +934,10 @@ export type Q2Query = { search: Array< export type TestQueryVariables = Exact<{ [key: string]: never; }>; - export type TestQuery = { some: Maybe< - | ( - { __typename: 'A' } - & Pick - ) - | ( - { __typename: 'B' } - & Pick - ) - > }; + export type TestQuery = { some: + | { __typename: 'A', id: string } + | { __typename: 'B', id: string } + | null }; " `); await validate(content); @@ -1149,34 +950,8 @@ export type Q2Query = { search: Array< dummy } `); - const config = { preResolveTypes: false }; - const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); - expect(content).toMatchInlineSnapshot(` - "export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>; - - - export type Unnamed_1_Query = ( - Pick - & { type: 'Query' } - ); - " - `); - await validate(content); - }); - it('Should add aliased __typename correctly with preResovleTypes', async () => { - const ast = parse(/* GraphQL */ ` - query { - type: __typename - dummy - } - `); - const config = { preResolveTypes: true }; - const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], {}, { outputFile: '' }); expect(content).toMatchInlineSnapshot(` "export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>; @@ -1194,18 +969,13 @@ export type Q2Query = { search: Array< dummy } `); - const config = { preResolveTypes: false }; - const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], {}, { outputFile: '' }); expect(content).toMatchInlineSnapshot(` "export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>; - export type Unnamed_1_Query = ( - { __typename: 'Query' } - & Pick - ); + export type Unnamed_1_Query = { __typename: 'Query', dummy: string | null }; " `); await validate(content); @@ -1217,38 +987,18 @@ export type Q2Query = { search: Array< dummy } `); - const config = { nonOptionalTypename: true, preResolveTypes: false }; - const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); - expect(content).toMatchInlineSnapshot(` - "export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>; - - - export type Unnamed_1_Query = ( - { __typename: 'Query' } - & Pick - ); - " - `); - await validate(content); - }); - it('Should add __typename as optional when its not specified', async () => { - const ast = parse(/* GraphQL */ ` - query { - dummy - } - `); - const config = { preResolveTypes: false }; - const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + const { content } = await plugin( + schema, + [{ location: 'test-file.ts', document: ast }], + { nonOptionalTypename: true }, + { outputFile: '' } + ); expect(content).toMatchInlineSnapshot(` "export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>; - export type Unnamed_1_Query = Pick; + export type Unnamed_1_Query = { __typename: 'Query', dummy: string | null }; " `); await validate(content); @@ -1261,25 +1011,25 @@ export type Q2Query = { search: Array< dummy } `); - const config = { skipTypename: true, preResolveTypes: false }; - const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin( + schema, + [{ location: 'test-file.ts', document: ast }], + { skipTypename: true }, + { outputFile: '' } + ); expect(content).toMatchInlineSnapshot(` "export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>; - export type Unnamed_1_Query = ( - { __typename: 'Query' } - & Pick - ); + export type Unnamed_1_Query = { __typename: 'Query', dummy: string | null }; " `); await validate(content); }); - it('Should add __typename correctly when unions are in use', async () => { + it('Should add __typename correctly when unions are in use and nonOptionalTypename=true', async () => { const ast = parse(/* GraphQL */ ` query unionTest { unionTest { @@ -1293,24 +1043,27 @@ export type Q2Query = { search: Array< } } `); - const config = { preResolveTypes: false }; - const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin( + schema, + [{ location: 'test-file.ts', document: ast }], + { nonOptionalTypename: true }, + { outputFile: '' } + ); expect(content).toMatchInlineSnapshot(` "export type UnionTestQueryVariables = Exact<{ [key: string]: never; }>; - export type UnionTestQuery = { unionTest: Maybe< - | Pick - | Pick - > }; + export type UnionTestQuery = { __typename: 'Query', unionTest: + | { __typename: 'User', id: string } + | { __typename: 'Profile', age: number | null } + | null }; " `); await validate(content); }); - it('Should add __typename correctly when interfaces are in use', async () => { + it('Should add __typename correctly when interfaces are in use and nonOptionalTypename=true', async () => { const ast = parse(/* GraphQL */ ` query notifications { notifications { @@ -1329,20 +1082,20 @@ export type Q2Query = { search: Array< } } `); - const config = { preResolveTypes: false }; - const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin( + schema, + [{ location: 'test-file.ts', document: ast }], + { nonOptionalTypename: true }, + { outputFile: '' } + ); expect(content).toMatchInlineSnapshot(` "export type NotificationsQueryVariables = Exact<{ [key: string]: never; }>; - export type NotificationsQuery = { notifications: Array< - | Pick - | ( - Pick - & { metadata: Pick } - ) + export type NotificationsQuery = { __typename: 'Query', notifications: Array< + | { __typename: 'TextNotification', text: string, id: string } + | { __typename: 'ImageNotification', imageUrl: string, id: string, metadata: { __typename: 'ImageMetadata', createdBy: string } } > }; " `); @@ -1362,23 +1115,15 @@ export type Q2Query = { search: Array< } } `); - const config = { preResolveTypes: false }; - const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], {}, { outputFile: '' }); expect(content).toMatchInlineSnapshot(` "export type NotificationsQueryVariables = Exact<{ [key: string]: never; }>; export type NotificationsQuery = { notifications: Array< - | ( - { __typename: 'TextNotification' } - & Pick - ) - | ( - { __typename: 'ImageNotification' } - & Pick - ) + | { __typename: 'TextNotification', text: string } + | { __typename: 'ImageNotification', imageUrl: string } > }; " `); @@ -1398,24 +1143,16 @@ export type Q2Query = { search: Array< } } `); - const config = { preResolveTypes: false }; - const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], {}, { outputFile: '' }); expect(content).toMatchInlineSnapshot(` "export type UnionTestQueryVariables = Exact<{ [key: string]: never; }>; - export type UnionTestQuery = { unionTest: Maybe< - | ( - { __typename: 'User' } - & Pick - ) - | ( - { __typename: 'Profile' } - & Pick - ) - > }; + export type UnionTestQuery = { unionTest: + | { __typename: 'User', email: string } + | { __typename: 'Profile', firstName: string } + | null }; " `); await validate(content); @@ -1429,22 +1166,25 @@ export type Q2Query = { search: Array< dummy } `); - const config = { skipTypename: true, preResolveTypes: false }; - const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin( + schema, + [{ location: 'test-file.ts', document: ast }], + { skipTypename: true }, + { outputFile: '' } + ); expect(content).toMatchInlineSnapshot(` "export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>; - export type Unnamed_1_Query = Pick; + export type Unnamed_1_Query = { dummy: string | null }; " `); expect(content).toMatchInlineSnapshot(` "export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>; - export type Unnamed_1_Query = Pick; + export type Unnamed_1_Query = { dummy: string | null }; " `); await validate(content); @@ -1460,57 +1200,60 @@ export type Q2Query = { search: Array< dummy } `); - const config = { skipTypename: true, preResolveTypes: false }; - const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin( + schema, + [{ location: 'test-file.ts', document: ast }], + { skipTypename: true }, + { outputFile: '' } + ); expect(content).toMatchInlineSnapshot(` "export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>; - export type Unnamed_1_Query = Pick; + export type Unnamed_1_Query = { dummy: string | null }; export type Unnamed_2_QueryVariables = Exact<{ [key: string]: never; }>; - export type Unnamed_2_Query = Pick; + export type Unnamed_2_Query = { dummy: string | null }; " `); expect(content).toMatchInlineSnapshot(` "export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>; - export type Unnamed_1_Query = Pick; + export type Unnamed_1_Query = { dummy: string | null }; export type Unnamed_2_QueryVariables = Exact<{ [key: string]: never; }>; - export type Unnamed_2_Query = Pick; + export type Unnamed_2_Query = { dummy: string | null }; " `); expect(content).toMatchInlineSnapshot(` "export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>; - export type Unnamed_1_Query = Pick; + export type Unnamed_1_Query = { dummy: string | null }; export type Unnamed_2_QueryVariables = Exact<{ [key: string]: never; }>; - export type Unnamed_2_Query = Pick; + export type Unnamed_2_Query = { dummy: string | null }; " `); expect(content).toMatchInlineSnapshot(` "export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>; - export type Unnamed_1_Query = Pick; + export type Unnamed_1_Query = { dummy: string | null }; export type Unnamed_2_QueryVariables = Exact<{ [key: string]: never; }>; - export type Unnamed_2_Query = Pick; + export type Unnamed_2_Query = { dummy: string | null }; " `); await validate(content); @@ -1524,7 +1267,6 @@ export type Q2Query = { search: Array< test } `); - const config = { preResolveTypes: false }; try { await plugin( @@ -1534,7 +1276,7 @@ export type Q2Query = { search: Array< } `), [{ location: 'test-file.ts', document: ast }], - config, + {}, { outputFile: '' } ); expect(true).toBeFalsy(); @@ -1583,10 +1325,13 @@ export type Q2Query = { search: Array< } } `); - const config = { preResolveTypes: false }; - const { content } = await plugin(testSchema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin( + testSchema, + [{ location: 'test-file.ts', document: ast }], + {}, + { outputFile: '' } + ); const usage = ` type Route = QqQuery['routes'][0]; @@ -1625,10 +1370,13 @@ export type Q2Query = { search: Array< } } `); - const config = { preResolveTypes: false }; - const { content } = await plugin(testSchema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin( + testSchema, + [{ location: 'test-file.ts', document: ast }], + {}, + { outputFile: '' } + ); await validate(content); expect(mergeOutputs([content])).toMatchSnapshot(); }); @@ -1658,10 +1406,13 @@ export type Q2Query = { search: Array< name } `); - const config = { preResolveTypes: false }; - const { content } = await plugin(testSchema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin( + testSchema, + [{ location: 'test-file.ts', document: ast }], + {}, + { outputFile: '' } + ); await validate(content); expect(mergeOutputs([content])).toMatchSnapshot(); }); @@ -1689,10 +1440,13 @@ export type Q2Query = { search: Array< name } `); - const config = { preResolveTypes: false }; - const { content } = await plugin(testSchema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin( + testSchema, + [{ location: 'test-file.ts', document: ast }], + {}, + { outputFile: '' } + ); await validate(content); expect(mergeOutputs([content])).toMatchSnapshot(); }); @@ -1723,10 +1477,13 @@ export type Q2Query = { search: Array< } } `); - const config = { preResolveTypes: false }; - const { content } = await plugin(testSchema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin( + testSchema, + [{ location: 'test-file.ts', document: ast }], + {}, + { outputFile: '' } + ); await validate( content, `function test(q: AaaQuery) { @@ -1779,10 +1536,13 @@ export type Q2Query = { search: Array< } } `); - const config = { preResolveTypes: false }; - const { content } = await plugin(testSchema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin( + testSchema, + [{ location: 'test-file.ts', document: ast }], + {}, + { outputFile: '' } + ); await validate( content, @@ -1840,10 +1600,13 @@ export type Q2Query = { search: Array< } } `); - const config = { preResolveTypes: false }; - const { content } = await plugin(testSchema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin( + testSchema, + [{ location: 'test-file.ts', document: ast }], + {}, + { outputFile: '' } + ); const usage = ` type Route = QqQuery['routes'][0]; @@ -1878,27 +1641,24 @@ export type Q2Query = { search: Array< } } `); - const config = { skipTypename: true, preResolveTypes: false }; - const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin( + schema, + [{ location: 'test-file.ts', document: ast }], + { skipTypename: true }, + { outputFile: '' } + ); expect(content).toMatchInlineSnapshot(` "export type Role = | 'USER' | 'ADMIN'; - export type UserFieldsFragment = ( - Pick - & { profile: Maybe> } - ); + export type UserFieldsFragment = { id: string, username: string, role: Role | null, profile: { age: number | null } | null }; export type MeQueryVariables = Exact<{ [key: string]: never; }>; - export type MeQuery = { me: Maybe<( - Pick - & { profile: Maybe> } - )> }; + export type MeQuery = { me: { id: string, username: string, role: Role | null, profile: { age: number | null } | null } | null }; " `); await validate(content); @@ -1920,24 +1680,21 @@ export type Q2Query = { search: Array< } } `); - const config = { skipTypename: true, preResolveTypes: false }; - const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin( + schema, + [{ location: 'test-file.ts', document: ast }], + { skipTypename: true }, + { outputFile: '' } + ); expect(content).toMatchInlineSnapshot(` - "export type UserFieldsFragment = ( - Pick - & { profile: Maybe> } - ); + "export type UserFieldsFragment = { id: string, profile: { age: number | null } | null }; export type MeQueryVariables = Exact<{ [key: string]: never; }>; - export type MeQuery = { me: Maybe<( - Pick - & { profile: Maybe> } - )> }; + export type MeQuery = { me: { username: string, id: string, profile: { age: number | null } | null } | null }; " `); await validate(content); @@ -1963,51 +1720,23 @@ export type Q2Query = { search: Array< } } `); - const config = { skipTypename: false, preResolveTypes: false }; - const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); - - expect(content).toMatchInlineSnapshot(` - "export type UserFieldsFragment = Pick; - - export type UserProfileFragment = { profile: Maybe> }; - - export type MeQueryVariables = Exact<{ [key: string]: never; }>; - - - export type MeQuery = { me: Maybe<( - Pick - & { profile: Maybe> } - )> }; - " - `); - expect(content).toMatchInlineSnapshot(` - "export type UserFieldsFragment = Pick; - - export type UserProfileFragment = { profile: Maybe> }; - - export type MeQueryVariables = Exact<{ [key: string]: never; }>; + const { content } = await plugin( + schema, + [{ location: 'test-file.ts', document: ast }], + { skipTypename: false }, + { outputFile: '' } + ); - export type MeQuery = { me: Maybe<( - Pick - & { profile: Maybe> } - )> }; - " - `); expect(content).toMatchInlineSnapshot(` - "export type UserFieldsFragment = Pick; + "export type UserFieldsFragment = { id: string }; - export type UserProfileFragment = { profile: Maybe> }; + export type UserProfileFragment = { profile: { age: number | null } | null }; export type MeQueryVariables = Exact<{ [key: string]: never; }>; - export type MeQuery = { me: Maybe<( - Pick - & { profile: Maybe> } - )> }; + export type MeQuery = { me: { username: string, id: string, profile: { age: number | null } | null } | null }; " `); await validate(content); @@ -2052,23 +1781,21 @@ export type Q2Query = { search: Array< y } `); - const config = { preResolveTypes: false }; - const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], {}, { outputFile: '' }); expect(content).toMatchInlineSnapshot(` "export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>; - export type Unnamed_1_Query = { b: Maybe< - | Pick - | Pick - > }; + export type Unnamed_1_Query = { b: + | { id: string, x: number } + | { id: string, y: number } + | null }; - export type AFragment = Pick; + export type AFragment = { id: string, x: number }; - export type BFragment = Pick; + export type BFragment = { id: string, y: number }; " `); await validate(content); @@ -2116,21 +1843,19 @@ export type Q2Query = { search: Array< bar } `); - const config = { preResolveTypes: false }; - const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], {}, { outputFile: '' }); expect(content).toMatchInlineSnapshot(` "export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>; - export type Unnamed_1_Query = { myType: Pick }; + export type Unnamed_1_Query = { myType: { foo: string, bar: string, test: string } }; - export type CFragment = Pick; + export type CFragment = { test: string }; - export type AFragment = Pick; + export type AFragment = { foo: string }; - export type BFragment = Pick; + export type BFragment = { bar: string }; " `); await validate(content); @@ -2173,27 +1898,24 @@ export type Q2Query = { search: Array< x } `); - const config = { preResolveTypes: false }; - const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], {}, { outputFile: '' }); expect(content).toMatchInlineSnapshot(` "export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>; - export type Unnamed_1_Query = { b: Maybe< - | Pick + export type Unnamed_1_Query = { b: + | { id: string, x: number } | Record - > }; + | null }; - export type AFragment = Pick; + export type AFragment = { id: string }; - export type BFragment = Pick; + export type BFragment = { x: number }; " `); - validateTs(mergeOutputs([content]), config); - expect(mergeOutputs([content])).toMatchSnapshot(); + validateTs(mergeOutputs([content]), {}); }); it('Should support interfaces correctly when used with inline fragments', async () => { @@ -2216,20 +1938,14 @@ export type Q2Query = { search: Array< } `); - const config = { preResolveTypes: false }; - const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], {}, { outputFile: '' }); expect(content).toMatchInlineSnapshot(` "export type NotificationsQueryVariables = Exact<{ [key: string]: never; }>; export type NotificationsQuery = { notifications: Array< - | Pick - | ( - Pick - & { metadata: Pick } - ) + | { text: string, id: string } + | { imageUrl: string, id: string, metadata: { createdBy: string } } > }; " `); @@ -2250,19 +1966,17 @@ export type Q2Query = { search: Array< } } `); - const config = { preResolveTypes: false }; - const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], {}, { outputFile: '' }); expect(content).toMatchInlineSnapshot(` "export type UnionTestQueryVariables = Exact<{ [key: string]: never; }>; - export type UnionTestQuery = { unionTest: Maybe< - | Pick - | Pick - > }; + export type UnionTestQuery = { unionTest: + | { id: string } + | { age: number | null } + | null }; " `); await validate(content); @@ -2286,18 +2000,16 @@ export type Q2Query = { search: Array< } } `); - const config = { preResolveTypes: false }; - const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], {}, { outputFile: '' }); expect(content).toMatchInlineSnapshot(` "export type UnionTestQueryVariables = Exact<{ [key: string]: never; }>; export type UnionTestQuery = { mixedNotifications: Array< - | Pick - | Pick + | { id: string, text: string } + | { id: string, imageUrl: string } > }; " `); @@ -2326,19 +2038,17 @@ export type Q2Query = { search: Array< } } `); - const config = { preResolveTypes: false }; - const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], {}, { outputFile: '' }); expect(content).toMatchInlineSnapshot(` "export type UnionTestQueryVariables = Exact<{ [key: string]: never; }>; export type UnionTestQuery = { search: Array< - | Pick - | Pick - | Pick + | { id: string, text: string } + | { id: string, imageUrl: string } + | { id: string } > }; " `); @@ -2357,17 +2067,20 @@ export type Q2Query = { search: Array< id } `); - const config = { preResolveTypes: true, mergeFragmentTypes: true, namingConvention: 'keep' }; - const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); - - expect(content).toMatchInlineSnapshot(` - "export type testQueryVariables = Exact<{ [key: string]: never; }>; + const { content } = await plugin( + schema, + [{ location: 'test-file.ts', document: ast }], + { mergeFragmentTypes: true, namingConvention: 'keep' }, + { outputFile: '' } + ); + + expect(content).toMatchInlineSnapshot(` + "export type testQueryVariables = Exact<{ [key: string]: never; }>; + + + export type testQuery = { notifications: Array<{ id: string }> }; - export type testQuery = { notifications: Array<{ id: string }> }; - export type NFragment = { id: string }; " `); @@ -2383,10 +2096,13 @@ export type Q2Query = { search: Array< } } `); - const config = { preResolveTypes: true, mergeFragmentTypes: true, namingConvention: 'keep' }; - const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin( + schema, + [{ location: 'test-file.ts', document: ast }], + { mergeFragmentTypes: true, namingConvention: 'keep' }, + { outputFile: '' } + ); expect(content).toMatchInlineSnapshot(` "type N_TextNotification_Fragment = { text: string, id: string }; @@ -2442,10 +2158,13 @@ export type Q2Query = { search: Array< } } `); - const config = { preResolveTypes: true, mergeFragmentTypes: true, namingConvention: 'keep' }; - const { content } = await plugin(testSchema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin( + testSchema, + [{ location: 'test-file.ts', document: ast }], + { mergeFragmentTypes: true, namingConvention: 'keep' }, + { outputFile: '' } + ); expect(content).toMatchInlineSnapshot(` "type N_A_Fragment = { text: string, id: string }; @@ -2471,10 +2190,13 @@ export type Q2Query = { search: Array< } } `); - const config = { preResolveTypes: true, mergeFragmentTypes: true, namingConvention: 'keep' }; - const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin( + schema, + [{ location: 'test-file.ts', document: ast }], + { mergeFragmentTypes: true, namingConvention: 'keep' }, + { outputFile: '' } + ); expect(content).toMatchInlineSnapshot(` "export type NFragment = { notifications: Array<{ text: string }> }; @@ -2495,10 +2217,13 @@ export type Q2Query = { search: Array< id } `); - const config = { preResolveTypes: true, skipTypename: true, mergeFragmentTypes: true, namingConvention: 'keep' }; - const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin( + schema, + [{ location: 'test-file.ts', document: ast }], + { skipTypename: true, mergeFragmentTypes: true, namingConvention: 'keep' }, + { outputFile: '' } + ); expect(content).toMatchInlineSnapshot(` "export type testQueryVariables = Exact<{ [key: string]: never; }>; @@ -2521,10 +2246,13 @@ export type Q2Query = { search: Array< } } `); - const config = { preResolveTypes: true, skipTypename: true, mergeFragmentTypes: true, namingConvention: 'keep' }; - const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin( + schema, + [{ location: 'test-file.ts', document: ast }], + { skipTypename: true, mergeFragmentTypes: true, namingConvention: 'keep' }, + { outputFile: '' } + ); expect(content).toMatchInlineSnapshot(` "type N_TextNotification_Fragment = { text: string, id: string }; @@ -2552,10 +2280,13 @@ export type Q2Query = { search: Array< id } `); - const config = { preResolveTypes: true, mergeFragmentTypes: true, inlineFragmentTypes: 'mask' } as const; - const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin( + schema, + [{ location: 'test-file.ts', document: ast }], + { mergeFragmentTypes: true, inlineFragmentTypes: 'mask' }, + { outputFile: '' } + ); expect(content).toMatchInlineSnapshot(` "export type TestQueryVariables = Exact<{ [key: string]: never; }>; @@ -2593,18 +2324,18 @@ export type Q2Query = { search: Array< } } `); - const config = { skipTypename: true, preResolveTypes: false }; - const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin( + schema, + [{ location: 'test-file.ts', document: ast }], + { skipTypename: true }, + { outputFile: '' } + ); expect(content).toMatchInlineSnapshot(` "export type CurrentUserQueryVariables = Exact<{ [key: string]: never; }>; - export type CurrentUserQuery = { me: Maybe<( - Pick - & { profile: Maybe> } - )> }; + export type CurrentUserQuery = { me: { username: string, id: string, profile: { age: number | null } | null } | null }; " `); @@ -2628,10 +2359,13 @@ export type Q2Query = { search: Array< } } `); - const config = { skipTypename: true, preResolveTypes: false }; - const { content } = await plugin(gitHuntSchema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin( + gitHuntSchema, + [{ location: 'test-file.ts', document: ast }], + { skipTypename: true }, + { outputFile: '' } + ); expect(content).toMatchInlineSnapshot( ` @@ -2640,13 +2374,7 @@ export type Q2Query = { search: Array< }>; - export type MeQuery = { - currentUser: Maybe>, - entry: Maybe<( - Pick - & { postedBy: Pick } - )>, - }; + export type MeQuery = { currentUser: { login: string, html_url: string } | null, entry: { id: number, createdAt: number, postedBy: { login: string, html_url: string } } | null }; " ` ); @@ -2656,19 +2384,13 @@ export type Q2Query = { search: Array< }>; - export type MeQuery = { - currentUser: Maybe>, - entry: Maybe<( - Pick - & { postedBy: Pick } - )>, - }; + export type MeQuery = { currentUser: { login: string, html_url: string } | null, entry: { id: number, createdAt: number, postedBy: { login: string, html_url: string } } | null }; " `); await validate(content); }); - it('Should build a basic selection set based on basic query on GitHub schema with preResolveTypes=true', async () => { + it('Should build a basic selection set based on basic query on GitHub schema', async () => { const ast = parse(/* GraphQL */ ` query me($repoFullName: String!) { currentUser { @@ -2685,10 +2407,13 @@ export type Q2Query = { search: Array< } } `); - const config = { preResolveTypes: true }; - const { content } = await plugin(gitHuntSchema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin( + gitHuntSchema, + [{ location: 'test-file.ts', document: ast }], + {}, + { outputFile: '' } + ); expect(content).toMatchInlineSnapshot(` "export type MeQueryVariables = Exact<{ @@ -2702,7 +2427,7 @@ export type Q2Query = { search: Array< await validate(content); }); - it('Should produce valid output with preResolveTypes=true and enums', async () => { + it('Should produce valid output with enums', async () => { const ast = parse(/* GraphQL */ ` query test { info { @@ -2736,10 +2461,13 @@ export type Q2Query = { search: Array< info: Information } `); - const config = { preResolveTypes: true }; - const { content } = await plugin(testSchema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin( + testSchema, + [{ location: 'test-file.ts', document: ast }], + {}, + { outputFile: '' } + ); const o = await validate(content); expect(o).toMatchInlineSnapshot(` @@ -2757,7 +2485,7 @@ export type Q2Query = { search: Array< `); }); - it('Should produce valid output with preResolveTypes=true and enums with prefixes set', async () => { + it('Should produce valid output with enums with prefixes set', async () => { const ast = parse(/* GraphQL */ ` query test($e: Information_EntryType!) { info { @@ -2795,10 +2523,13 @@ export type Q2Query = { search: Array< info: Information } `); - const config = { preResolveTypes: true, typesPrefix: 'I', enumPrefix: false }; - const { content } = await plugin(testSchema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin( + testSchema, + [{ location: 'test-file.ts', document: ast }], + { typesPrefix: 'I', enumPrefix: false }, + { outputFile: '' } + ); const o = await validate(content); expect(o).toMatchInlineSnapshot(` @@ -2818,7 +2549,7 @@ export type Q2Query = { search: Array< `); }); - it('Should produce valid output with preResolveTypes=true and enums with no suffixes', async () => { + it('Should produce valid output with enums with no suffixes', async () => { const ast = parse(/* GraphQL */ ` query test($e: Information_EntryType!) { info { @@ -2856,10 +2587,13 @@ export type Q2Query = { search: Array< info: Information } `); - const config = { preResolveTypes: true, typesSuffix: 'I', enumSuffix: false }; - const { content } = await plugin(testSchema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin( + testSchema, + [{ location: 'test-file.ts', document: ast }], + { typesSuffix: 'I', enumSuffix: false }, + { outputFile: '' } + ); const o = await validate(content); expect(o).toMatchInlineSnapshot(` @@ -2885,16 +2619,19 @@ export type Q2Query = { search: Array< dummy } `); - const config = { skipTypename: true, preResolveTypes: false }; - const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin( + schema, + [{ location: 'test-file.ts', document: ast }], + { skipTypename: true }, + { outputFile: '' } + ); expect(content).toMatchInlineSnapshot(` "export type DummyQueryVariables = Exact<{ [key: string]: never; }>; - export type DummyQuery = Pick; + export type DummyQuery = { dummy: string | null }; " `); await validate(content); @@ -2909,19 +2646,19 @@ export type Q2Query = { search: Array< } } `); - const config = { skipTypename: true, preResolveTypes: false }; - const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin( + schema, + [{ location: 'test-file.ts', document: ast }], + { skipTypename: true }, + { outputFile: '' } + ); expect(content).toMatchInlineSnapshot(` "export type DummyQueryVariables = Exact<{ [key: string]: never; }>; - export type DummyQuery = ( - { customName: Query['dummy'] } - & { customName2: Maybe> } - ); + export type DummyQuery = { customName: string | null, customName2: { age: number | null } | null }; " `); await validate(content); @@ -2940,10 +2677,13 @@ export type Q2Query = { search: Array< } } `); - const config = { skipTypename: true, preResolveTypes: false }; - const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin( + schema, + [{ location: 'test-file.ts', document: ast }], + { skipTypename: true }, + { outputFile: '' } + ); expect(content).toMatchInlineSnapshot(` "export type Role = @@ -2953,10 +2693,7 @@ export type Q2Query = { search: Array< export type CurrentUserQueryVariables = Exact<{ [key: string]: never; }>; - export type CurrentUserQuery = { me: Maybe<( - Pick - & { profile: Maybe> } - )> }; + export type CurrentUserQuery = { me: { id: string, username: string, role: Role | null, profile: { age: number | null } | null } | null }; " `); await validate(content); @@ -2974,16 +2711,16 @@ export type Q2Query = { search: Array< } } `); - const config = { skipTypename: true, preResolveTypes: false }; - const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin( + schema, + [{ location: 'test-file.ts', document: ast }], + { skipTypename: true }, + { outputFile: '' } + ); expect(content).toMatchInlineSnapshot(` - "export type UserFieldsFragment = ( - Pick - & { profile: Maybe> } - ); + "export type UserFieldsFragment = { id: string, username: string, profile: { age: number | null } | null }; " `); await validate(content); @@ -3003,19 +2740,19 @@ export type Q2Query = { search: Array< } } `); - const config = { skipTypename: true, preResolveTypes: false }; - const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin( + schema, + [{ location: 'test-file.ts', document: ast }], + { skipTypename: true }, + { outputFile: '' } + ); expect(content).toMatchInlineSnapshot(` "export type LoginMutationVariables = Exact<{ [key: string]: never; }>; - export type LoginMutation = { login: Maybe<( - Pick - & { profile: Maybe> } - )> }; + export type LoginMutation = { login: { id: string, username: string, profile: { age: number | null } | null } | null }; " `); await validate(content); @@ -3027,16 +2764,19 @@ export type Q2Query = { search: Array< dummy } `); - const config = { skipTypename: true, preResolveTypes: false }; - const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin( + schema, + [{ location: 'test-file.ts', document: ast }], + { skipTypename: false }, + { outputFile: '' } + ); expect(content).toMatchInlineSnapshot(` "export type TestQueryVariables = Exact<{ [key: string]: never; }>; - export type TestQuery = Pick; + export type TestQuery = { dummy: string | null }; " `); await validate(content); @@ -3050,16 +2790,19 @@ export type Q2Query = { search: Array< } } `); - const config = { skipTypename: true, preResolveTypes: false }; - const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin( + schema, + [{ location: 'test-file.ts', document: ast }], + { skipTypename: true }, + { outputFile: '' } + ); expect(content).toMatchInlineSnapshot(` "export type TestSubscriptionVariables = Exact<{ [key: string]: never; }>; - export type TestSubscription = { userCreated: Maybe> }; + export type TestSubscription = { userCreated: { id: string } | null }; " `); await validate(content); @@ -3080,10 +2823,13 @@ export type Q2Query = { search: Array< dummy } `); - const config = { skipTypename: true }; - const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin( + schema, + [{ location: 'test-file.ts', document: ast }], + { skipTypename: true }, + { outputFile: '' } + ); expect(content).toMatchInlineSnapshot( ` @@ -3116,10 +2862,13 @@ export type Q2Query = { search: Array< dummy } `); - const config = { skipTypename: true }; - const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin( + schema, + [{ location: 'test-file.ts', document: ast }], + { skipTypename: true }, + { outputFile: '' } + ); expect(content).toMatchInlineSnapshot( ` @@ -3141,10 +2890,13 @@ export type Q2Query = { search: Array< dummy } `); - const config = { skipTypename: true }; - const { content } = await plugin(schema, [{ location: 'test-file.ts', document: ast }], config, { - outputFile: '', - }); + + const { content } = await plugin( + schema, + [{ location: 'test-file.ts', document: ast }], + { skipTypename: true }, + { outputFile: '' } + ); expect(content).toMatchInlineSnapshot(` "export type TestQueryQueryVariables = Exact<{ [key: string]: never; }>; @@ -3188,10 +2940,8 @@ export type Q2Query = { search: Array< const { content } = await plugin( testSchema, [{ location: '', document: query }], - { preResolveTypes: false }, - { - outputFile: 'graphql.ts', - } + {}, + { outputFile: 'graphql.ts' } ); expect(content).toMatchInlineSnapshot(` @@ -3201,8 +2951,8 @@ export type Q2Query = { search: Array< export type SubmitMessageMutation = { mutation: - | Pick - | Pick + | { deleted: boolean } + | { updated: boolean } }; " `); @@ -3230,10 +2980,8 @@ export type Q2Query = { search: Array< const { content } = await plugin( testSchema, [{ location: '', document: query }], - { preResolveTypes: false }, - { - outputFile: 'graphql.ts', - } + {}, + { outputFile: 'graphql.ts' } ); expect(content).toMatchInlineSnapshot(` @@ -3269,17 +3017,15 @@ export type Q2Query = { search: Array< const { content } = await plugin( testSchema, [{ location: '', document: query }], - { preResolveTypes: false }, - { - outputFile: 'graphql.ts', - } + {}, + { outputFile: 'graphql.ts' } ); expect(content).toMatchInlineSnapshot(` "export type InfoQueryVariables = Exact<{ [key: string]: never; }>; - export type InfoQuery = { __schema: { queryType: { fields: Maybe>> } } }; + export type InfoQuery = { __schema: { queryType: { fields: Array<{ name: string }> | null } } }; " `); }); @@ -3311,23 +3057,15 @@ export type Q2Query = { search: Array< const { content } = await plugin( testSchema, [{ location: '', document: query }], - { preResolveTypes: false }, - { - outputFile: 'graphql.ts', - } + {}, + { outputFile: 'graphql.ts' } ); expect(content).toMatchInlineSnapshot(` "export type InfoQueryVariables = Exact<{ [key: string]: never; }>; - export type InfoQuery = { __type: Maybe<( - Pick<__Type, 'name'> - & { fields: Maybe - & { type: Pick<__Type, 'name' | 'kind'> } - )>> } - )> }; + export type InfoQuery = { __type: { name: string | null, fields: Array<{ name: string, type: { name: string | null, kind: __TypeKind } }> | null } | null }; " `); }); @@ -3360,10 +3098,8 @@ export type Q2Query = { search: Array< const { content } = await plugin( testSchema, [{ location: '', document: query }], - { typesPrefix: 'PREFIX_', preResolveTypes: false }, - { - outputFile: 'graphql.ts', - } + { typesPrefix: 'PREFIX_' }, + { outputFile: 'graphql.ts' } ); expect(content).toMatchInlineSnapshot(` @@ -3381,25 +3117,7 @@ export type Q2Query = { search: Array< }>; - export type PREFIX_UsersQuery = { users: Maybe>>> }; - " - `); - expect(content).toMatchInlineSnapshot(` - "export type PREFIX_Access = - | 'Read' - | 'Write' - | 'All'; - - type PREFIX_Filter = { - match: string; - }; - - export type PREFIX_UsersQueryVariables = Exact<{ - filter: PREFIX_Filter; - }>; - - - export type PREFIX_UsersQuery = { users: Maybe>>> }; + export type PREFIX_UsersQuery = { users: Array<{ access: PREFIX_Access | null } | null> | null }; " `); }); @@ -3425,9 +3143,7 @@ export type Q2Query = { search: Array< testSchema, [{ location: '', document: query }], {}, - { - outputFile: 'graphql.ts', - } + { outputFile: 'graphql.ts' } ); expect(content).toMatchInlineSnapshot(` @@ -3490,35 +3206,16 @@ export type Q2Query = { search: Array< } `); - const { content } = await plugin( - schema, - [{ location: '', document: query }], - { preResolveTypes: false }, - { - outputFile: 'graphql.ts', - } - ); + const { content } = await plugin(schema, [{ location: '', document: query }], {}, { outputFile: 'graphql.ts' }); expect(content).toMatchInlineSnapshot(` "export type FieldQueryVariables = Exact<{ [key: string]: never; }>; export type FieldQuery = { field: - | ( - { __typename: 'Error1' } - & Pick - ) - | ( - { __typename: 'Error2' } - & Pick - ) - | ( - { __typename: 'ComplexError' } - & Pick - ) - | ( - { __typename: 'FieldResultSuccess' } - & Pick - ) + | { __typename: 'Error1', message: string } + | { __typename: 'Error2', message: string } + | { __typename: 'ComplexError', message: string, additionalInfo: string } + | { __typename: 'FieldResultSuccess', someValue: boolean } }; " `); @@ -3571,32 +3268,16 @@ export type Q2Query = { search: Array< } `); - const { content } = await plugin( - schema, - [{ location: '', document: query }], - { preResolveTypes: false }, - { - outputFile: 'graphql.ts', - } - ); + const { content } = await plugin(schema, [{ location: '', document: query }], {}, { outputFile: 'graphql.ts' }); expect(content).toMatchInlineSnapshot(` "export type FieldQueryVariables = Exact<{ [key: string]: never; }>; export type FieldQuery = { field: - | ( - { __typename: 'Error1' } - & Pick - ) - | ( - { __typename: 'Error2' } - & Pick - ) - | ( - { __typename: 'ComplexError' } - & Pick - ) - | Pick + | { __typename: 'Error1', message: string } + | { __typename: 'Error2', message: string } + | { __typename: 'ComplexError', message: string, additionalInfo: string } + | { someValue: boolean } }; " `); @@ -3639,20 +3320,18 @@ export type Q2Query = { search: Array< const { content } = await plugin( testSchema, [{ location: '', document: query }], - { preResolveTypes: false }, - { - outputFile: 'graphql.ts', - } + {}, + { outputFile: 'graphql.ts' } ); expect(content).toMatchInlineSnapshot(` "export type SomethingQueryVariables = Exact<{ [key: string]: never; }>; - export type SomethingQuery = { node: Maybe< - | Pick - | Pick - > }; + export type SomethingQuery = { node: + | { a: string | null } + | { a: boolean | null } + | null }; " `); }); @@ -3707,24 +3386,19 @@ export type Q2Query = { search: Array< const { content } = await plugin( testSchema, [{ location: '', document: query }], - { preResolveTypes: false }, - { - outputFile: 'graphql.ts', - } + {}, + { outputFile: 'graphql.ts' } ); expect(content).toMatchInlineSnapshot(` "export type UserQueryVariables = Exact<{ [key: string]: never; }>; - export type UserQuery = { user: Maybe< - | Pick - | Pick - | ( - Pick - & { info: Maybe> } - ) - > }; + export type UserQuery = { user: + | { id: string, login: string } + | { message: string } + | { message: string, info: { message: string } | null } + | null }; " `); }); @@ -3795,24 +3469,19 @@ export type Q2Query = { search: Array< const { content } = await plugin( testSchema, [{ location: '', document: query }], - { preResolveTypes: false }, - { - outputFile: 'graphql.ts', - } + {}, + { outputFile: 'graphql.ts' } ); expect(content).toMatchInlineSnapshot(` "export type UserQueryVariables = Exact<{ [key: string]: never; }>; - export type UserQuery = { user: Maybe< - | Pick - | Pick - | ( - Pick - & { info: Maybe> } - ) - > }; + export type UserQuery = { user: + | { id: string, login: string } + | { message: string } + | { message: string, info: { message: string, message2: string } | null } + | null }; " `); }); @@ -3846,10 +3515,8 @@ export type Q2Query = { search: Array< const { content } = await plugin( testSchema, [{ location: '', document: query }], - { preResolveTypes: false }, - { - outputFile: 'graphql.ts', - } + {}, + { outputFile: 'graphql.ts' } ); const o = await validate(content); @@ -3858,7 +3525,7 @@ export type Q2Query = { search: Array< "export type UserQueryQueryVariables = Exact<{ [key: string]: never; }>; - export type UserQueryQuery = { user: Pick }; + export type UserQueryQuery = { user: { id: string, login: string } }; " `); }); @@ -3894,10 +3561,8 @@ export type Q2Query = { search: Array< const { content } = await plugin( testSchema, [{ location: '', document: query }], - { preResolveTypes: false }, - { - outputFile: 'graphql.ts', - } + {}, + { outputFile: 'graphql.ts' } ); const o = await validate(content); @@ -3906,19 +3571,9 @@ export type Q2Query = { search: Array< "export type UserQueryQueryVariables = Exact<{ [key: string]: never; }>; - export type UserQueryQuery = { user: Pick }; - - export type TestFragment = Pick; - " - `); - - expect(o).toMatchInlineSnapshot(` - "export type UserQueryQueryVariables = Exact<{ [key: string]: never; }>; - - - export type UserQueryQuery = { user: Pick }; + export type UserQueryQuery = { user: { id: string, login: string } }; - export type TestFragment = Pick; + export type TestFragment = { login: string }; " `); }); @@ -3999,10 +3654,8 @@ export type Q2Query = { search: Array< const { content } = await plugin( testSchema, [{ location: '', document: query }], - { preResolveTypes: false }, - { - outputFile: 'graphql.ts', - } + {}, + { outputFile: 'graphql.ts' } ); const output = await validate( @@ -4026,87 +3679,31 @@ export type Q2Query = { search: Array< } }` ); - expect(mergeOutputs([content])).toMatchSnapshot(); - - expect(output).toMatchInlineSnapshot(` - "export type UserQueryQueryVariables = Exact<{ [key: string]: never; }>; - - - export type UserQueryQuery = { user: - | Pick - | Pick - | ( - Pick - & { info: Maybe> } - ) - }; - - export type AdditionalInfoFragment = Pick; - - type UserResult1_User_Fragment = Pick; - - type UserResult1_Error3_Fragment = { info: Maybe> }; - - export type UserResult1Fragment = - | UserResult1_User_Fragment - | UserResult1_Error3_Fragment - ; - - type UserResult_User_Fragment = Pick; - - type UserResult_Error2_Fragment = Pick; - - export type UserResultFragment = - | UserResult_User_Fragment - | UserResult_Error2_Fragment - ; - - function t(q: UserQueryQuery) { - if (q.user) { - if (q.user.__typename === 'User') { - if (q.user.id) { - const u = q.user.login; - } - } - if (q.user.__typename === 'Error2') { - console.log(q.user.message); - } - if (q.user.__typename === 'Error3') { - if (q.user.info) { - console.log(q.user.info.__typename) - } - } - } - }" - `); expect(output).toMatchInlineSnapshot(` "export type UserQueryQueryVariables = Exact<{ [key: string]: never; }>; export type UserQueryQuery = { user: - | Pick - | Pick - | ( - Pick - & { info: Maybe> } - ) + | { login: string, id: string } + | { message: string } + | { message: string, info: { message2: string, message: string } | null } }; - export type AdditionalInfoFragment = Pick; + export type AdditionalInfoFragment = { message: string }; - type UserResult1_User_Fragment = Pick; + type UserResult1_User_Fragment = { id: string }; - type UserResult1_Error3_Fragment = { info: Maybe> }; + type UserResult1_Error3_Fragment = { info: { message2: string } | null }; export type UserResult1Fragment = | UserResult1_User_Fragment | UserResult1_Error3_Fragment ; - type UserResult_User_Fragment = Pick; + type UserResult_User_Fragment = { id: string }; - type UserResult_Error2_Fragment = Pick; + type UserResult_Error2_Fragment = { message: string }; export type UserResultFragment = | UserResult_User_Fragment @@ -4206,14 +3803,12 @@ export type Q2Query = { search: Array< } `); - const config = { - flattenGeneratedTypes: true, - preResolveTypes: false, - }; - - const { content } = await plugin(testSchema, [{ location: '', document: query }], config, { - outputFile: 'graphql.ts', - }); + const { content } = await plugin( + testSchema, + [{ location: '', document: query }], + { flattenGeneratedTypes: true }, + { outputFile: 'graphql.ts' } + ); const output = await validate( content, @@ -4236,19 +3831,15 @@ export type Q2Query = { search: Array< } }` ); - expect(mergeOutputs([output])).toMatchSnapshot(); expect(output).toMatchInlineSnapshot(` "export type UserQueryQueryVariables = Exact<{ [key: string]: never; }>; export type UserQueryQuery = { user: - | Pick - | Pick - | ( - Pick - & { info: Maybe> } - ) + | { id: string, login: string } + | { message: string } + | { message: string, info: { message2: string, message: string } | null } }; function t(q: UserQueryQuery) { @@ -4321,29 +3912,23 @@ export type Q2Query = { search: Array< } `); - const config = { - flattenGeneratedTypes: true, - preResolveTypes: false, - }; - - const { content } = await plugin(testSchema, [{ location: '', document: query }], config, { - outputFile: 'graphql.ts', - }); + const { content } = await plugin( + testSchema, + [{ location: '', document: query }], + { flattenGeneratedTypes: true }, + { outputFile: 'graphql.ts' } + ); const output = await validate(content); - expect(mergeOutputs([output])).toMatchSnapshot(); expect(output).toMatchInlineSnapshot(` "export type SearchPopularQueryVariables = Exact<{ [key: string]: never; }>; - export type SearchPopularQuery = { search: Maybe - | ( - Pick - & { dimension: Maybe> } - ) - >> }; + export type SearchPopularQuery = { search: Array< + | { id: string | null } + | { value: string, dimension: { id: string | null } | null } + > | null }; " `); }); @@ -4382,22 +3967,17 @@ export type Q2Query = { search: Array< } `); - const config = { - flattenGeneratedTypes: true, - flattenGeneratedTypesIncludeFragments: true, - preResolveTypes: true, - }; - const { content } = await plugin( testSchema, [ { location: '', document: query }, { location: '', document: fragment }, ], - config, { - outputFile: 'graphql.ts', - } + flattenGeneratedTypes: true, + flattenGeneratedTypesIncludeFragments: true, + }, + { outputFile: 'graphql.ts' } ); const output = await validate(content); @@ -4448,22 +4028,17 @@ export type Q2Query = { search: Array< } `); - const config = { - flattenGeneratedTypes: true, - flattenGeneratedTypesIncludeFragments: false, - preResolveTypes: true, - }; - const { content } = await plugin( testSchema, [ { location: '', document: query }, { location: '', document: fragment }, ], - config, { - outputFile: 'graphql.ts', - } + flattenGeneratedTypes: true, + flattenGeneratedTypesIncludeFragments: false, + }, + { outputFile: 'graphql.ts' } ); const output = await validate(content); @@ -4502,25 +4077,23 @@ export type Q2Query = { search: Array< } `); - const config = { - addOperationExport: true, - preResolveTypes: false, - }; - - const { content } = await plugin(testSchema, [{ location: '', document: query }], config, { - outputFile: 'graphql.ts', - }); + const { content } = await plugin( + testSchema, + [{ location: '', document: query }], + { addOperationExport: true }, + { outputFile: 'graphql.ts' } + ); expect(content).toMatchInlineSnapshot(` "export type UserIdQueryQueryVariables = Exact<{ [key: string]: never; }>; - export type UserIdQueryQuery = { user: Pick }; + export type UserIdQueryQuery = { user: { id: string } }; export type UserLoginQueryQueryVariables = Exact<{ [key: string]: never; }>; - export type UserLoginQueryQuery = { user: Pick }; + export type UserLoginQueryQuery = { user: { login: string } }; export declare const UserIdQuery: import("graphql").DocumentNode; export declare const UserLoginQuery: import("graphql").DocumentNode;" @@ -4607,14 +4180,12 @@ export type Q2Query = { search: Array< } `); - const config = { - flattenGeneratedTypes: true, - preResolveTypes: false, - }; - - const { content } = await plugin(testSchema, [{ location: '', document: query }], config, { - outputFile: 'graphql.ts', - }); + const { content } = await plugin( + testSchema, + [{ location: '', document: query }], + { flattenGeneratedTypes: true }, + { outputFile: 'graphql.ts' } + ); const output = await validate( content, @@ -4637,25 +4208,15 @@ export type Q2Query = { search: Array< } }` ); - expect(mergeOutputs([output])).toMatchSnapshot(); expect(output).toMatchInlineSnapshot(` "export type UserQueryQueryVariables = Exact<{ [key: string]: never; }>; export type UserQueryQuery = { user: - | Pick< - User, - | 'id' - | 'test2' - | 'login' - | 'test' - > - | Pick - | ( - Pick - & { info: Maybe> } - ) + | { id: string, test2: string | null, login: string, test: string | null } + | { message: string } + | { message: string, info: { message2: string, message: string } | null } }; function t(q: UserQueryQuery) { @@ -4725,9 +4286,7 @@ export type Q2Query = { search: Array< testSchema, [{ location: '', document: query }], {}, - { - outputFile: 'graphql.ts', - } + { outputFile: 'graphql.ts' } ); await validate( @@ -4764,14 +4323,17 @@ export type Q2Query = { search: Array< const { content } = await plugin( testSchema, [{ location: '', document: query }], - { preResolveTypes: false }, - { - outputFile: 'graphql.ts', - } + {}, + { outputFile: 'graphql.ts' } ); - expect(content).not.toContain(`Maybe<>`); - expect(content).toContain(`Maybe`); + expect(content).toMatchInlineSnapshot(` + "export type TestQueryVariables = Exact<{ [key: string]: never; }>; + + + export type TestQuery = { test: never | null }; + " + `); }); it('#4389 - validate issues with interfaces', async () => { @@ -4809,16 +4371,14 @@ export type Q2Query = { search: Array< const { content } = await plugin( testSchema, [{ location: '', document: query }], - { preResolveTypes: false }, - { - outputFile: 'graphql.ts', - } + {}, + { outputFile: 'graphql.ts' } ); expect(content).toMatchInlineSnapshot(` "export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>; - export type Unnamed_1_Query = { foo: Maybe> }; + export type Unnamed_1_Query = { foo: Record | null }; " `); }); @@ -4846,13 +4406,12 @@ export type Q2Query = { search: Array< } `); - const config = { - typesSuffix: 'Type', - }; - - const { content } = await plugin(testSchema, [{ location: '', document: query }], config, { - outputFile: 'graphql.ts', - }); + const { content } = await plugin( + testSchema, + [{ location: '', document: query }], + { typesSuffix: 'Type' }, + { outputFile: 'graphql.ts' } + ); expect(content).not.toContain('UserTypeQueryVariablesType'); expect(content).not.toContain('UserTypeQueryType'); @@ -4915,13 +4474,12 @@ export type Q2Query = { search: Array< } `); - const config = {}; - - const { content } = await plugin(testSchema, [{ location: '', document: query }], config, { - outputFile: 'graphql.ts', - }); - - expect(content).toMatchSnapshot(); + const { content } = await plugin( + testSchema, + [{ location: '', document: query }], + {}, + { outputFile: 'graphql.ts' } + ); const result = await validate( content, @@ -4938,7 +4496,7 @@ export type Q2Query = { search: Array< expect(mergeOutputs([result])).toMatchSnapshot(); }); - it('#2916 - Missing import prefix with preResolveTypes: true and near-operation-file preset', async () => { + it('#2916 - Missing import prefix with near-operation-file preset', async () => { const testSchema = buildSchema(/* GraphQL */ ` type Query { user(id: ID!): User! @@ -4968,15 +4526,15 @@ export type Q2Query = { search: Array< } `); - const config = { - skipTypename: true, - preResolveTypes: true, - namespacedImportName: 'Types', - }; - - const { content } = await plugin(testSchema, [{ location: '', document: query }], config, { - outputFile: 'graphql.ts', - }); + const { content } = await plugin( + testSchema, + [{ location: '', document: query }], + { + skipTypename: true, + namespacedImportName: 'Types', + }, + { outputFile: 'graphql.ts' } + ); expect(content).toContain(`dep: Types.Department`); expect(content).toMatchSnapshot(); @@ -5104,9 +4662,7 @@ export type Q2Query = { search: Array< testSchema, [{ location: '', document: query }], {}, - { - outputFile: 'graphql.ts', - } + { outputFile: 'graphql.ts' } ); expect(mergeOutputs([content])).toMatchSnapshot(); @@ -5169,10 +4725,8 @@ function test(q: GetEntityBrandDataQuery): void { const { content } = await plugin( testSchema, [{ location: '', document: query }], - { preResolveTypes: false }, - { - outputFile: 'graphql.ts', - } + {}, + { outputFile: 'graphql.ts' } ); expect(content).toMatchInlineSnapshot(` @@ -5180,13 +4734,13 @@ function test(q: GetEntityBrandDataQuery): void { export type TestQueryQuery = { fooBar: Array< - | Pick - | Pick + | { id: string } + | { id: string } > }; - type FooBarFragment_Foo_Fragment = Pick; + type FooBarFragment_Foo_Fragment = { id: string }; - type FooBarFragment_Bar_Fragment = Pick; + type FooBarFragment_Bar_Fragment = { id: string }; export type FooBarFragmentFragment = | FooBarFragment_Foo_Fragment @@ -5239,19 +4793,14 @@ function test(q: GetEntityBrandDataQuery): void { { location: '', document: productFragmentDocument }, { location: '', document: priceFragmentDocument }, ], - { preResolveTypes: false }, - { - outputFile: 'graphql.ts', - } + {}, + { outputFile: 'graphql.ts' } ); expect(content).toMatchInlineSnapshot(` - "export type ProductFragmentFragment = Pick; + "export type ProductFragmentFragment = { id: string, title: string }; - export type PriceFragmentFragment = ( - Pick - & { item: Array>> } - ); + export type PriceFragmentFragment = { id: string, item: Array<{ id: string, title: string } | null> }; " `); }); @@ -5280,10 +4829,8 @@ function test(q: GetEntityBrandDataQuery): void { const { content } = await plugin( schema, [{ location: '', document: fragment }], - { preResolveTypes: false }, - { - outputFile: 'graphql.ts', - } + {}, + { outputFile: 'graphql.ts' } ); expect(content).toMatchInlineSnapshot(` @@ -5292,7 +4839,7 @@ function test(q: GetEntityBrandDataQuery): void { }>; - export type UserQuery = { user?: Maybe> }; + export type UserQuery = { user?: { name: string | null } | null }; " `); }); @@ -5348,22 +4895,14 @@ function test(q: GetEntityBrandDataQuery): void { const { content } = await plugin( schema, [{ location: '', document: fragment }], - { preResolveTypes: false }, - { - outputFile: 'graphql.ts', - } + {}, + { outputFile: 'graphql.ts' } ); expect(content).toMatchInlineSnapshot(` "export type DashboardVersionFragmentFragment = { tiles: - | ( - Pick - & { md: Pick } - ) - | ( - Pick - & { md: Pick } - ) + | { tileId: string, md: { viz: string, columnInfo: string } } + | { tileId: string, md: { viz: string, columnInfo: string } } }; " `); @@ -5419,22 +4958,14 @@ function test(q: GetEntityBrandDataQuery): void { const { content } = await plugin( schema, [{ location: '', document: fragment }], - { preResolveTypes: false }, - { - outputFile: 'graphql.ts', - } + {}, + { outputFile: 'graphql.ts' } ); expect(content).toMatchInlineSnapshot(` "export type DashboardVersionFragmentFragment = { tiles: - | ( - Pick - & { md: Pick } - ) - | ( - Pick - & { md: Pick } - ) + | { tileId: string, md: { viz: string, columnInfo: string } } + | { tileId: string, md: { viz: string, columnInfo: string } } }; " `); @@ -5483,12 +5014,8 @@ function test(q: GetEntityBrandDataQuery): void { const { content } = await plugin( schema, [{ location: '', document: query }], - { - skipTypename: true, - }, - { - outputFile: 'graphql.ts', - } + { skipTypename: true }, + { outputFile: 'graphql.ts' } ); expect(content).toMatchInlineSnapshot(` @@ -5556,12 +5083,8 @@ function test(q: GetEntityBrandDataQuery): void { const { content } = await plugin( schema, [{ location: '', document: query }], - { - skipTypename: false, - }, - { - outputFile: 'graphql.ts', - } + { skipTypename: false }, + { outputFile: 'graphql.ts' } ); expect(content).toMatchInlineSnapshot(` @@ -5618,13 +5141,8 @@ function test(q: GetEntityBrandDataQuery): void { const { content } = await plugin( schema, [{ location: '', document: query }], - { - skipTypename: true, - preResolveTypes: false, - }, - { - outputFile: 'graphql.ts', - } + { skipTypename: true }, + { outputFile: 'graphql.ts' } ); expect(content).toMatchInlineSnapshot(` @@ -5632,7 +5150,7 @@ function test(q: GetEntityBrandDataQuery): void { export type UserQuery = { user: - | Pick + | { id: string, login: string | null } | Record }; " @@ -5657,10 +5175,8 @@ function test(q: GetEntityBrandDataQuery): void { } } `); - const config = { preResolveTypes: true }; - const { content } = await plugin(schema, [{ location: '', document: ast }], config, { - outputFile: 'graphql.ts', - }); + + const { content } = await plugin(schema, [{ location: '', document: ast }], {}, { outputFile: 'graphql.ts' }); expect(content).toMatchInlineSnapshot(` "export type UserQueryVariables = Exact<{ @@ -5694,10 +5210,13 @@ function test(q: GetEntityBrandDataQuery): void { } } `); - const config = { preResolveTypes: true, arrayInputCoercion: false }; - const { content } = await plugin(schema, [{ location: '', document: ast }], config, { - outputFile: 'graphql.ts', - }); + + const { content } = await plugin( + schema, + [{ location: '', document: ast }], + { arrayInputCoercion: false }, + { outputFile: 'graphql.ts' } + ); expect(content).toMatchInlineSnapshot(` "export type UserQueryVariables = Exact<{ @@ -5750,22 +5269,15 @@ function test(q: GetEntityBrandDataQuery): void { } `); - const { content } = await plugin( - schema, - [{ location: '', document }], - { preResolveTypes: false }, - { - outputFile: 'graphql.ts', - } - ); + const { content } = await plugin(schema, [{ location: '', document }], {}, { outputFile: 'graphql.ts' }); expect(content).toMatchInlineSnapshot(` "export type EntityQueryVariables = Exact<{ [key: string]: never; }>; export type EntityQuery = { entity: - | Pick - | Pick + | { id: string } + | { name: string, id: string } }; " `); @@ -5802,20 +5314,13 @@ function test(q: GetEntityBrandDataQuery): void { } `); - const { content } = await plugin( - schema, - [{ location: '', document }], - { preResolveTypes: false }, - { - outputFile: 'graphql.ts', - } - ); + const { content } = await plugin(schema, [{ location: '', document }], {}, { outputFile: 'graphql.ts' }); expect(content).toMatchInlineSnapshot(` "export type InlineFragmentQueryQueryVariables = Exact<{ [key: string]: never; }>; - export type InlineFragmentQueryQuery = { user: { friends: Array> } }; + export type InlineFragmentQueryQuery = { user: { friends: Array<{ id: string, name: string }> } }; " `); }); @@ -5843,24 +5348,17 @@ function test(q: GetEntityBrandDataQuery): void { } `); - const { content } = await plugin( - schema, - [{ location: '', document }], - { preResolveTypes: false }, - { - outputFile: 'graphql.ts', - } - ); + const { content } = await plugin(schema, [{ location: '', document }], {}, { outputFile: 'graphql.ts' }); expect(content).toMatchInlineSnapshot(` - "export type UserFriendsIdFragmentFragment = { user: { friends: Array> } }; + "export type UserFriendsIdFragmentFragment = { user: { friends: Array<{ id: string }> } }; - export type UserFriendsNameFragmentFragment = { user: { friends: Array> } }; + export type UserFriendsNameFragmentFragment = { user: { friends: Array<{ name: string }> } }; export type SpreadFragmentQueryQueryVariables = Exact<{ [key: string]: never; }>; - export type SpreadFragmentQueryQuery = { user: { friends: Array> } }; + export type SpreadFragmentQueryQuery = { user: { friends: Array<{ id: string, name: string }> } }; " `); }); @@ -5885,25 +5383,15 @@ function test(q: GetEntityBrandDataQuery): void { } `); - const { content } = await plugin( - schema, - [{ location: '', document }], - { preResolveTypes: false }, - { - outputFile: 'graphql.ts', - } - ); + const { content } = await plugin(schema, [{ location: '', document }], {}, { outputFile: 'graphql.ts' }); expect(content).toMatchInlineSnapshot(` - "export type UserFriendsNameFragmentFragment = { user: { friends: Array> } }; + "export type UserFriendsNameFragmentFragment = { user: { friends: Array<{ name: string }> } }; export type SpreadFragmentWithSelectionQueryQueryVariables = Exact<{ [key: string]: never; }>; - export type SpreadFragmentWithSelectionQueryQuery = { user: ( - Pick - & { friends: Array> } - ) }; + export type SpreadFragmentWithSelectionQueryQuery = { user: { id: string, friends: Array<{ id: string, name: string }> } }; " `); }); @@ -5928,25 +5416,15 @@ function test(q: GetEntityBrandDataQuery): void { } `); - const { content } = await plugin( - schema, - [{ location: '', document }], - { preResolveTypes: false }, - { - outputFile: 'graphql.ts', - } - ); + const { content } = await plugin(schema, [{ location: '', document }], {}, { outputFile: 'graphql.ts' }); expect(content).toMatchInlineSnapshot(` - "export type UserFriendsNameFragmentFragment = { user: { friends: Array> } }; + "export type UserFriendsNameFragmentFragment = { user: { friends: Array<{ name: string }> } }; export type SpreadFragmentWithSelectionQueryQueryVariables = Exact<{ [key: string]: never; }>; - export type SpreadFragmentWithSelectionQueryQuery = { user: ( - Pick - & { friends: Array> } - ) }; + export type SpreadFragmentWithSelectionQueryQuery = { user: { id: string, friends: Array<{ id: string, name: string }> } }; " `); }); @@ -6033,7 +5511,7 @@ function test(q: GetEntityBrandDataQuery): void { `); }); - it('#6874 - generates types when parent type differs from spread fragment member types and preResolveTypes=true', async () => { + it('#6874 - generates types when parent type differs from spread fragment member types', async () => { const testSchema = buildSchema(/* GraphQL */ ` interface Animal { name: String! @@ -6088,11 +5566,12 @@ function test(q: GetEntityBrandDataQuery): void { } `); - const config = { preResolveTypes: true }; - - const { content } = await plugin(testSchema, [{ location: '', document: query }], config, { - outputFile: 'graphql.ts', - }); + const { content } = await plugin( + testSchema, + [{ location: '', document: query }], + {}, + { outputFile: 'graphql.ts' } + ); expect(content).toMatchSnapshot(); }); @@ -6136,13 +5615,23 @@ function test(q: GetEntityBrandDataQuery): void { } `); - const config = { preResolveTypes: true }; + const { content } = await plugin( + testSchema, + [{ location: '', document: query }], + {}, + { outputFile: 'graphql.ts' } + ); + + expect(content).toMatchInlineSnapshot(` + "export type SnakeQueryQueryVariables = Exact<{ [key: string]: never; }>; - const { content } = await plugin(testSchema, [{ location: '', document: query }], config, { - outputFile: 'graphql.ts', - }); - expect(content).toMatchSnapshot(); + export type SnakeQueryQuery = { __typename: 'Query', snake: + | { __typename: 'Snake' } + | { __typename: 'Error' } + }; + " + `); }); it('#8461 - conditional directives are ignored on fields with alias', async () => { @@ -6174,11 +5663,12 @@ function test(q: GetEntityBrandDataQuery): void { } `); - const config = { preResolveTypes: true }; - - const { content } = await plugin(testSchema, [{ location: '', document: query }], config, { - outputFile: 'graphql.ts', - }); + const { content } = await plugin( + testSchema, + [{ location: '', document: query }], + {}, + { outputFile: 'graphql.ts' } + ); expect(content).toMatchInlineSnapshot(` "export type UserQueryQueryVariables = Exact<{ @@ -6222,12 +5712,8 @@ function test(q: GetEntityBrandDataQuery): void { const { content } = await plugin( schema, [{ location: '', document: fragment }], - { - preResolveTypes: true, - }, - { - outputFile: 'graphql.ts', - } + {}, + { outputFile: 'graphql.ts' } ); expect(content).toMatchInlineSnapshot(` @@ -6278,12 +5764,8 @@ function test(q: GetEntityBrandDataQuery): void { const { content } = await plugin( schema, [{ location: '', document: fragment }], - { - preResolveTypes: true, - }, - { - outputFile: 'graphql.ts', - } + {}, + { outputFile: 'graphql.ts' } ); expect(content).toMatchInlineSnapshot(` @@ -6298,101 +5780,6 @@ function test(q: GetEntityBrandDataQuery): void { `); }); - it('fields with @skip, @include should make container resolve into MakeOptional type', async () => { - const schema = buildSchema(/* GraphQL */ ` - type Query { - user: User! - } - type User { - id: String! - name: String! - address: Address! - friends: [User!]! - } - type Address { - city: String! - } - `); - - const fragment = parse(/* GraphQL */ ` - query user($showAddress: Boolean!, $showName: Boolean!) { - user { - id - name @include(if: $showName) - address @include(if: $showAddress) { - city - } - friends @include(if: $isFriendly) { - id - } - } - } - `); - - const { content } = await plugin( - schema, - [{ location: '', document: fragment }], - { preResolveTypes: false }, - { - outputFile: 'graphql.ts', - } - ); - - expect(content).toMatchInlineSnapshot(` - "export type UserQueryVariables = Exact<{ - showAddress: boolean; - showName: boolean; - }>; - - - export type UserQuery = { user: ( - MakeOptional, 'name'> - & { - address?: Pick, - friends?: Array>, - } - ) }; - " - `); - }); - - it('Should handle "preResolveTypes" ', async () => { - const schema = buildSchema(/* GraphQL */ ` - type Query { - user(id: ID!): User! - } - - type User { - id: ID! - username: String! - email: String - } - `); - const operations = parse(/* GraphQL */ ` - query user { - user(id: 1) { - id - username - email - } - } - `); - const config = { preResolveTypes: true }; - const { content } = await plugin(schema, [{ location: '', document: operations }], config, { - outputFile: 'graphql.ts', - }); - - expect(content).toMatchInlineSnapshot( - ` - "export type UserQueryVariables = Exact<{ [key: string]: never; }>; - - - export type UserQuery = { user: { id: string, username: string, email: string | null } }; - " - ` - ); - }); - it('optionals (?) on types should be avoided by default', async () => { const schema = buildSchema(/* GraphQL */ ` type Query { @@ -6421,13 +5808,8 @@ function test(q: GetEntityBrandDataQuery): void { const { content } = await plugin( schema, [{ location: '', document: fragment }], - { - nonOptionalTypename: true, - preResolveTypes: false, - }, - { - outputFile: 'graphql.ts', - } + { nonOptionalTypename: true }, + { outputFile: 'graphql.ts' } ); expect(content).toMatchInlineSnapshot(` @@ -6436,16 +5818,7 @@ function test(q: GetEntityBrandDataQuery): void { }>; - export type MyQueryQuery = ( - { __typename: 'Query' } - & { me: ( - { __typename: 'User' } - & { messages?: Array<( - { __typename: 'Message' } - & Pick - )> } - ) } - ); + export type MyQueryQuery = { __typename: 'Query', me: { __typename: 'User', messages?: Array<{ __typename: 'Message', content: string }> } }; " `); }); @@ -6482,10 +5855,8 @@ function test(q: GetEntityBrandDataQuery): void { const { content } = await plugin( schema, [{ location: '', document: fragment }], - { preResolveTypes: true }, - { - outputFile: 'graphql.ts', - } + {}, + { outputFile: 'graphql.ts' } ); expect(content).toMatchInlineSnapshot(` @@ -6529,13 +5900,8 @@ function test(q: GetEntityBrandDataQuery): void { const { content } = await plugin( schema, [{ location: '', document: fragment }], - { - preResolveTypes: true, - maybeValue: "T | 'specialType'", - }, - { - outputFile: 'graphql.ts', - } + { maybeValue: "T | 'specialType'" }, + { outputFile: 'graphql.ts' } ); expect(content).toMatchInlineSnapshot(` "export type UserQueryVariables = Exact<{ @@ -6547,62 +5913,10 @@ function test(q: GetEntityBrandDataQuery): void { " `); }); - - it('inline fragment with conditional directives, without preResolveTypes', async () => { - const schema = buildSchema(/* GraphQL */ ` - type Query { - user: User - group: Group! - } - - type User { - name: String - } - - type Group { - id: Int! - } - `); - - const fragment = parse(/* GraphQL */ ` - query user($withUser: Boolean! = false) { - ... @include(if: $withUser) { - user { - name - } - group { - id - } - } - } - `); - - const { content } = await plugin( - schema, - [{ location: '', document: fragment }], - { preResolveTypes: false }, - { - outputFile: 'graphql.ts', - } - ); - - expect(content).toMatchInlineSnapshot(` - "export type UserQueryVariables = Exact<{ - withUser?: boolean; - }>; - - - export type UserQuery = { - user?: Maybe>, - group?: Pick, - }; - " - `); - }); }); describe('incremental delivery directive handling', () => { - it('should generate an union of initial and deferred fields for fragments (preResolveTypes: true)', async () => { + it('should generate an union of initial and deferred fields for fragments', async () => { const schema = buildSchema(/* GraphQL */ ` type Address { street1: String! @@ -6687,7 +6001,7 @@ function test(q: GetEntityBrandDataQuery): void { const { content } = await plugin( schema, [{ location: '', document: fragment }], - { preResolveTypes: true }, + {}, { outputFile: 'graphql.ts' } ); @@ -6706,294 +6020,6 @@ function test(q: GetEntityBrandDataQuery): void { `); }); - it('should generate an union of initial and deferred fields for fragments using MakeEmpty (preResolveTypes: false)', async () => { - const schema = buildSchema(/* GraphQL */ ` - type Address { - street1: String! - } - - type Phone { - home: String! - } - - type Employment { - title: String! - } - - type User { - name: String! - email: String! - address: Address! - phone: Phone! - employment: Employment! - widgetCount: Int! - clearanceLevel: String! - } - - type Query { - user: User! - } - `); - - const fragment = parse(/* GraphQL */ ` - fragment WidgetFragment on User { - widgetCount - } - - fragment EmploymentFragment on User { - employment { - title - } - } - - query user { - user { - # Test inline fragment defer - ... @defer { - email - } - - # Test inline fragment defer with nested selection set - ... @defer { - address { - street1 - } - } - - # Test named fragment defer - ...WidgetFragment @defer - - # Not deferred fields, fragments, selection sets, etc are left alone - name - phone { - home - } - ...EmploymentFragment - ... { - clearanceLevel - } - } - } - `); - - const { content } = await plugin( - schema, - [{ location: '', document: fragment }], - { preResolveTypes: false }, - { outputFile: 'graphql.ts' } - ); - - expect(content).toMatchInlineSnapshot(` - "export type WidgetFragmentFragment = Pick; - - export type EmploymentFragmentFragment = { employment: Pick }; - - export type UserQueryVariables = Exact<{ [key: string]: never; }>; - - - export type UserQuery = { user: ( - Pick - & { - phone: Pick, - employment: Pick, - } - ) & (Pick | MakeEmpty) & ({ address: Pick } | { address?: Pick }) & (Pick | MakeEmpty) }; - " - `); - }); - - it('should generate an union of initial and deferred fields for fragments MakeEmpty', async () => { - const schema = buildSchema(/* GraphQL */ ` - type Address { - street1: String! - } - - type Phone { - home: String! - } - - type Employment { - title: String! - } - - type User { - name: String! - email: String! - address: Address! - phone: Phone! - employment: Employment! - widgetName: String! - widgetCount: Int! - clearanceLevel: String! - } - - type Query { - user: User! - } - `); - - const fragment = parse(/* GraphQL */ ` - fragment WidgetFragment on User { - widgetName - widgetCount - } - - fragment EmploymentFragment on User { - employment { - title - } - } - - query user { - user { - # Test inline fragment defer - ... @defer { - email - } - - # Test inline fragment defer with nested selection set - ... @defer { - address { - street1 - } - } - - # Test named fragment defer - ...WidgetFragment @defer - - # Not deferred fields, fragments, selection sets, etc are left alone - name - phone { - home - } - ...EmploymentFragment - ... { - clearanceLevel - } - } - } - `); - - const { content } = await plugin( - schema, - [{ location: '', document: fragment }], - { - preResolveTypes: false, - }, - { outputFile: 'graphql.ts' } - ); - - expect(content).toMatchInlineSnapshot(` - "export type WidgetFragmentFragment = Pick; - - export type EmploymentFragmentFragment = { employment: Pick }; - - export type UserQueryVariables = Exact<{ [key: string]: never; }>; - - - export type UserQuery = { user: ( - Pick - & { - phone: Pick, - employment: Pick, - } - ) & (Pick | MakeEmpty) & ({ address: Pick } | { address?: Pick }) & (Pick | MakeEmpty) }; - " - `); - }); - - it('should support "preResolveTypes: true"', async () => { - const schema = buildSchema(/* GraphQL */ ` - type Address { - street1: String! - } - - type Phone { - home: String! - } - - type Employment { - title: String! - } - - type User { - name: String! - email: String! - address: Address! - phone: Phone! - employment: Employment! - widgetCount: Int! - clearanceLevel: String! - } - - type Query { - user: User! - } - `); - - const fragment = parse(/* GraphQL */ ` - fragment WidgetFragment on User { - widgetCount - } - - fragment EmploymentFragment on User { - employment { - title - } - } - - query user { - user { - # Test inline fragment defer - ... @defer { - email - } - - # Test inline fragment defer with nested selection set - ... @defer { - address { - street1 - } - } - - # Test named fragment defer - ...WidgetFragment @defer - - # Not deferred fields, fragments, selection sets, etc are left alone - name - phone { - home - } - ...EmploymentFragment - ... { - clearanceLevel - } - } - } - `); - - const { content } = await plugin( - schema, - [{ location: '', document: fragment }], - { - preResolveTypes: true, - }, - { outputFile: 'graphql.ts' } - ); - - expect(content).toMatchInlineSnapshot(` - "export type WidgetFragmentFragment = { widgetCount: number }; - - export type EmploymentFragmentFragment = { employment: { title: string } }; - - export type UserQueryVariables = Exact<{ [key: string]: never; }>; - - - export type UserQuery = { user: { clearanceLevel: string, name: string, phone: { home: string }, employment: { title: string } } & ({ email: string } | { email?: never }) & ({ address: { street1: string } } | { address?: never }) & ({ widgetCount: number } | { widgetCount?: never }) }; - " - `); - }); - it('should resolve optionals according to maybeValue together with deferred fragments', async () => { const schema = buildSchema(/* GraphQL */ ` type Address { @@ -7069,10 +6095,7 @@ function test(q: GetEntityBrandDataQuery): void { const { content } = await plugin( schema, [{ location: '', document: fragment }], - { - preResolveTypes: true, - maybeValue: "T | 'specialType'", - }, + { maybeValue: "T | 'specialType'" }, { outputFile: 'graphql.ts' } ); @@ -7171,15 +6194,19 @@ function test(q: GetEntityBrandDataQuery): void { } `); - const { content } = await plugin( - schema, - [{ location: '', document: fragment }], - { preResolveTypes: true, inlineFragmentTypes: 'mask' }, - { outputFile: 'graphql.ts' } - ); + const content = mergeOutputs([ + await plugin( + schema, + [{ location: '', document: fragment }], + { inlineFragmentTypes: 'mask' }, + { outputFile: 'graphql.ts' } + ), + ]); expect(content).toMatchInlineSnapshot(` - "export type WidgetFragmentFragment = { widgetCount: number, widgetPreference: string } & { ' $fragmentName'?: 'WidgetFragmentFragment' }; + "type Exact = { [K in keyof T]: T[K] }; + export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; + export type WidgetFragmentFragment = { widgetCount: number, widgetPreference: string } & { ' $fragmentName'?: 'WidgetFragmentFragment' }; export type FoodFragmentFragment = { favoriteFood: string, leastFavoriteFood: string } & { ' $fragmentName'?: 'FoodFragmentFragment' }; @@ -7206,19 +6233,14 @@ function test(q: GetEntityBrandDataQuery): void { } `); - const result = await plugin( - schema, - [{ location: 'test-file.ts', document: ast }], - { preResolveTypes: false }, - { outputFile: '' } - ); + const result = await plugin(schema, [{ location: 'test-file.ts', document: ast }], {}, { outputFile: '' }); expect(result.content).toMatchInlineSnapshot(` "export type Unnamed_1_QueryVariables = Exact<{ [key: string]: never; }>; export type Unnamed_1_Query = { notifications: Array< - | Pick - | Pick + | { id: string } + | { id: string } > }; " `);