diff --git a/.changeset/twenty-buckets-brush.md b/.changeset/twenty-buckets-brush.md new file mode 100644 index 00000000000..92cda5aef3d --- /dev/null +++ b/.changeset/twenty-buckets-brush.md @@ -0,0 +1,5 @@ +--- +'@graphql-codegen/typescript-operations': patch +--- + +Fix importing issue of Input when importSchemaTypesFrom is used diff --git a/dev-test/codegen.ts b/dev-test/codegen.ts index 075ee2918be..87c64c7cfc5 100644 --- a/dev-test/codegen.ts +++ b/dev-test/codegen.ts @@ -256,7 +256,7 @@ const config: CodegenConfig = { }, }, - // standalone-operations + // standalone-operations/import-schema-types './dev-test/standalone-operations/import-schema-types/_base.generated.ts': { schema: './dev-test/standalone-operations/schema.graphql', documents: ['./dev-test/standalone-operations/import-schema-types/*.graphql'], @@ -274,6 +274,21 @@ const config: CodegenConfig = { namespacedImportName: 'Types', }, }, + + // standalone-operations/with-typescript-plugin + './dev-test/standalone-operations/with-typescript-plugin/_base.generated.ts': { + schema: './dev-test/standalone-operations/schema.graphql', + plugins: ['typescript'], + }, + './dev-test/standalone-operations/with-typescript-plugin/_types.generated.ts': { + schema: './dev-test/standalone-operations/schema.graphql', + documents: ['./dev-test/standalone-operations/with-typescript-plugin/*.graphql'], + plugins: ['typescript-operations'], + config: { + importSchemaTypesFrom: './dev-test/standalone-operations/with-typescript-plugin/_base.generated.ts', + namespacedImportName: 'Types', + }, + }, }, }; diff --git a/dev-test/standalone-operations/import-schema-types/_base.generated.ts b/dev-test/standalone-operations/import-schema-types/_base.generated.ts index 8df53ac5f67..f0dd411ab38 100644 --- a/dev-test/standalone-operations/import-schema-types/_base.generated.ts +++ b/dev-test/standalone-operations/import-schema-types/_base.generated.ts @@ -4,3 +4,9 @@ export type UserRole = | 'ADMIN' /** UserRole CUSTOMER */ | 'CUSTOMER'; + +export type UsersInput = { + name?: string | null | undefined; + nestedInput?: UsersInput | null | undefined; + role?: UserRole | null | undefined; +}; diff --git a/dev-test/standalone-operations/import-schema-types/_types.generated.ts b/dev-test/standalone-operations/import-schema-types/_types.generated.ts index 506b64e32b0..6a222027557 100644 --- a/dev-test/standalone-operations/import-schema-types/_types.generated.ts +++ b/dev-test/standalone-operations/import-schema-types/_types.generated.ts @@ -7,3 +7,9 @@ export type WithVariablesQueryVariables = Exact<{ }>; export type WithVariablesQuery = { user: { id: string; name: string } | null }; + +export type UsersQueryVariables = Exact<{ + input: Types.UsersInput; +}>; + +export type UsersQuery = { users: Array<{ id: string }> }; diff --git a/dev-test/standalone-operations/import-schema-types/query.graphql b/dev-test/standalone-operations/import-schema-types/query.graphql index e8de0b4506d..ddf5351bc36 100644 --- a/dev-test/standalone-operations/import-schema-types/query.graphql +++ b/dev-test/standalone-operations/import-schema-types/query.graphql @@ -4,3 +4,9 @@ query WithVariables($role: UserRole) { name } } + +query Users($input: UsersInput!) { + users(input: $input) { + id + } +} diff --git a/dev-test/standalone-operations/schema.graphql b/dev-test/standalone-operations/schema.graphql index 2fd2cb04bc6..0f7ac081d36 100644 --- a/dev-test/standalone-operations/schema.graphql +++ b/dev-test/standalone-operations/schema.graphql @@ -1,5 +1,6 @@ type Query { user(id: ID!, role: UserRole): User + users(input: UsersInput!): [User!]! } type User { @@ -15,3 +16,14 @@ enum UserRole { "UserRole CUSTOMER" CUSTOMER } + +enum UserStatus { + ACTIVE + INACTIVE +} + +input UsersInput { + name: String + role: UserRole + nestedInput: UsersInput +} diff --git a/dev-test/standalone-operations/with-typescript-plugin/_base.generated.ts b/dev-test/standalone-operations/with-typescript-plugin/_base.generated.ts new file mode 100644 index 00000000000..30664af7c84 --- /dev/null +++ b/dev-test/standalone-operations/with-typescript-plugin/_base.generated.ts @@ -0,0 +1,51 @@ +export type Maybe = T | null; +export type InputMaybe = Maybe; +/** All built-in and custom scalars, mapped to their actual values */ +export type Scalars = { + ID: { input: string; output: string }; + String: { input: string; output: string }; + Boolean: { input: boolean; output: boolean }; + Int: { input: number; output: number }; + Float: { input: number; output: number }; +}; + +export type Query = { + __typename?: 'Query'; + user?: Maybe; + users: Array; +}; + +export type QueryUserArgs = { + id: Scalars['ID']['input']; + role?: InputMaybe; +}; + +export type QueryUsersArgs = { + input: UsersInput; +}; + +export type User = { + __typename?: 'User'; + id: Scalars['ID']['output']; + name: Scalars['String']['output']; + role: UserRole; +}; + +/** UserRole Description */ +export enum UserRole { + /** UserRole ADMIN */ + Admin = 'ADMIN', + /** UserRole CUSTOMER */ + Customer = 'CUSTOMER', +} + +export enum UserStatus { + Active = 'ACTIVE', + Inactive = 'INACTIVE', +} + +export type UsersInput = { + name?: InputMaybe; + nestedInput?: InputMaybe; + role?: InputMaybe; +}; diff --git a/dev-test/standalone-operations/with-typescript-plugin/_types.generated.ts b/dev-test/standalone-operations/with-typescript-plugin/_types.generated.ts new file mode 100644 index 00000000000..6a222027557 --- /dev/null +++ b/dev-test/standalone-operations/with-typescript-plugin/_types.generated.ts @@ -0,0 +1,15 @@ +import type * as Types from './_base.generated.js'; + +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 WithVariablesQueryVariables = Exact<{ + role?: Types.UserRole | null | undefined; +}>; + +export type WithVariablesQuery = { user: { id: string; name: string } | null }; + +export type UsersQueryVariables = Exact<{ + input: Types.UsersInput; +}>; + +export type UsersQuery = { users: Array<{ id: string }> }; diff --git a/dev-test/standalone-operations/with-typescript-plugin/query.graphql b/dev-test/standalone-operations/with-typescript-plugin/query.graphql new file mode 100644 index 00000000000..ddf5351bc36 --- /dev/null +++ b/dev-test/standalone-operations/with-typescript-plugin/query.graphql @@ -0,0 +1,12 @@ +query WithVariables($role: UserRole) { + user(id: "100") { + id + name + } +} + +query Users($input: UsersInput!) { + users(input: $input) { + id + } +} diff --git a/packages/plugins/typescript/operations/src/visitor.ts b/packages/plugins/typescript/operations/src/visitor.ts index 31b3c51114c..9c5ca3e87ef 100644 --- a/packages/plugins/typescript/operations/src/visitor.ts +++ b/packages/plugins/typescript/operations/src/visitor.ts @@ -191,8 +191,11 @@ export class TypeScriptDocumentsVisitor extends BaseDocumentsVisitor< EnumTypeDefinition(node: EnumTypeDefinitionNode): string | null { const enumName = node.name.value; - if (!this._usedNamedInputTypes[enumName] || this.config.importSchemaTypesFrom) { - return null; + if ( + !this._usedNamedInputTypes[enumName] || // If not used... + this.config.importSchemaTypesFrom // ... Or, is imported from a shared file + ) { + return null; // ... then, don't generate in this file } return convertSchemaEnumToDeclarationBlockString({ @@ -216,12 +219,20 @@ export class TypeScriptDocumentsVisitor extends BaseDocumentsVisitor< InputObjectTypeDefinition(node: InputObjectTypeDefinitionNode): string | null { const inputTypeName = node.name.value; - if (!this._usedNamedInputTypes[inputTypeName]) { - return null; + if ( + !this._usedNamedInputTypes[inputTypeName] || // If not used... + this.config.importSchemaTypesFrom // ... Or, is imported from a shared file + ) { + return null; // ... then, don't generate in this file } + // Note: we usually don't need to export this type, + // however, it's not possible to know if another file is using this type e.g. using `importSchemaTypesFrom`, + // so it's better export the types. + if (isOneOfInputObjectType(this._schema.getType(inputTypeName))) { return new DeclarationBlock(this._declarationBlockConfig) + .export() .asKind('type') .withName(this.convertName(node)) .withComment(node.description?.value) @@ -229,6 +240,7 @@ export class TypeScriptDocumentsVisitor extends BaseDocumentsVisitor< } return new DeclarationBlock(this._declarationBlockConfig) + .export() .asKind('type') .withName(this.convertName(node)) .withComment(node.description?.value) diff --git a/packages/plugins/typescript/operations/tests/ts-documents.spec.ts b/packages/plugins/typescript/operations/tests/ts-documents.spec.ts index e9a6660569c..b60b3f2a956 100644 --- a/packages/plugins/typescript/operations/tests/ts-documents.spec.ts +++ b/packages/plugins/typescript/operations/tests/ts-documents.spec.ts @@ -2714,7 +2714,7 @@ export type Q2Query = { search: Array< expect(content).toMatchInlineSnapshot( ` - "type InputType = { + "export type InputType = { t?: string | null | undefined; }; @@ -2979,7 +2979,7 @@ export type Q2Query = { search: Array< | 'Write' | 'All'; - type PREFIX_Filter = { + export type PREFIX_Filter = { match: string; }; diff --git a/packages/plugins/typescript/operations/tests/ts-documents.standalone.default-scalar-types.spec.ts b/packages/plugins/typescript/operations/tests/ts-documents.standalone.default-scalar-types.spec.ts index cbfb79d8f0e..057605180e6 100644 --- a/packages/plugins/typescript/operations/tests/ts-documents.standalone.default-scalar-types.spec.ts +++ b/packages/plugins/typescript/operations/tests/ts-documents.standalone.default-scalar-types.spec.ts @@ -68,7 +68,7 @@ describe('TypeScript Operations Plugin - Default Scalar types', () => { expect(result).toMatchInlineSnapshot(` "type Exact = { [K in keyof T]: T[K] }; export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; - type UserInput = { + export type UserInput = { nonNullableDate: unknown; nullableDate?: unknown; dateArray1?: Array | null | undefined; @@ -161,7 +161,7 @@ describe('TypeScript Operations Plugin - Default Scalar types', () => { expect(result).toMatchInlineSnapshot(` "type Exact = { [K in keyof T]: T[K] }; export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; - type UserInput = { + export type UserInput = { nonNullableDate: any; nullableDate?: any; dateArray1?: Array | null | undefined; @@ -254,7 +254,7 @@ describe('TypeScript Operations Plugin - Default Scalar types', () => { expect(result).toMatchInlineSnapshot(` "type Exact = { [K in keyof T]: T[K] }; export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; - type UserInput = { + export type UserInput = { nonNullableDate: Date; nullableDate?: Date | null | undefined; dateArray1?: Array | null | undefined; diff --git a/packages/plugins/typescript/operations/tests/ts-documents.standalone.import-types.spec.ts b/packages/plugins/typescript/operations/tests/ts-documents.standalone.import-types.spec.ts index a75ebd0f397..20a634d0820 100644 --- a/packages/plugins/typescript/operations/tests/ts-documents.standalone.import-types.spec.ts +++ b/packages/plugins/typescript/operations/tests/ts-documents.standalone.import-types.spec.ts @@ -107,15 +107,6 @@ describe('TypeScript Operations Plugin - Import Types', () => { type Exact = { [K in keyof T]: T[K] }; export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; - /** UsersInput Description */ - type UsersInput = { - /** UsersInput from */ - from?: unknown; - /** UsersInput to */ - to?: unknown; - role?: UserRole | null | undefined; - }; - export type UserQueryVariables = Exact<{ id: string; }>; @@ -251,15 +242,6 @@ describe('TypeScript Operations Plugin - Import Types', () => { type Exact = { [K in keyof T]: T[K] }; export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; - /** UsersInput Description */ - type UsersInput = { - /** UsersInput from */ - from?: unknown; - /** UsersInput to */ - to?: unknown; - role?: UserRole | null | undefined; - }; - export type UserQueryVariables = Exact<{ id: string; }>; diff --git a/packages/plugins/typescript/operations/tests/ts-documents.standalone.input.spec.ts b/packages/plugins/typescript/operations/tests/ts-documents.standalone.input.spec.ts index a6cc40fd9e2..c77972b6537 100644 --- a/packages/plugins/typescript/operations/tests/ts-documents.standalone.input.spec.ts +++ b/packages/plugins/typescript/operations/tests/ts-documents.standalone.input.spec.ts @@ -97,7 +97,7 @@ describe('TypeScript Operations Plugin - Input', () => { | 'CUSTOMER'; /** UsersInput Description */ - type UsersInput = { + export type UsersInput = { /** UsersInput from */ from?: Date | null | undefined; /** UsersInput to */ @@ -112,7 +112,7 @@ describe('TypeScript Operations Plugin - Input', () => { nestedInput?: UsersInput | null | undefined; }; - type UsersBestFriendInput = { + export type UsersBestFriendInput = { name?: string | null | undefined; }; @@ -214,7 +214,7 @@ describe('TypeScript Operations Plugin - Input', () => { | 'CUSTOMER'; /** UsersInput Description */ - type UsersInput = { + export type UsersInput = { /** UsersInput from */ readonly from?: Date | null | undefined; /** UsersInput to */ @@ -229,7 +229,7 @@ describe('TypeScript Operations Plugin - Input', () => { readonly nestedInput?: UsersInput | null | undefined; }; - type UsersBestFriendInput = { + export type UsersBestFriendInput = { readonly name?: string | null | undefined; }; @@ -323,7 +323,7 @@ describe('TypeScript Operations Plugin - Input', () => { | 'CUSTOMER'; /** UsersInput Description */ - type UsersInput = + export type UsersInput = { /** UsersInput from */ from: Date; to?: never; timezone?: never; role?: never; ageRange1?: never; ageRange3?: never; bestFriend?: never; nestedInput?: never; } | { from?: never; /** UsersInput to */ @@ -335,7 +335,7 @@ describe('TypeScript Operations Plugin - Input', () => { | { from?: never; to?: never; timezone?: never; role?: never; ageRange1?: never; ageRange3?: never; bestFriend: UsersBestFriendInput; nestedInput?: never; } | { from?: never; to?: never; timezone?: never; role?: never; ageRange1?: never; ageRange3?: never; bestFriend?: never; nestedInput: UsersInput; }; - type UsersBestFriendInput = { + export type UsersBestFriendInput = { name?: string | null | undefined; }; @@ -414,7 +414,7 @@ describe('TypeScript Operations Plugin - Input', () => { expect(result).toMatchInlineSnapshot(` "type Exact = { [K in keyof T]: T[K] }; export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; - type UserInput = { + export type UserInput = { dateRange1?: Array | null; dateRange2: Array; dateRange3?: Array | null; @@ -423,7 +423,7 @@ describe('TypeScript Operations Plugin - Input', () => { nestedInput?: UserInput | null; }; - type UserBestFriendInput = { + export type UserBestFriendInput = { name?: string | null; bestFriendDateRange1?: Array | null; bestFriendDateRange2: Array; diff --git a/packages/plugins/typescript/operations/tests/ts-documents.standalone.spec.ts b/packages/plugins/typescript/operations/tests/ts-documents.standalone.spec.ts index f048786fee7..86ade3e739a 100644 --- a/packages/plugins/typescript/operations/tests/ts-documents.standalone.spec.ts +++ b/packages/plugins/typescript/operations/tests/ts-documents.standalone.spec.ts @@ -136,7 +136,7 @@ describe('TypeScript Operations Plugin - Standalone', () => { | 'CUSTOMER'; /** UsersInput Description */ - type UsersInput = { + export type UsersInput = { /** UsersInput from */ from?: unknown; /** UsersInput to */ @@ -251,11 +251,11 @@ describe('TypeScript Operations Plugin - Standalone', () => { | 'ENUM_E' | 'ENUM_F'; - type EnumsInner = { + export type EnumsInner = { enumsDeep: Array; }; - type UsersInput = { + export type UsersInput = { enum: EnumRoot; enums: Array; innerEnums: EnumsInner; @@ -652,7 +652,7 @@ describe('TypeScript Operations Plugin - Standalone', () => { | 'CUSTOMER'; /** UsersInput Description */ - type UsersInput = { + export type UsersInput = { /** UsersInput from */ from?: unknown; /** UsersInput to */